CLI reference
Complete reference for the Arctic command-line interface
The Arctic CLI (arctic) is a command-line tool for managing Arctic agents and clusters. It follows the pattern arctic <command> [subcommand] [flags].
bootstrap
Initialize an Arctic agent with a license file.
Synopsis
arctic bootstrap --url <agent-url> --license-file <path> [flags]Description
The bootstrap command initializes an Arctic agent with a license. This process:
- Uploads the license to the agent
- Generates a unique peer identity (Ed25519 key pair)
- Creates OAuth2 credentials for API access
- Saves the configuration to your CLI config file
Required flags
| Flag | Description |
|---|---|
--url | Agent URL (e.g., http://192.168.1.10:8080) |
--license-file | Path to the license JSON file |
Optional flags
| Flag | Default | Description |
|---|---|---|
--name | Human-readable name for this peer |
Output
On success, displays:
Peer ID: 01HXYZ...
Cluster ID: 01HABC...
Client ID: cl_01HXYZ...
License ID: lic_abc123...
Expires: 2025-12-31 23:59:59 UTC
Max Nodes: 10
Max Services: 100
Configuration saved to ~/.config/arctic/config.yaml
Set as current cluster: 01HABC...Examples
# Basic bootstrap
arctic bootstrap \
--url http://192.168.1.10:8080 \
--license-file license.json
# With name
arctic bootstrap \
--url http://192.168.1.10:8080 \
--license-file license.json \
--name "prod-svr-1"Errors
| Error | Description |
|---|---|
--license-file is required | Missing license file flag |
--url is required for bootstrap | Missing agent URL |
failed to read license file | License file not found or invalid JSON |
license has expired | License expiration date has passed |
agent is already bootstrapped | Agent was previously initialized |
Notes
- An agent can only be bootstrapped once. To re-bootstrap, you must reset the agent's database.
- Credentials are saved automatically to your CLI config file.
cluster
Manage cluster operations.
Synopsis
arctic cluster <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
init | Initialize cluster |
identity | Show cluster identity |
sync | Trigger synchronization |
status | Show gossip status for diagnostics |
cluster init
Initialize a cluster for legacy upgraded agents.
arctic cluster init [--force]| Flag | Description |
|---|---|
--force | Force reinitialize even if cluster exists |
Required scope: urn:tillered:arctic:admin
Cluster initialized
Cluster ID: 01HABC...
Created By: 01HXYZ...
Oldest Peer: 01HXYZ...
Was Created: trueNotes:
- Only needed for agents upgraded from older versions
- New agents have clusters initialized during bootstrap
- Use
--forceto regenerate the cluster ID (destroys existing cluster state)
cluster identity
Show the cluster identity of a peer. No authentication required (public endpoint).
arctic cluster identityPeer ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Public Key: qnGyPtol7lqzLYU3989eaC+K4xda0w9KXlcEOM9cSBQ=
License ID: lic_01KB45EYP1VJ1RZEGJDPKJQ9V4
Cluster ID: clu_01KBYMHMRJ92E090P50VRKG4ZC
Version: v0.1.0Use -j for JSON output:
arctic cluster identity -j{
"peer_id": "peer_01KBYMHC35F0N070F3XXMEZAZR",
"public_key": "qnGyPtol7lqzLYU3989eaC+K4xda0w9KXlcEOM9cSBQ=",
"license_id": "lic_01KB45EYP1VJ1RZEGJDPKJQ9V4",
"cluster_id": "clu_01KBYMHMRJ92E090P50VRKG4ZC",
"version": "v0.1.0"
}Use cases:
- Verify peer identity before adding
- Check license ID matches your cluster
- Retrieve public key for verification
cluster sync
Trigger cluster synchronization. Required scope: urn:tillered:arctic:admin
arctic cluster syncTriggers immediate:
- Gossip protocol heartbeats to all peers
- Configuration regeneration
- Subsystem processing (network, firewall, etc.)
Use cases:
- Force configuration update after changes
- Speed up propagation of new peers
- Troubleshoot synchronization issues
cluster status
Show gossip status for cluster diagnostics. Required scope: urn:tillered:arctic:admin
arctic cluster statusGossip Status
-------------
Local Peer: peer_01KBYMHC35F0N070F3XXMEZAZR
Cluster ID: clu_01KBYMHMRJ92E090P50VRKG4ZC
Peer Status:
peer_01KBYMD32Z2RVDE3G5Y9M530QR:
Last Seen: 2025-12-09 10:15:30 UTC
Status: healthy
Registry Hash: a1b2c3d4...
Registry:
Services: 5
Routes: 12
Hash: e5f6g7h8...Use -j for JSON output. Use cases:
- Diagnose cluster synchronization issues
- Verify peer connectivity and health
- Check registry hash for drift detection
- Monitor gossip protocol state
completion
Generate shell completion scripts for Arctic CLI.
Synopsis
arctic completion <shell>Arguments
| Argument | Description |
|---|---|
shell | Shell type: bash, zsh, or fish |
Supported shells
Bash:
# Add to ~/.bashrc
source <(arctic completion bash)
# Or save to completions directory
arctic completion bash > /etc/bash_completion.d/arcticZsh:
# Add to ~/.zshrc
source <(arctic completion zsh)
# Or for Oh My Zsh, save to completions directory
arctic completion zsh > ~/.oh-my-zsh/completions/_arcticFish:
# Save to Fish completions directory
arctic completion fish > ~/.config/fish/completions/arctic.fishFeatures
Shell completion provides:
- Command completion: Type
arctic pe<TAB>to complete topeers - Subcommand completion: Type
arctic peers l<TAB>to complete tolist - Flag completion: Type
arctic peers list --<TAB>to see available flags - Value completion: Peer IDs, service IDs, and other values are completed from cache
Example session
$ arctic <TAB>
bootstrap cluster completion config
health license peers routes
services
$ arctic peers <TAB>
add delete get list remove-self update
$ arctic peers list --<TAB>
--local --remote --client-id --client-secret
--config --context --debug --insecure
--json --no-headers --output --quiet
--timeout --token --url --yes
-c -j -o -q -yErrors
| Error | Description |
|---|---|
shell type required | Missing shell argument |
unsupported shell | Shell not bash, zsh, or fish |
compose
Manage Arctic clusters using declarative YAML configuration files.
Synopsis
arctic compose <subcommand> <config-file> [flags]Description
The compose command is the recommended way to deploy and manage Arctic clusters. It provides Infrastructure as Code (IaC) capabilities, allowing you to define your cluster state in a YAML file and apply it declaratively.
Subcommands
| Subcommand | Description |
|---|---|
apply | Apply cluster configuration from YAML |
diff | Show differences between config and cluster state |
export | Export cluster configuration to YAML |
fmt | Format configuration files |
init | Generate starter configuration template |
validate | Validate YAML syntax and schema |
compose apply
Apply cluster configuration from a YAML file.
arctic compose apply <config-file> [flags]| Flag | Description | Default |
|---|---|---|
--dry-run | Show changes without applying | false |
--prune | Delete resources not in config | false |
--ignore-unreachable | Skip unreachable peers | false |
--license-file | License file for bootstrap | |
--credentials-file | Write credentials to JSON file on bootstrap | |
--env-file | Write credentials to .env file on bootstrap | |
--save-config | Save cluster to CLI config and set as current | true |
--skip-validate | Skip pre-validation checks (not recommended) | false |
--strict | Treat validation warnings as errors | false |
Required scope: urn:tillered:arctic:admin
# Validate and apply configuration
arctic compose apply cluster.yaml
# Preview changes without applying
arctic compose apply cluster.yaml --dry-run
# Apply and prune resources not in config
arctic compose apply cluster.yaml --prune
# Apply with new license and save credentials
arctic compose apply cluster.yaml \
--license-file license.json \
--credentials-file creds.json
# Apply without saving to CLI config
arctic compose apply cluster.yaml --save-config=falseExample output:
Validating cluster.yaml...
OK - Configuration valid
Checking cluster state...
peer-a: bootstrapped
peer-b: bootstrapped
Planning changes...
+ Create service: web-tunnel (peer-a -> peer-b)
+ Create route: 0.0.0.0/0 -> 10.0.0.0/8
Applying changes...
[OK] Created service web-tunnel
[OK] Created route 10.0.0.0/8
Apply complete: 1 service created, 1 route createdcompose diff
Show differences between configuration file and current cluster state.
arctic compose diff <config-file>Required scope: urn:tillered:arctic:peers.read, urn:tillered:arctic:services.read, urn:tillered:arctic:routes.read
Example output:
Comparing cluster.yaml with cluster state...
Services:
~ web-tunnel: bandwidth_limit_mbps changed (0 -> 100)
+ new-tunnel: will be created
- old-tunnel: will be deleted (with --prune)
Routes:
+ 10.0.0.0/8: will be added to web-tunnelcompose export
Export current cluster configuration to YAML format.
arctic compose export [flags]| Flag | Description |
|---|---|
--file | Output file path (defaults to stdout) |
Required scope: urn:tillered:arctic:peers.read, urn:tillered:arctic:services.read, urn:tillered:arctic:routes.read
# Export to stdout
arctic compose export
# Export to file
arctic compose export --file cluster.yamlcompose fmt
Format a cluster configuration file with consistent formatting.
arctic compose fmt <config-file> [flags]| Flag | Description | Default |
|---|---|---|
--write | Write formatted output back to file | false |
--check | Check if file is formatted (exit 1 if not) | false |
The fmt command normalizes YAML configuration files to a canonical format:
- Reorders keys to canonical order (see Compose configuration)
- Uses 2-space indentation
- Preserves comments
# Output formatted config to stdout
arctic compose fmt cluster.yaml
# Format file in place
arctic compose fmt cluster.yaml --write
# Check if file is formatted (for CI)
arctic compose fmt cluster.yaml --checkcompose init
Generate a starter cluster configuration template.
arctic compose init [flags]| Flag | Description | Default |
|---|---|---|
--file | Output file path (defaults to stdout) | |
--minimal | Generate minimal valid config | false |
--example | Generate full example with comments | true |
# Generate example config to stdout
arctic compose init
# Generate example config to file
arctic compose init --file cluster.yaml
# Generate minimal config
arctic compose init --minimalMinimal output:
version: v1
peers:
- name: peer-1
address: 192.168.1.10:8080
services: []compose validate
Validate cluster configuration YAML syntax and schema.
arctic compose validate <config-file> [flags]| Flag | Description | Default |
|---|---|---|
--strict | Treat warnings as errors | false |
Valid output:
Validating cluster.yaml...
OK - Configuration valid
Schema version: v1
Peers: 2
Services: 1
Routes: 1Invalid output:
Validating cluster.yaml...
ERROR - Configuration invalid
Errors:
- services[0]: source_peer "unknown" not found in peers list
- services[0].routes[0]: invalid source_cidr "invalid"Configuration schema quick reference
version: v1 # Schema version (required)
license: path/to/license.json # License file path (optional)
peers: # Peer definitions (required)
- name: string # Unique peer name
address: host:port # Agent address
services: # Service definitions (optional)
- name: string # Unique service name
source_peer: string # Source peer name
target_peer: string # Target peer name
transport_type: tcp|kcp # Transport protocol
fully_transparent: bool # Full transparency mode (default: false)
interface: # MACVLAN interface config (optional)
enabled: bool
ipv4: CIDR
qos: # QoS settings (optional)
bandwidth_limit_mbps: uint64
routes: # Routing rules (optional)
- source_cidr: CIDR
dest_cidr: CIDR
priority: uint64A service requires either interface (enabled) or routes to be functional.
Exit codes
| Code | Condition |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Validation error |
| 3 | Configuration error |
| 4 | Connection error |
config
Manage Arctic CLI configuration.
Synopsis
arctic config <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List all clusters and peers |
view | View current configuration |
current | Show current context |
use-cluster | Set current cluster |
add-peer | Add peer to a cluster |
delete-peer | Delete peer from cluster configuration |
config list
List all clusters and peers in the configuration.
arctic config listID NAME URL LICENSE CURRENT
01HXYZABC123... agent-a http://192.168.1.10:8080 lic_... *
01HXYZDEF789... agent-b http://192.168.1.20:8080 lic_...config view
View the full configuration file.
arctic config viewconfig current
Show the current context.
arctic config currentCluster ID: 01HABC...
Name: Production
Customer ID: cust_...
Peer Count: 3
Default Peer: 01HXYZ...
Default URL: http://192.168.1.10:8080
Format: clusterconfig use-cluster
Set the current cluster context.
arctic config use-cluster <cluster-id-or-name>| Argument | Description |
|---|---|
cluster-id-or-name | Cluster ID or name to set as current |
arctic config use-cluster Production
arctic config use-cluster 01HABCDEF...config add-peer
Add a peer configuration to a cluster.
arctic config add-peer --peer-id <id> --peer-url <url> [flags]Required flags:
| Flag | Description |
|---|---|
--peer-id | Peer ID |
--peer-url | Agent URL |
Optional flags:
| Flag | Description |
|---|---|
--cluster | Cluster ID or name (defaults to current cluster) |
--name | Human-readable name for the peer |
arctic config add-peer \
--peer-id 01HXYZ... \
--peer-url http://192.168.1.30:8080 \
--name "agent-c" \
--cluster Productionconfig delete-peer
Delete a peer from the cluster configuration.
arctic config delete-peer <peer-id-or-name> [flags]| Flag | Description |
|---|---|
--cluster | Cluster ID or name (defaults to current cluster) |
arctic config delete-peer agent-c
arctic config delete-peer agent-c --cluster ProductionRequires confirmation unless --yes is specified.
docs
Serve the embedded Arctic documentation locally in your browser.
Synopsis
arctic docs [flags]Description
The docs command starts a local web server and serves the Arctic documentation. This allows you to browse the documentation offline or in environments without internet access.
Flags
| Flag | Description | Default |
|---|---|---|
--port | Port to serve documentation on | 8888 |
--no-browser | Do not open browser automatically | false |
Examples
# Start documentation server
arctic docs
# Custom port
arctic docs --port 9999
# Without opening browser
arctic docs --no-browserOpens the documentation in your default browser at http://localhost:8888.
Notes
- The documentation is embedded in the CLI binary
- No internet connection required
- Press Ctrl+C to stop the server
- The server binds to
localhostonly by default
health
Check Arctic agent health status.
Synopsis
arctic health [flags]Description
The health command checks the liveness or readiness of Arctic agents. It does not require authentication.
Flags
| Flag | Description |
|---|---|
--readyz | Check readiness instead of liveness |
Examples
# Check current context
arctic health
# Check readiness
arctic health --readyz
# Check specific agent
arctic health --url http://192.168.1.30:8080
# JSON output
arctic health -jDefault output:
Peer ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Name: agent-1
URL: http://192.168.3.251:8080
Status: ok
Timestamp: 2025-12-09 04:43:41 UTCJSON output:
{
"peer_id": "peer_01KBYMHC35F0N070F3XXMEZAZR",
"name": "agent-1",
"url": "http://192.168.3.251:8080",
"status": "ok",
"timestamp": "2025-12-09 04:43:41 UTC"
}Exit codes
| Code | Condition |
|---|---|
| 0 | Agent healthy |
| 4 | Agent unreachable |
Scripting example
arctic health
exit_code=$?
case $exit_code in
0)
echo "Agent healthy"
;;
4)
echo "Agent down"
send_alert "Arctic agent unreachable"
;;
*)
echo "Unexpected error: $exit_code"
;;
esacLiveness vs readiness
Liveness (/livez) - Default check. Indicates the agent process is running. Returns ok if the agent can respond.
Readiness (/readyz) - Use --readyz flag. Indicates the agent is ready to serve requests. May return not ready during startup or maintenance.
Health checks do not require authentication. They are designed for use by load balancers, monitoring systems, health check scripts, and Kubernetes probes.
license
Manage the Arctic agent license.
Synopsis
arctic license <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
status | Show license usage status |
update | Update license |
license status
Show license usage status. Required scope: urn:tillered:arctic:admin
arctic license statusLicense Information
-------------------
License ID: lic_abc123...
Customer ID: cust_xyz789...
Customer Name: Acme Corp
Validity
--------
Issued: 2024-01-01 00:00:00 UTC
Expires: 2025-12-31 23:59:59 UTC
Status: Valid (350 days remaining)
Limits
------
Max Nodes: 10
Max Services: 100
Metadata
--------
Issuer: Tillered
Key ID: 2024Q4
Algorithm: Ed25519Use -o json for JSON output.
license update
Update the agent license with a new license file. Required scope: urn:tillered:arctic:admin
arctic license update --license-file <path>| Flag | Description |
|---|---|
--license-file | Path to new license file |
arctic license update --license-file new-license.jsonLicense updated
Customer ID: cust_xyz789...
License ID: lic_def456...
Expires: 2026-12-31 23:59:59 UTC
Max Nodes: 20
Max Services: 200Errors:
| Error | Description |
|---|---|
--license-file is required | Missing license file flag |
failed to read license file | File not found or invalid |
license has expired | New license is expired |
license update failed | API error |
Notes:
- The new license must be for the same customer
- All connected peers receive the updated license via gossip
- Existing services are not affected unless limits decrease
peers
Manage cluster peers.
Aliases: peer
Synopsis
arctic peers <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List all peers |
get | Get peer details |
add | Add a remote peer |
update | Update peer metadata |
delete | Delete a peer |
remove-self | Remove local peer from cluster |
peers list
List all peers in the cluster. Required scope: urn:tillered:arctic:peers.read
arctic peers list [flags]| Flag | Description |
|---|---|
--local | Show only local peers |
--remote | Show only remote peers |
# List all peers
arctic peers list
# List only remote peers
arctic peers list --remote
# List with detailed JSON output
arctic peers list -jDefault table output:
ID NAME ADDRESS
peer_01KBYMHC35F0N070F3XXMEZAZR agent-1 192.168.3.251:8080
peer_01KBYMD32Z2RVDE3G5Y9M530QR agent-2 10.10.40.95:8080peers get
Get details of a specific peer. Required scope: urn:tillered:arctic:peers.read
arctic peers get <peer-id>ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Name: agent-1
Public Key: qnGyPtol7lqzLYU3989eaC+K4xda0w9KXlcEOM9cSBQ=
Is Local: Yes
Address: 192.168.3.251:8080
Created At: 2025-12-08 09:26:30 UTCpeers add
Add a remote peer to the cluster. Required scope: urn:tillered:arctic:peers.write
arctic peers add <peer-address> [flags]| Flag | Description |
|---|---|
--name | Human-readable name for the peer |
# Add a peer
arctic peers add 192.168.1.20:8080
# Add with a name
arctic peers add 192.168.1.20:8080 --name "prod-svr"
# Add with debug output
arctic peers add 192.168.1.20:8080 --debugBehavior:
- Contacts the remote peer's API
- Performs handshake (exchanges public keys)
- Both peers verify signatures against the license
- Peer is added to the local database
- Remote peer adds local peer via gossip
Errors:
| Error | Description |
|---|---|
peer URL required | Missing address argument |
peer already exists in cluster | Duplicate peer |
handshake failed | Peer unreachable or validation failed |
node limit exceeded | License node limit reached |
peers update
Update a peer's metadata. Required scope: urn:tillered:arctic:peers.write
arctic peers update <peer-id> [flags]| Flag | Description | Default |
|---|---|---|
--name | Human-readable name for the peer | |
--qos | Enable QoS for this peer | true |
# Update peer name
arctic peers update 01HXYZDEF789... --name "prod-svr-2"
# Disable QoS for a peer
arctic peers update 01HXYZDEF789... --qos=falsepeers delete
Delete a peer from the cluster. Required scope: urn:tillered:arctic:peers.write
arctic peers delete <peer-id> [--yes]# Delete with confirmation prompt
arctic peers delete 01HXYZDEF789...
# Delete without confirmation
arctic peers delete 01HXYZDEF789... --yesErrors:
| Error | Description |
|---|---|
peer ID required | Missing peer ID |
peer not found | Peer does not exist |
cannot delete local peer | Use remove-self instead |
peers remove-self
Gracefully remove the local peer from the cluster. Required scope: urn:tillered:arctic:admin
arctic peers remove-self [--yes]Behavior:
- Marks the local peer as deactivated
- Broadcasts deactivation announcement to cluster
- Other peers remove this peer from their databases
- Services involving this peer become inactive
arctic peers remove-self --yesPeer removed from cluster
Peer ID: 01HXYZABC123...
Version: 2
Active: falseroutes
Manage CIDR-based routing rules for services.
Aliases: route
Synopsis
arctic routes <subcommand> --service <service-id> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List routes for a service |
add | Add a route to a service |
update | Update a route |
delete | Delete a route |
routes list
List routes for a service. Required scope: urn:tillered:arctic:services.read
arctic routes list --service <service-id>ID PRIORITY SOURCE CIDR DEST CIDR
6 100 10.0.0.0/8 192.168.100.0/24
7 200 10.1.0.0/16 192.168.200.0/24routes add
Add a route to a service. Required scope: urn:tillered:arctic:services.write
arctic routes add --service <service-id> --priority <priority> [flags]| Flag | Description |
|---|---|
--service | Service ID (required) |
--priority | Route priority - higher = more preferred (required) |
--source-cidr | Source CIDR (e.g., 10.0.0.0/8) |
--dest-cidr | Destination CIDR (e.g., 192.168.100.0/24) |
# Source and destination CIDR
arctic routes add --service svc_01HSVCABC123... \
--priority 100 \
--source-cidr 10.0.0.0/8 \
--dest-cidr 192.168.100.0/24
# Destination only
arctic routes add --service svc_01HSVCABC123... \
--priority 100 \
--dest-cidr 192.168.100.0/24Errors:
| Error | Description |
|---|---|
--service is required | Missing service flag |
--priority is required | Missing priority flag |
invalid CIDR notation | Malformed CIDR |
service not found | Service does not exist |
routes update
Update a route. Required scope: urn:tillered:arctic:services.write
arctic routes update --service <service-id> --route <route-id> [flags]| Flag | Description |
|---|---|
--service | Service ID (required) |
--route | Route ID (required) |
--priority | New priority |
--source-cidr | New source CIDR |
--dest-cidr | New destination CIDR |
# Update priority
arctic routes update --service svc_01HSVCABC123... --route 6 --priority 200
# Update CIDRs
arctic routes update --service svc_01HSVCABC123... --route 6 \
--source-cidr 10.1.0.0/16 \
--dest-cidr 192.168.200.0/24Errors:
| Error | Description |
|---|---|
--service is required | Missing service flag |
--route is required | Missing route flag |
invalid --route value: must be a number | Non-numeric route ID |
no fields to update | No update flags provided |
route not found | Route does not exist |
routes delete
Delete a route. Required scope: urn:tillered:arctic:services.write
arctic routes delete --service <service-id> --route <route-id> [--yes]# Delete with confirmation
arctic routes delete --service svc_01HSVCABC123... --route 6
# Delete without confirmation
arctic routes delete --service svc_01HSVCABC123... --route 6 --yesRoute priority
Routes are evaluated by specificity first, then priority:
- Specificity: More specific CIDRs (larger prefix) match first
- Priority: When specificity is equal, higher priority wins
Example evaluation order:
| Priority | Source CIDR | Dest CIDR | Order |
|---|---|---|---|
| 200 | 10.1.0.0/16 | 192.168.100.0/24 | 1st (most specific) |
| 100 | 10.0.0.0/8 | 192.168.100.0/24 | 2nd |
| 100 | 10.0.0.0/8 | 192.168.0.0/16 | 3rd (less specific dest) |
services
Manage services for network routing.
Aliases: service
Synopsis
arctic services <subcommand> [flags]Subcommands
| Subcommand | Description |
|---|---|
list | List services |
get | Get service details |
create | Create a new service |
update | Update service settings |
delete | Delete a service |
services list
List services. Required scope: urn:tillered:arctic:services.read
arctic services list [flags]| Flag | Description |
|---|---|
--source-peer | Filter by source peer ID |
--target-peer | Filter by target peer ID |
--requires-interface | Filter to services requiring MACVLAN |
# List all services
arctic services list
# Filter by target peer
arctic services list --target-peer 01HXYZDEF789...
# JSON output (shorthand)
arctic services list -jTable output shows a compact view with service configuration flags:
ID SOURCE TARGET TRANSPORT FLAGS
svc_01KBYMNEVYN9NC4M3RB3ZGN4RZ agent-1 agent-2 tcp I
svc_01KBYMP2220REHB2MSPHT4XJGT agent-2 agent-1 tcp I
svc_01KBYMP88A7MBM1KTXBYSFA7VK agent-2 agent-1 tcp I
svc_01KBYMP8NZC6MSFBVE8C98AHBX agent-2 agent-1 tcp IT
FLAGS: I=interface, T=transparent, Q=qos, -=noneFLAGS Legend:
I: Service requires dedicated MACVLAN interfaceT: Fully transparent mode enabled (no NAT)Q: QoS bandwidth limiting configured-: No special flags set
Use -j or -o json for full detailed output with all fields.
services get
Get details of a specific service. Required scope: urn:tillered:arctic:services.read
arctic services get <service-id>ID: svc_01KBYMNEVYN9NC4M3RB3ZGN4RZ
Source Peer ID: peer_01KBYMHC35F0N070F3XXMEZAZR
Source Peer Name: agent-1
Target Peer ID: peer_01KBYMD32Z2RVDE3G5Y9M530QR
Target Peer Name: agent-2
Transport: tcp
Requires Interface: Yes
Interface MAC: 4A:CC:DB:76:CF:59
Actual Interface IPv4: 192.168.3.219
Fully Transparent: No
Created At: 2025-12-08 09:28:44 UTC
Updated At: 2025-12-08 09:28:44 UTC
Data Source: sourceIf the source peer is unreachable, the CLI queries the target peer for service data. In this case, interface details may be incomplete and Data Source: local will be shown.
services create
Create a new service. Required scope: urn:tillered:arctic:services.write
arctic services create --target-peer <id> [flags]| Flag | Default | Description |
|---|---|---|
--target-peer | Target peer ID (required) | |
--source-peer | local | Source peer ID |
--transport | tcp | Transport type: tcp or kcp |
--requires-interface | false | Create MACVLAN interface |
--desired-ipv4 | IPv4 CIDR for interface | |
--fully-transparent | false | Enable fully transparent mode |
--bandwidth-limit | 0 | Bandwidth limit in Mbps (0 = unlimited) |
# Basic service
arctic services create --target-peer 01HXYZDEF789...
# With MACVLAN interface
arctic services create \
--target-peer 01HXYZDEF789... \
--requires-interface \
--desired-ipv4 192.168.100.10/24
# With bandwidth limit
arctic services create \
--target-peer 01HXYZDEF789... \
--bandwidth-limit 1000
# Using KCP transport
arctic services create \
--target-peer 01HXYZDEF789... \
--transport kcpErrors:
| Error | Description |
|---|---|
--target-peer is required | Missing target peer |
--transport must be 'tcp' or 'kcp' | Invalid transport |
peer not found | Target peer does not exist |
service limit exceeded | License service limit reached |
service already exists | Duplicate service between peers |
services update
Update a service's settings. Required scope: urn:tillered:arctic:services.write
arctic services update <service-id> [flags]| Flag | Description |
|---|---|
--requires-interface[=BOOL] | Enable/disable MACVLAN interface |
--fully-transparent[=BOOL] | Enable/disable fully transparent mode |
--bandwidth-limit | Bandwidth limit in Mbps (0 = unlimited) |
--desired-ipv4 | IPv4 CIDR for interface |
# Enable interface requirement
arctic services update 01HSVCABC123... --requires-interface
# Disable interface requirement
arctic services update 01HSVCABC123... --requires-interface=false
# Enable fully transparent mode
arctic services update 01HSVCABC123... --fully-transparent
# Set bandwidth limit
arctic services update 01HSVCABC123... --bandwidth-limit 500
# Remove bandwidth limit
arctic services update 01HSVCABC123... --bandwidth-limit 0Errors:
| Error | Description |
|---|---|
service ID required | Missing service ID |
no fields to update | No update flags provided |
service not found | Service does not exist |
services delete
Delete a service. Required scope: urn:tillered:arctic:services.write
arctic services delete <service-id> [--yes]# Delete with confirmation
arctic services delete 01HSVCABC123...
# Delete without confirmation
arctic services delete 01HSVCABC123... --yesDeleting a service:
- Removes all associated routes
- Removes the MACVLAN interface (if created)
- Updates firewall rules
- Regenerates TProxy and IP tunnel configs
Global flags
These flags can be used with any Arctic CLI command.
Context selection
--context, -c - Specify a context (peer or cluster) to use for this command. Accepts peer ID, peer name, cluster ID, or cluster name.
arctic peers list --context my-cluster
arctic peers list -c prod-agent-01Connection override
--url - Override the agent URL for this command.
arctic health --url http://192.168.1.10:8080--token - Use a specific access token instead of the configured credentials.
arctic peers list --token "eyJ..."--client-id - Override the OAuth client ID.
arctic peers list --client-id "cl_01HXYZ..."--client-secret - Override the OAuth client secret.
arctic peers list --client-secret "sec_..."--insecure - Skip TLS certificate validation. Only use for testing. Do not use in production.
arctic health --url https://agent.example.com --insecureOutput control
--output, -o - Set the output format. Options: table, json, yaml.
arctic peers list -o json
arctic peers list -o yaml--json, -j - Output in JSON format. Shorthand for -o json.
arctic peers list -jFor list commands, table format shows compact tables with essential information. Use -j or -o json for full detailed output including all fields.
--no-headers - Omit column headers in table output. Useful for scripting.
arctic peers list --no-headers--quiet, -q - Suppress non-error output.
arctic services delete SERVICE_ID --yes --quietConfirmation
--yes, -y - Skip confirmation prompts for destructive operations.
arctic peers delete PEER_ID --yes
arctic services delete SERVICE_ID -yDebugging
--debug - Show debug information including operation progress and internal state.
arctic peers list --debug--trace - Show full HTTP request and response traces, including headers and bodies.
arctic peers list --traceTimeout
--timeout - Set request timeout. Accepts duration format (e.g., 30s, 1m30s). Default: 30s.
arctic peers add 192.168.1.20:8080 --timeout 60sConfiguration
--config - Path to configuration file. Default: ~/.config/arctic/config.yaml.
arctic peers list --config /path/to/config.yamlEnvironment variables
Some flags have equivalent environment variables:
| Flag | Environment Variable |
|---|---|
--config | ARCTIC_CONFIG |
--context | ARCTIC_CONTEXT |
--url | ARCTIC_URL |
--token | ARCTIC_TOKEN |
--client-id | ARCTIC_CLIENT_ID |
--client-secret | ARCTIC_CLIENT_SECRET |
Exit codes
The Arctic CLI uses exit codes to indicate the result of command execution.
Exit code reference
| Code | Name | Description |
|---|---|---|
| 0 | Success | Command completed successfully |
| 1 | General Error | Unspecified error occurred |
| 2 | Usage Error | Invalid arguments or flags |
| 3 | Config Error | Missing or invalid configuration |
| 4 | Connection Error | Agent could not be reached |
| 5 | Auth Error | Invalid or expired credentials |
| 6 | Partial Failure | Some operations succeeded, others failed |
Detailed descriptions
0 - Success - The command completed without errors.
arctic peers list
echo $? # Output: 01 - General Error - An unspecified error occurred during command execution.
arctic services create --target-peer nonexistent
# Error: peer not found
echo $? # Output: 12 - Usage Error - The command was called with invalid arguments, unknown flags, or missing required parameters.
arctic services create
# Error: --target-peer is required
echo $? # Output: 23 - Config Error - The CLI configuration is missing, invalid, or incomplete.
arctic peers list
# Error: no current cluster set
echo $? # Output: 34 - Connection Error - Could not establish a connection to the agent.
arctic health --url http://unreachable:8080
# Error: connection refused
echo $? # Output: 45 - Auth Error - Authentication failed due to invalid or expired credentials.
arctic peers list --token "invalid_token"
# Error: unauthorized
echo $? # Output: 56 - Partial Failure - Some operations succeeded while others failed.
Using exit codes in scripts
if arctic peers list > /dev/null 2>&1; then
echo "Command succeeded"
else
echo "Command failed"
fiarctic health --url http://192.168.1.10:8080
exit_code=$?
case $exit_code in
0)
echo "Agent is healthy"
;;
4)
echo "Agent is unreachable"
;;
5)
echo "Authentication failed"
;;
*)
echo "Unexpected error: $exit_code"
;;
esacExit codes are independent of output format. Error messages are always written to stderr, regardless of output format.