Skip to content

CLI Commands

Complete reference for all Nefia CLI commands and flags.

This page provides a complete reference for the nefia CLI. Commands are organized by function.

When invoked with no arguments in a terminal, nefia launches the interactive TUI dashboard.

Global Flags

These persistent flags are available on all commands:

FlagTypeDefaultDescription
--configstringautoPath to nefia.yaml configuration file
-o, --outputstringconfig default (human)Output format: human, table, json, jsonl, yaml, or compact
--jsonbooleanfalseShorthand for --output json
--jqstringjq expression to filter JSON output. Implies --json
--no-colorbooleanfalseDisable color output
-q, --quietbooleanfalseSuppress non-essential output
-v, --verbosebooleanfalseEnable verbose output
--debugbooleanfalseEnable debug output
-T, --timeoutdurationconfig default (30m)Execution timeout (e.g. 60s, 5m, 1h30m)
-c, --concurrencyint0Maximum number of concurrent hosts (0 = use config default)
-t, --targetstringTarget selector expression: host:<id>, group:<name>, tag:<key>=<value>, all, regex ~..., file @path, stdin -, plus ,, !, and & operators
-H, --hoststringSingle host ID (shorthand for --target host:<id>)
-s, --sessionstringSession ID (prefix match, min 8 chars)
-y, --yesbooleanfalseSkip standard interactive confirmations (named risk prompts still require --accept-risk)
--fail-fastbooleanfalseStop on first failure
--min-success-ratefloat0.0Minimum required success rate (0.0-1.0); aborts early if mathematically impossible
--notifybooleanfalseSend a desktop notification when the operation completes
--teamstringTeam slug to use for this command (overrides NEFIA_TEAM env var and config)
--profilestringLoad an alternate config profile from ~/.config/nefia/profiles/
--retry-timeoutdurationconfig default (30s)Max wait time for automatic VPN recovery retry
--wait-for-vpnbooleanfalseWait for the VPN tunnel to become healthy before executing
--insecure-skip-hostkey-checkbooleanfalseSkip SSH host key verification (INSECURE)
--allow-absolute-rootbooleanfalseAllow absolute paths as root directories
--accept-riskstringAccept named risk prompts for destructive/security-sensitive operations (for example disconnect-peers,rotate-key,revoke-all)

Setup Commands

setup

Guided first-time onboarding that creates config, generates VPN keys, and can invite a host.

bash
nefia setup [flags]
FlagTypeDefaultDescription
--non-interactivebooleanfalseSkip the interactive setup wizard
--host-namestringHost name to invite in non-interactive mode
--host-osstringHost OS for non-interactive mode (macos, linux, windows)
--skip-hostbooleanfalseCreate config and keys without generating an invite token

setup is the canonical command. nefia init remains available as an alias for backward compatibility.

The setup flow is idempotent and runs four phases:

  1. Check or create nefia.yaml
  2. Check or generate the operator WireGuard keypair
  3. Optionally collect the first host's details
  4. Generate an invite token for that host

In interactive mode, Nefia can open the browser automatically if login is required before generating the invite. In non-interactive mode, pass --host-name and --host-os to generate an invite token, or --skip-host to stop after config and key setup.

bash
# Initialize config and keys only
nefia setup --skip-host
 
# Full unattended bootstrap
nefia setup --non-interactive --host-name my-server --host-os linux

login

Authenticate with your Nefia account.

bash
nefia login

Uses challenge-response authentication: the CLI generates a verifier and challenge, opens the browser for approval, then polls until the approval completes. No local HTTP server is required. On success, stores a refresh token in your OS keyring (macOS Keychain, Linux Secret Service, Windows Credential Manager). See Authentication for details.

logout

Remove stored authentication tokens.

bash
nefia logout

Core Commands

exec

Execute a command on one or more remote hosts.

bash
nefia exec [flags] -- <command>

The -- separator is required to distinguish nefia flags from the remote command. Everything after -- is concatenated and executed as a single shell command on the remote host(s).

FlagTypeDefaultDescription
-n, --dry-runbooleanfalsePreview what would be executed without running
--rerunstringRerun against hosts from the last multi-host execution (failure or success)
--when-onlinebooleanfalseQueue the command for offline hosts and execute it when they come online
--queue-ttlduration24hTTL for queued commands created by --when-online
--streambooleanfalseStream per-host output in real time with host prefixes
--log-dirstringWrite per-host output to separate files in this directory
--out-filestringAlso write aggregate output to a single file
--batch-sizeint0Execute on N hosts at a time (0 = all at once)
--batch-percentint0Execute on P% of hosts per batch (1-100, mutually exclusive with --batch-size)
--batch-waitdurationWait between execution batches
--subsetint0Execute on a random subset of N hosts

Examples:

bash
# Run on a single host
nefia exec --host my-server -- uname -a
 
# Run on all hosts in a group
nefia exec --target group:webservers -- systemctl status nginx
 
# Run on all hosts with fail-fast
nefia exec --target all --fail-fast -- apt update
 
# Run within a session context
nefia exec --session <id> -- ls -la /tmp
 
# Queue for offline hosts
nefia exec --target group:laptops --when-online --queue-ttl 48h -- softwareupdate --install --all

MCP-Only Parameters:

When using nefia.exec via MCP, these additional parameters are available:

ParameterTypeDescription
stdinstringInput data to pipe to the command's stdin.
working_directorystringOverride the working directory for command execution.
uidstringRun as this user/uid on the target host.

ssh

Open an interactive SSH session to a remote host via VPN tunnel.

bash
nefia ssh <host-id> [-- <command>]

Opens a fully interactive SSH terminal session to the specified host. If a command is provided after --, it runs non-interactively and returns the output.

Arguments:

ArgumentDescription
host-idThe target host identifier.
commandOptional command to run non-interactively.

Examples:

bash
# Interactive SSH session
nefia ssh my-pc
 
# Run a single command
nefia ssh my-pc -- whoami
 
# Run a command with arguments
nefia ssh my-pc -- ls -la /var/log

All traffic flows through the WireGuard VPN tunnel. The host must have an active VPN configuration.

fs

Remote file system operations.

fs read -- Read a file
bash
nefia fs read --host <id> --path <remote-path> [--base64] [--out <local-path>]
FlagTypeDefaultDescription
--pathstringrequiredRemote file path
--base64booleanfalseForce base64-encoded output
--outstringDownload to local file (streaming, supports large files up to 3 GB)

Reads a file from the remote host and prints its contents to stdout. When --out is provided, the file is streamed directly to a local path without buffering in memory.

bash
# Read and display
nefia fs read --host web-1 --path /etc/hostname
 
# Download a large log file
nefia fs read --host web-01 --path /var/log/app/access.log --out ./access.log
fs write -- Write a file
bash
nefia fs write --host <id> --path <remote-path> [--text <content>] [--in <local-path>]
FlagTypeDefaultDescription
--pathstringrequiredRemote file path
--textstringInline text content to write
--instringUpload a local file (streaming, supports large files up to 3 GB)

Writes content to a file on the remote host. One of --text or --in is required. When --in is provided, the local file is streamed directly without buffering in memory.

bash
# Write inline text
nefia fs write --host web-1 --path /tmp/hello.txt --text "Hello"
 
# Upload a local file
nefia fs write --host db-01 --path /tmp/backup.sql.gz --in ./backup.sql.gz
fs list -- List directory contents
bash
nefia fs list --host <id> --path <remote-path>

Lists files and directories at the specified remote path. Displays type, size, modification time, and name.

fs stat -- Show file metadata
bash
nefia fs stat --host <id> --path <remote-path>

Displays file metadata including path, type, size, permissions, and modification time. Use --output json for structured output.

push

Push a local file to multiple remote hosts in parallel.

bash
nefia push <local-file> <remote-path>

The remote path must be the full destination file path (not a directory). The local file is read into memory only after target resolution and policy checks succeed, saving memory when validation fails.

FlagTypeDefaultDescription
-n, --dry-runbooleanfalsePreview what would be pushed without transferring
--batch-sizeint0Push to N hosts at a time (0 = all at once)
--batch-percentint0Push to P% of hosts per batch (1-100, mutually exclusive with --batch-size)
--batch-waitdurationWait between batches
--subsetint0Push to a random subset of N hosts
bash
# Deploy a config file to all web servers
nefia push --target group:webservers ./nginx.conf /etc/nginx/nginx.conf
 
# Push to a single host
nefia push --host my-pc ./script.sh /tmp/script.sh

sync

Synchronize a local directory to remote hosts via SFTP.

bash
nefia sync <local-dir> <remote-dir>

Only changed files are transferred (based on size and modification time by default). Use --checksum for SHA256-based comparison.

FlagTypeDefaultDescription
--checksumbooleanfalseUse SHA256 checksum for comparison instead of size+mtime
--deletebooleanfalseDelete remote files not present locally
-n, --dry-runbooleanfalsePreview changes without transferring
--excludestring[]Glob patterns to exclude (can be repeated)
--file-concurrencyint4Concurrent file transfers per host
--batch-sizeint0Sync to N hosts at a time (0 = all at once)
--batch-percentint0Sync to P% of hosts per batch (1-100, mutually exclusive with --batch-size)
--batch-waitdurationWait between batches
--subsetint0Sync to a random subset of N hosts
bash
# Sync app directory with preview
nefia sync --target group:webservers --dry-run ./dist /opt/app/dist
 
# Sync with cleanup of removed files
nefia sync --target all --delete --exclude "*.log" ./config /etc/myapp

plan exec

Create an execution plan for review before applying.

bash
nefia plan exec [flags] -- <command>
FlagTypeDefaultDescription
--outstringplan.jsonOutput plan file path

Generates a JSON execution plan that captures the target hosts, command, and policy evaluation so you can review what will happen before executing.

bash
# Generate plan
nefia plan exec --target all -- systemctl restart nginx --out plan.json
 
# Review the plan
cat plan.json
 
# Apply the plan
nefia apply plan.json

apply

Execute a saved execution plan.

bash
nefia apply <plan-file>

Runs a JSON execution plan generated by nefia plan exec. Shows a summary and prompts for confirmation before executing.


Session Commands

Session commands and their subcommands do not require authentication. They work without nefia login.

session open

Create a persistent session bound to a host and root directory.

bash
nefia session open --host <id> [--root <dir>] [--cwd <dir>]
FlagTypeDefaultDescription
--rootstringhost configured root (or remote home)Root directory on the remote host (sandbox: paths cannot escape it)
--cwdstringrootInitial working directory relative to root

Returns a session ID for subsequent file and exec operations.

session close

Close an active session.

bash
nefia session close <session-id> [--summary]
FlagTypeDefaultDescription
--summarybooleanfalseGenerate and display a session summary after closing

When --summary is provided, a structured summary of session activity is generated and printed before the session is closed.

session list

List all active sessions.

bash
nefia session list
session recordings -- List saved terminal recordings
bash
nefia session recordings [--limit N]
FlagTypeDefaultDescription
--limitint0Limit the number of recordings shown (0 = all)

Lists saved session recordings with session ID, size, and creation time.

session replay -- Replay a recording locally
bash
nefia session replay <session-id> [--speed <factor>]
FlagTypeDefaultDescription
--speedfloat1Playback speed (0 = instant, 1 = real-time, 5 = 5x)

Replays a stored session recording to the terminal. Press Ctrl+C to stop replay cleanly.

session export -- Export a recording as .cast
bash
nefia session export <session-id> [--out <path>]
FlagTypeDefaultDescription
--outstring<session-id>.castOutput file path

Exports a saved recording as an asciinema-compatible .cast file.

session summary

Generate an AI-consumable summary of a session.

bash
nefia session summary <session-id>

Generates a structured summary of session activity from audit records. The summary includes commands executed, files read/written, error count, duration, and a markdown narrative. It is persisted to disk and can be retrieved later.

bash
nefia session summary <session-id>
nefia session summary <session-id> --output json

ping

Test point-to-point VPN latency to a specific host.

bash
nefia ping <host-id> [flags]
FlagTypeDefaultDescription
-n, --countint5Number of probes to send (0 = until interrupted)
--intervalduration1sInterval between probes
--timeoutduration5sPer-probe timeout
--sshbooleanfalseAlso verify that the remote SSH daemon responds

Creates a temporary tunnel, probes the target VPN address, and prints aggregate loss and latency statistics.


VPN Commands

vpn keygen -- Generate WireGuard keypair
bash
nefia vpn keygen [--force]
FlagTypeDefaultDescription
--forcebooleanfalseOverwrite existing keypair without confirmation

Generates a new WireGuard keypair and saves it to your configuration. The private key is stored in the OS keyring when possible, falling back to plaintext in the config file. Usually done automatically by nefia setup.

vpn show-config -- Display VPN configuration
bash
nefia vpn show-config

Displays the current VPN configuration including public key, listen port (port 0 is resolved to the default 51820), address, and all configured peers.

vpn invite -- Generate enrollment token
bash
nefia vpn invite --name <hostname> --os <macos|linux|windows> [flags]
FlagTypeDefaultDescription
--namestringrequiredHostname for the target. Must match ^[a-zA-Z0-9][a-zA-Z0-9._-]{0,62}$.
--osstringrequiredTarget OS: macos, linux, or windows
--endpointstringOperator's public endpoint (ip:port) for direct connection
--stunbooleanfalseUse STUN to discover public endpoint
--ttlduration24hToken validity duration
--enroll-portint19820Enrollment listener port
--listenbooleantrueStart enrollment listener after generating invite
--listen-timeoutduration60mEnrollment listener timeout
--token-outstringWrite the raw token to a file (permissions: 0600) instead of printing to stdout
--copybooleanfalseCopy the invite token to the system clipboard
--fleetbooleanfalseCreate a fleet token for multi-agent self-registration
--countint0Max uses for fleet token (0 = unlimited, only with --fleet)
--approval-modestringauto-approveApproval mode for fleet enrollment: auto-approve or require-approval
--no-print-tokenbooleanfalseSuppress human-readable token output (useful for TUI and internal automation)

Creates a single-use, HMAC-SHA256 signed enrollment token for a new target PC. When --fleet is used, creates a multi-use fleet token that allows multiple agents to enroll without individual invitations. If the operator is logged in, a cloud relay session is also created so agents behind NAT can enroll without a direct connection.

If neither a direct endpoint nor cloud relay is available, the command returns an error instead of creating an unusable invite.

After generating the token, vpn invite prints platform-specific installation instructions including a one-liner command to run on the target PC.

vpn reinvite -- Regenerate enrollment token
bash
nefia vpn reinvite --name <hostname> [flags]
FlagTypeDefaultDescription
--namestringrequiredHost ID to reinvite
--osstringexistingOverride target OS: macos, linux, or windows
--endpointstringOperator's public endpoint (ip:port)
--stunbooleanfalseUse STUN to discover endpoint
--ttlduration24hToken validity duration
--enroll-portint19820Enrollment listener port
--listenbooleantrueStart enrollment listener after generating invite
--listen-timeoutduration60mEnrollment listener timeout
--token-outstringWrite the raw token to a file (permissions: 0600)
--copybooleanfalseCopy the invite token to the system clipboard
--no-print-tokenbooleanfalseSuppress human-readable token output (useful for TUI and internal automation)

Regenerates an invite token for an existing host. The host is reset to pending status while preserving its VPN address. Use this when a previous invite has expired or when re-enrolling an active host.

bash
# Regenerate expired invite
nefia vpn reinvite --name my-server --stun
 
# Change OS and regenerate
nefia vpn reinvite --name my-server --os linux --endpoint 203.0.113.10:51820
vpn listen -- Start enrollment listener
bash
nefia vpn listen [--timeout <duration>] [--count <n>]
FlagTypeDefaultDescription
--timeoutduration60mMax time to wait per enrollment
--countint0Number of enrollments to accept. 0 enrolls all pending hosts, automatically stopping when none remain.

Listens for incoming enrollment requests from target PCs. When --count is set, the listener stops automatically after the specified number of successful enrollments.

The listener prints a heartbeat progress message every 30 seconds while waiting for enrollments.

bash
# Enroll all pending hosts
nefia vpn listen --count 0
 
# Enroll exactly 3 hosts with a longer timeout
nefia vpn listen --count 3 --timeout 2h
vpn enroll-status -- Check enrollment status
bash
nefia vpn enroll-status --name <name>

Checks the enrollment status of a specific host. Displays host ID, status, VPN address, public key, and expiration. Warns when an invite has expired.

vpn status -- Show connection status
bash
nefia vpn status [--live] [--ping]
FlagTypeDefaultDescription
--livebooleanfalseStart tunnel and show real-time peer stats
--pingbooleanfalseTest TCP connectivity to each active peer (3s timeout)

Without --live, displays VPN configuration status and peer list. With --live, starts the tunnel and shows real-time peer statistics including endpoint, handshake timestamps, transfer counters, and MagicDNS records. Peers with no recent handshake are marked STALE.

The --ping flag tests TCP connectivity to each active peer using the SSH port from host configuration, falling back to port 22.

vpn diagnose -- Run VPN diagnostics
bash
nefia vpn diagnose [--host <id>]
FlagTypeDefaultDescription
--hoststringDiagnose a specific host only

Runs comprehensive diagnostic checks on VPN configuration, peer validation, and connectivity. Reports results as [PASS], [WARN], or [FAIL].

Diagnostic checks include:

  • Latency measurement: Each active peer is probed with a TCP dial. Results are classified as [FAST] (< 500ms), [OK] (< 2s), or [SLOW] (> 2s).
  • Route conflict detection: Checks for overlapping routes between the VPN subnet and existing network interfaces. Detects subnet conflicts that can cause routing failures.
vpn rotate-key -- Rotate WireGuard key
bash
nefia vpn rotate-key [--grace-period <duration>]
FlagTypeDefaultDescription
--grace-periodduration72hGrace period for old key retention

Generates a new WireGuard keypair and stores it. After rotation, run nefia vpn push-key to distribute the new public key to all active hosts. The result includes a Warning field when there are conditions that require attention (e.g. hosts that could not be reached during rotation).

vpn push-key -- Distribute public key
bash
nefia vpn push-key [--host <id>]
FlagTypeDefaultDescription
--hoststringPush key to a specific host only

Pushes the current operator public key to all active VPN peers. If a key rotation is in progress, the command temporarily uses the previous key to reach hosts that have not yet received the new key.

vpn token-info -- Inspect an invite token
bash
nefia vpn token-info --token <token>
FlagTypeDefaultDescription
--tokenstringrequiredThe invite token string to inspect

Display the contents of an invite token without verifying the signature. Useful for inspecting token payloads, checking expiry, and debugging enrollment issues.

nefia vpn token-info --token '...'

Host ID: mac-dev VPN Address: 10.99.0.2 Operator PK: xYz1...aBcD= Endpoint: 203.0.113.10:19820 Nonce: a1b2c3... Expires At: 2026-03-02T12:00:00Z (expires in 23h45m)

If the token has expired, the output shows an [EXPIRED] label:

nefia vpn token-info (expired)

Host ID: mac-dev ... Expires At: 2026-02-28T12:00:00Z [EXPIRED] 2d5h ago

vpn approve -- Approve pending host(s) for VPN access
bash
nefia vpn approve --name <hostname>
nefia vpn approve --all --accept-risk=approve-all
FlagTypeDefaultDescription
--namestringPending host ID to approve
--allbooleanfalseApprove all pending-approval hosts
--timeoutduration60mMax time to wait for the approved host to enroll
--accept-riskstringRequired risk acknowledgment when using --all (must be approve-all)

Approve a specific pending host or all pending-approval hosts.

For hosts enrolled via single-use tokens (status: pending), opens a targeted enrollment listener and waits for the agent to connect. For hosts enrolled via fleet tokens (status: pending-approval), immediately transitions the host to active status.

The --name and --all flags are mutually exclusive. When using --all, you must pass --accept-risk=approve-all to explicitly acknowledge the bulk operation. The --yes flag does not bypass this requirement.

bash
# Approve and wait for a pending host
nefia vpn approve --name my-pc
 
# Approve a fleet-enrolled host immediately
nefia vpn approve --name fleet-host-1
 
# Approve all pending-approval hosts at once
nefia vpn approve --all --accept-risk=approve-all
vpn fleet list -- List active fleet tokens
bash
nefia vpn fleet list

Lists all active fleet tokens. Each entry shows the token nonce, usage count (used/max or used/inf for unlimited), approval mode, expiry status, and creation time.

Create a fleet token with nefia vpn invite --fleet.

vpn fleet revoke -- Revoke a fleet token
bash
nefia vpn fleet revoke <nonce>

Revokes the fleet token identified by the given nonce. Once revoked, no new agents can enroll using that token. Hosts that have already enrolled are not affected.


Team Management Commands

team list

List all teams you belong to.

bash
nefia team list

Displays a table of teams with slug, name, plan, your role, member count, and host count. The currently active team is marked with *.

team current

Show the currently active team.

bash
nefia team current

Displays the active team's slug, name, ID, plan, your role, member count, and host count. If no team is selected, shows "personal" (your default workspace).

Running nefia team with no subcommand also shows the current team.

team use

Switch the active team.

bash
nefia team use <slug>

Sets the active team for subsequent commands. The choice is persisted to the config file. Use personal to switch back to your personal workspace.

It can also be overridden per-command with --team or the NEFIA_TEAM environment variable.

team create

Create a new shared team.

bash
nefia team create --name <name>
FlagTypeDefaultDescription
--namestringrequiredDisplay name for the team

Creates a new team and sets you as the owner. A URL-safe slug is generated from the name.

team invite

Generate an invitation code for the active team.

bash
nefia team invite [--role MEMBER|ADMIN] [--max-uses N] [--expires H]
FlagTypeDefaultDescription
--rolestringMEMBERRole to assign to invitees: MEMBER or ADMIN
--max-usesint1Maximum number of times the code can be used (1-100)
--expiresint48Expiration in hours (max: 168)

Generates a single-use or multi-use invitation code. Requires ADMIN or OWNER role.

team join

Join a team via invitation code.

bash
nefia team join <code>

Joins the team associated with the invitation code. The code must be valid, unexpired, and not fully used.

team members

List members of the active team.

bash
nefia team members

Displays a table of team members with email, name, role, and join date.

team role

Change a member's role in the active team.

bash
nefia team role <email> --role <ADMIN|MEMBER>
FlagTypeDefaultDescription
--rolestringrequiredNew role for the member (ADMIN or MEMBER)

Requires OWNER role. Cannot demote the last owner of a team.

team leave

Leave the active team.

bash
nefia team leave

Removes you from the active team and switches to your personal workspace. You cannot leave your personal team. Team owners must transfer ownership first.


Configuration Commands

config show

Show the resolved configuration with source annotations.

bash
nefia config show [--reveal] [--filter <substring>]
FlagTypeDefaultDescription
--revealbooleanfalseShow sensitive values such as keys, tokens, and passwords
--filterstringFilter displayed keys by substring

By default, sensitive fields are masked. Sources are annotated as config file, environment override, or default.

config ssh-config

Generate OpenSSH config entries for Nefia-managed hosts.

bash
nefia config ssh-config [--write] [--identity-file <path>]
FlagTypeDefaultDescription
--writebooleanfalseWrite directly to ~/.ssh/config.d/nefia instead of stdout
--identity-filestringauto-detectSSH private key path to include in generated host blocks

Hosts with active VPN addresses use the VPN IP as HostName. Pending hosts are skipped.


Profile Commands

profile list

List available config profiles.

bash
nefia profile list

Profiles live under ~/.config/nefia/profiles/. The active profile is marked with * when --profile or NEFIA_PROFILE is set.

profile show

Show the raw contents of a profile file.

bash
nefia profile show <name>

Displays the profile path and YAML content.

profile create

Create a new profile from the built-in template.

bash
nefia profile create <name>

Writes a starter profile file and prints example activation commands.


Host Management Commands

hosts list

List all configured hosts.

bash
nefia hosts list

Displays a table of all hosts with ID, address, OS, user, VPN status, and tags.

hosts show

Display detailed host information.

bash
nefia hosts show <host-id>

hosts remove

Remove a host from configuration.

bash
nefia hosts remove <host-id>
hosts import -- Import hosts from external sources
bash
nefia hosts import --from <source> [--file <path>] [--dry-run]
FlagTypeDefaultDescription
--fromstringSource type: ssh-config, ansible-inventory, known-hosts, csv (required)
--filestringautoSource file path (optional for ssh-config and known-hosts, required for ansible-inventory and csv)
--dry-runbooleanfalseShow what would be imported without making changes

Parses hosts from external sources and adds new hosts to your configuration. Existing hosts are skipped. Imported hosts receive address, user, and port settings but no VPN configuration.

CSV files require a header row with at least one of: id, hostname, host, address, or ip. Optional columns: user, os, port, tags.

bash
# Import from default SSH config
nefia hosts import --from ssh-config
 
# Import from Ansible inventory
nefia hosts import --from ansible-inventory --file inventory.yml
 
# Preview what would be imported
nefia hosts import --from known-hosts --dry-run
 
# Import from CSV without prompting
nefia hosts import --from csv --file hosts.csv --yes
hosts refresh -- Refresh host metadata via SSH
bash
nefia hosts refresh [--target <selector>] [--categories <list>]
FlagTypeDefaultDescription
--targetstringallHost selector (host ID, group name, or tag selector)
--categoriesstringallFact categories to collect (comma-separated: os, disk, memory, cpu, uptime, network)

Connects to hosts via SSH and collects system metadata (OS, CPU, memory, network). Only hosts with active VPN connections are probed. Collected metadata is stored in the host's meta field in nefia.yaml.

bash
# Refresh all active hosts
nefia hosts refresh
 
# Refresh a specific host
nefia hosts refresh --target host-1
 
# Collect only specific categories
nefia hosts refresh --categories os,cpu

revoke

Emergency revoke of a host's VPN access.

bash
nefia revoke <host>
nefia revoke --all --accept-risk=revoke-all

revoke clears the stored peer configuration and removes the host from inventory so future reconnection attempts fail immediately.

groups list

List all configured host groups.

bash
nefia groups list

Shows groups with their tag filter criteria.

power wake

Wake an offline host with Wake-on-LAN.

bash
nefia power wake <host> [--proxy <online-host>] [--wait] [--timeout <duration>]
FlagTypeDefaultDescription
--proxystringautoOnline proxy host that sends the WoL magic packet
--waitbooleanfalsePoll until the target host comes back online
--timeoutduration60sTimeout used with --wait

Nefia resolves the target MAC from host.mac first, then from collected host metadata. If you omit --proxy, it tries to find an active agent on the same /24 subnet automatically.

recording

Manage session recordings (asciinema v2 .cast.gz files). Recording commands and their subcommands do not require authentication and work without nefia login.

recording list -- List session recordings
bash
nefia recording list [--limit <N>]
FlagTypeDefaultDescription
--limitint0Limit number of recordings shown (0 = all)

Lists session recordings with session ID, host, user, date, duration, and file size.

recording replay -- Replay a recording in the terminal
bash
nefia recording replay <session-id> [--speed <factor>]
FlagTypeDefaultDescription
--speedfloat1Playback speed (0 = instant, 1 = real-time, 5 = 5x)

Replays a stored session recording to the terminal. Press Ctrl+C to stop replay cleanly.

recording export -- Export a recording as .cast
bash
nefia recording export <session-id> [--out <path>]
FlagTypeDefaultDescription
--outstring<session-id>.castOutput file path

Exports a saved recording as an asciinema-compatible .cast file.

recording delete -- Delete a recording
bash
nefia recording delete <session-id>

Deletes a recording file. Prompts for confirmation before deleting. Use --yes to skip.


Playbook Commands

playbook run

Execute a playbook against target hosts.

bash
nefia playbook run <name-or-path> [flags]
FlagTypeDefaultDescription
--varstring[]Template variable override (key=value, can be repeated)
--dry-runbooleanfalsePreview execution plan without running
--step-timeoutdurationDefault step timeout (e.g. 60s, 5m)

Playbooks are discovered from search paths (in priority order):

  1. Direct file path (if path separator or .yaml/.yml extension present)
  2. ./playbooks/<name>.yaml
  3. User config directory (e.g. ~/.config/nefia/playbooks/<name>.yaml)
bash
nefia playbook run setup-monitoring --target group:webservers
nefia playbook run ./playbooks/deploy.yaml --target all --dry-run
nefia playbook run security-baseline --host pc-office --var port=9100

playbook validate

Validate playbook YAML syntax.

bash
nefia playbook validate <path>

playbook list

List available playbooks from the search paths.

bash
nefia playbook list

playbook show

Display playbook details including name, description, variables, and all steps.

bash
nefia playbook show <name-or-path>

Schedule Commands

schedule create -- Create a schedule
bash
nefia schedule create --name <name> --cron <expr> --playbook <file> --target <selector> [flags]
FlagTypeDefaultDescription
--namestringrequiredSchedule name
--cronstringrequiredCron expression (e.g. "0 2 * * *")
--playbookstringrequiredPlaybook name or path
--targetstringrequiredTarget selector (all, host:<id>, group:<name>)
--varstring[]Template variable override (key=value)
--timezonestringlocalIANA timezone (e.g. Asia/Tokyo)
--overlap-policystringOverlap policy: skip, cancel_running, allow
--missed-run-policystringMissed run policy: skip, run_once
--descriptionstringOptional description

Creates a cron-based schedule for recurring playbook execution. After creation, shows the next 3 upcoming runs.

bash
nefia schedule create --name daily-backup --cron "0 2 * * *" --playbook backup --target all
nefia schedule create --name hourly-check --cron "0 * * * *" --playbook health --target group:web --timezone Asia/Tokyo
schedule list -- List all schedules
bash
nefia schedule list

Shows all schedules with their name, cron expression, playbook, target, status (enabled/disabled), and last run time. Also displays whether the daemon is running.

schedule show -- Show schedule details
bash
nefia schedule show <id-or-name>

Displays full schedule details including cron description, variables, overlap/missed-run policies, last run status, and the next 5 upcoming runs.

schedule update -- Modify a schedule
bash
nefia schedule update <id-or-name> [flags]
FlagTypeDescription
--cronstringNew cron expression
--playbookstringNew playbook name or path
--timezonestringNew IANA timezone
--overlap-policystringOverlap policy
--missed-run-policystringMissed run policy
--descriptionstringNew description
--enabledstringEnable/disable (true or false)
schedule delete -- Remove a schedule
bash
nefia schedule delete <id-or-name>

Prompts for confirmation before deleting. Use --yes to skip.

schedule enable / disable -- Toggle a schedule
bash
nefia schedule enable <id-or-name>
nefia schedule disable <id-or-name>
schedule history -- Show execution history
bash
nefia schedule history [id-or-name] [--limit N]
FlagTypeDefaultDescription
--limitint20Maximum number of records to show

Shows execution history with start time, schedule name, trigger type, status, duration, and host success counts. When called without an argument, shows history for all schedules.

schedule trigger -- Manually trigger a schedule
bash
nefia schedule trigger <id-or-name>

Runs the schedule's playbook immediately, bypassing the cron expression. The schedule does not need to be enabled. This command executes the playbook directly and does not require the daemon to be running.


Queue Commands

queue list

List offline commands queued by nefia exec --when-online.

bash
nefia queue list [--status <state>]
FlagTypeDefaultDescription
--statusstringpendingFilter by pending, running, completed, failed, expired, cancelled, or all

Human output shows the queue ID, host, status, truncated command, and expiry timestamp.

queue show

Show details for a queued command.

bash
nefia queue show <id>

Displays the full details of a queue entry including ID, host, status, command, timestamps, retry lineage, and execution results (exit code, stdout, stderr) if available.

queue cancel

Cancel a queued command before it runs.

bash
nefia queue cancel <id>

queue retry

Create a new pending entry from a failed, expired, or cancelled queue entry.

bash
nefia queue retry <id> [--ttl <duration>]

Alias: requeue

FlagTypeDefaultDescription
--ttlduration24hTTL for the new queued retry entry

The new entry is linked to the original via a retry_of field. The host must still exist in the configuration.

bash
# Retry a failed queue entry with default TTL
nefia queue retry abc123
 
# Retry with a custom TTL
nefia queue retry abc123 --ttl 48h

Webhook Commands

webhook list

List configured webhook destinations from alerts.webhooks.

bash
nefia webhook list

webhook test

Send a test event to every configured webhook.

bash
nefia webhook test [--type <event-type>]
FlagTypeDefaultDescription
--typestringtestEvent type to send

webhook send

Send a custom webhook event.

bash
nefia webhook send --type <event-type> --message <text> [--details key=value]
FlagTypeDefaultDescription
--typestringrequiredEvent type
--messagestringrequiredEvent message
--detailsstring[]Additional key=value pairs (repeatable)

Webhook delivery waits up to 30 seconds for completion and returns an error if no webhooks are configured.


Agent Management

agent version

Show the nefia-agent version on remote hosts.

bash
nefia agent version [--target <selector>]

Defaults to all if no target is specified. Displays version, compatibility status, and any messages per host.

agent upgrade

Upgrade nefia-agent on remote hosts.

bash
nefia agent upgrade [--target <selector>] [--agent-dir <dir>]
FlagTypeDefaultDescription
--agent-dirstringDirectory containing agent binaries

Prompts for confirmation before upgrading. Displays old and new version for each host.

agent update

Trigger remote agent self-update via update server.

bash
nefia agent update [--target <selector>] [--version <version>]
FlagTypeDefaultDescription
--versionstringTarget version (empty = latest)

Unlike agent upgrade which pushes a binary from the operator, this command instructs the agent to pull its own update from its configured update server. It enables auto-update in the agent config, optionally sets a pinned version, and restarts the agent service.

bash
# Update agent on a specific host to the latest version
nefia agent update --host my-pc
 
# Update agent to a specific version
nefia agent update --host my-pc --version v1.2.0

agent pin

Pin agent to a specific version on remote hosts.

bash
nefia agent pin <version> [--target <selector>]

Sets the pinned_version in the remote agent config. When pinned, the agent's auto-update will only update to the specified version and will not automatically upgrade beyond it.

bash
nefia agent pin v1.2.0 --host my-pc
nefia agent pin v1.2.0 --target all

agent unpin

Clear pinned version on remote agents.

bash
nefia agent unpin [--target <selector>]

Clears the pinned_version in the remote agent config. The agent's auto-update will resume tracking the latest available version.

bash
nefia agent unpin --host my-pc
nefia agent unpin --target all

Audit Commands

audit tail -- Show recent records
bash
nefia audit tail [-n <count>]
FlagTypeDefaultDescription
-nint200Number of records to show

Displays the most recent audit log entries in a table with sequence number, timestamp, host, operation, job ID, and user.

audit show -- Show records for a job
bash
nefia audit show --job <job-id>

Displays all audit records associated with a specific job ID in JSON format.

audit verify -- Verify hash chain
bash
nefia audit verify [date] [--range <range>]
FlagTypeDefaultDescription
--rangestringDate range to verify (e.g. 7d, 30d, 2026-03-01..2026-03-08)

Verifies the hash chain integrity of an audit log file for a given date (YYYY-MM-DD format). Defaults to today. Verifies both the SHA-256 hash chain and HMAC signatures when the key is available. Use --range to verify multiple dates at once.

audit list -- List audit records with filtering
bash
nefia audit list [flags]
FlagTypeDefaultDescription
--datestringtodaySpecific date (YYYY-MM-DD)
--rangestringDate range (e.g. 7d, 30d, 2026-03-01..2026-03-08)
--opstringFilter by operation kind
--hoststringFilter by host ID
--userstringFilter by user
--limitint100Max records to display
--reversebooleanfalseReverse chronological order
--summarybooleanfalseHuman-readable summary format (one line per record)

Lists audit records with filtering. The --summary flag outputs a human-readable one-line-per-record format: 2024-01-15 10:30:00 | exec | user@host | ls -la | success.

bash
# List today's audit records
nefia audit list
 
# List records for a specific date
nefia audit list --date 2026-03-01
 
# Filter by operation type
nefia audit list --op exec --range 7d
 
# Filter by host and limit results
nefia audit list --host my-pc --limit 50
 
# Show records in reverse order
nefia audit list --range 30d --reverse
 
# Human-readable summary
nefia audit list --summary

System Commands

account

Show account and subscription information.

bash
nefia account

Displays your plan, status, host count, limits, and cancellation status.

status

Show system status overview with per-host connectivity.

bash
nefia status [--no-check] [--active]
FlagTypeDefaultDescription
--no-checkbooleanfalseSkip connectivity checks for faster output
--activebooleanfalseShow only online hosts in the host table

Displays version, config path, VPN status, policy mode, audit status, auth state, host/group/session counts, and a per-host connectivity table.

When VPN is enabled and --no-check is not set, the command creates a standalone VPN tunnel and probes each active host with a TCP dial (3-second timeout, up to 10 concurrent). The host table shows:

nefia status

Nefia Status Version: 1.0.0 Config: /Users/admin/.config/nefia/nefia.yaml

VPN: enabled (3 active, 1 pending) Policy: enforce Audit: enabled (dir: /Users/admin/.local/state/nefia/audit, today: 42 records) Auth: logged in Hosts: 4 configured Groups: 2 configured Sessions: 1 active

Hosts: ID OS VPN CONNECTION LATENCY my-pc macos active online 12ms office-pc windows active offline - dev-server linux pending - - backup-srv linux active online 45ms

2 online, 1 offline, 1 pending

Use --no-check for fast output without connectivity probing. Use --output json for structured output including a hosts array.

validate

Validate configuration and optionally test host connectivity.

bash
nefia validate [--target <selector>]

When a --target is specified, resolves the selector and tests SSH connectivity to each matched host via the VPN tunnel.

bugreport

Generate a sanitized diagnostic bundle for support and debugging.

bash
nefia bugreport [--output-file <path>]
FlagTypeDefaultDescription
--output-filestringstdoutWrite the report to a file instead of stdout

The bundle includes system information, sanitized config structure, VPN status, doctor output, and recent audit errors. Private keys, tokens, passwords, SSH keys, API keys, and full command lines are excluded.

update

Check for and apply updates to the Nefia CLI.

bash
nefia update [--check]
FlagTypeDefaultDescription
--checkbooleanfalseCheck for updates without applying

Downloads the latest release, verifies the Ed25519 signature, and atomically replaces the running binary.

backup

Back up configuration and state to a tar.gz archive.

bash
nefia backup [--output <path>]
FlagTypeDefaultDescription
--outputstringnefia-backup-YYYY-MM-DD.tar.gzOutput archive path

Archives the configuration file, audit logs, and session state. Sensitive files (keys, tokens, secrets) are automatically excluded.

restore

Restore configuration and state from a backup archive.

bash
nefia restore <archive-path>

Extracts files from a backup archive to the config and state directories. Includes Zip Slip protection and skips sensitive files. Prompts for confirmation before restoring.

version

Show version, build, and runtime information.

bash
nefia version

Displays the nefia version, git commit, build date, Go version, and OS/architecture.


Diagnostics Commands

netcheck

Run compact VPN network diagnostics.

bash
nefia netcheck [--host <id>]
FlagTypeDefaultDescription
--hoststringLimit connectivity tests to a single host

netcheck is the top-level, discoverable form of nefia vpn diagnose. It summarizes NAT type, STUN reachability, DERP RTTs, TURN/relay availability, route conflicts, and per-host connectivity.

doctor

Run comprehensive system health checks covering configuration, authentication, audit, VPN, and host connectivity.

bash
nefia doctor [--host <id>]
FlagTypeDefaultDescription
--hoststringCheck a specific host only
--strictbooleanfalseTreat warnings as failures (exit non-zero). Useful for CI pipelines

Similar to brew doctor or tailscale netcheck, this command runs a multi-phase diagnostic suite and reports results as [PASS], [WARN], or [FAIL].

Phases:

  1. Config -- Verifies the configuration file can be found and loaded
  2. Auth -- Checks whether the user is logged in
  3. Audit -- Validates audit logging is enabled and the audit directory is writable
  4. VPN -- Runs all vpn diagnose checks (keypair, port availability, peer validation, STUN, address uniqueness)
  5. Connectivity -- Creates a standalone VPN tunnel and TCP-dials each active host (10 concurrent, 3s timeout)
nefia doctor

Nefia Doctor: [PASS] config-path: Configuration found at /Users/admin/.config/nefia/nefia.yaml [PASS] config-load: Configuration loaded successfully [PASS] auth-status: Logged in [PASS] audit-config: Audit logging is enabled [PASS] audit-dir: Audit directory is writable: /Users/admin/.local/state/nefia/audit [PASS] vpn-enabled: VPN is enabled [PASS] operator-keypair: operator keypair is valid [PASS] port-available: UDP port 51820 is available [PASS] enrollment-port: TCP port 19820 (enrollment) is available [PASS] vpn-addr-unique: all 3 VPN addresses are unique [PASS] ssh-identity: SSH public key found in ssh.identities [PASS] stun-reachability: STUN reachable (public IP: 203.0.113.10) [PASS] peer-my-pc-connectivity: Connection OK (12ms) [WARN] peer-office-pc-connectivity: Connection failed: dial timeout

Result: 12 passed, 1 warning, 0 failures

Exit codes:

  • 0 -- All checks passed (warnings are allowed)
  • 1 -- One or more checks failed

Use --output json for structured output with a checks array and summary object.

explain

Look up an error code and display detailed resolution steps.

bash
nefia explain [code] [--list]
FlagTypeDefaultDescription
--listbooleanfalseList all registered error codes

Accepts both structured codes (e.g., E2001) and domain codes (e.g., SSH_AUTH_FAILED).

All domain errors in Nefia are produced using the sentinel error pattern (types.Errorf(types.ErrXxx, ...)). The CLI classifies errors via errors.Is() to determine the appropriate exit code and user-facing message. nefia explain displays the resolution steps and documentation links for a given error code.

bash
# Look up a specific error code
nefia explain E2001
 
# Look up by domain code
nefia explain SSH_AUTH_FAILED
 
# List all error codes
nefia explain --list
nefia explain E2001

Error [E2001]: SSH authentication failed

The SSH key or credentials were rejected by the remote host.

Resolution:

  1. Verify the SSH key: ssh -i ~/.ssh/id_ed25519 <user>@<host>
  2. Check key file permissions: chmod 600 ~/.ssh/id_ed25519
  3. Ensure the public key is in the remote host's ~/.ssh/authorized_keys.
  4. Re-enroll the host if SSH keys were rotated: nefia vpn reinvite --host <host>

Docs: https://www.nefia.ai/docs/errors/E2001


Agent Binary

nefia-agent

The nefia-agent binary runs on target PCs and establishes the WireGuard tunnel back to the operator. It is installed during enrollment.

nefia-agent enroll -- Enroll with an invite token
bash
nefia-agent enroll [--token <token> | --token-file <path>] [--install] [--yes]
FlagTypeDefaultDescription
--tokenstringRaw invite token from the operator
--token-filestringRead the invite token from a file
--installbooleanfalseInstall the system service immediately after enrollment
--out-dirstring~/.nefiaDirectory used for generated agent.yaml
--ssh-addrstring127.0.0.1:22Local SSH server address the agent should expose through the tunnel
--forcebooleanfalseOverwrite an existing agent.yaml without prompting
--yesbooleanfalseSkip the SSH public-key confirmation prompt

Enrolls the agent with the operator using the provided invite token. Performs WireGuard key exchange, writes agent.yaml, and can register the system service automatically with --install.

nefia-agent run -- Start the agent
bash
nefia-agent run [flags]
FlagTypeDefaultDescription
--strict-permissionsbooleantrueRefuse to start if config file has world-readable permissions and contains a plaintext private key
--auto-update-intervalduration0Interval for checking binary changes and auto-restarting (0 = disabled, e.g. 5m)
--log-filestringplatform defaultPath to the log file
--log-max-sizeint50Maximum log file size in megabytes before rotation
--log-max-backupsint5Number of rotated log files to retain
--log-max-ageint30Maximum number of days to retain rotated log files

Starts the agent process. Establishes and maintains the WireGuard tunnel, handles SSH forwarding, and reports endpoints to the cloud API.

Default log file locations:

PlatformPath
macOS~/Library/Logs/nefia/agent.log
Linux$XDG_STATE_HOME/nefia/agent.log (default: ~/.local/state/nefia/agent.log)
Windows%LOCALAPPDATA%\nefia\logs\agent.log

Log rotation is handled by lumberjack. When the log file exceeds --log-max-size, it is rotated and compressed. Old files are pruned based on --log-max-backups and --log-max-age.

nefia-agent install-service / uninstall-service / status / wol
bash
nefia-agent install-service
nefia-agent uninstall-service [--yes]
nefia-agent status
nefia-agent wol --mac <mac-address> [--broadcast <ip:port>]
CommandPurpose
install-serviceRegister the agent as a platform-native background service (launchd, systemd, or schtasks)
uninstall-serviceRemove the registered service. --yes skips the confirmation prompt
statusShow the last persisted health report from the agent
wolSend a Wake-on-LAN magic packet directly from the agent

nefia-agent wol is primarily used by nefia power wake through a proxy agent on the same subnet.


DERP Server

nefia-derp

The nefia-derp binary runs a standalone DERP relay server for NAT traversal when direct peer-to-peer connections are not possible.

bash
nefia-derp [flags]
FlagTypeDefaultDescription
--addrstring:8443Listen address
--allowed-keys-filestringPath to a file containing allowed WireGuard public keys (one base64 key per line). When set, only listed keys can use the relay.
--max-clientsint10000Maximum number of concurrent clients
--metrics-tokenstringBearer token for authenticated /healthz metrics. Without this, /healthz returns basic liveness only. Can also be set via NEFIA_DERP_METRICS_TOKEN environment variable.
--ping-intervalduration30sKeepalive ping interval
--trust-proxyboolfalseTrust Fly-Client-IP / X-Forwarded-For headers for rate limiting. Enable when running behind a reverse proxy.
--versionboolfalsePrint version and exit

Example:

bash
# Start with ACL and metrics authentication
nefia-derp --addr :8443 --allowed-keys-file /etc/nefia/allowed-keys.txt --metrics-token "secret-token"

Advanced Commands

dashboard

Launch the interactive TUI dashboard.

bash
nefia dashboard

Also available by running nefia with no subcommand in a terminal.

daemon

Run the background daemon for scheduled playbook execution and background tasks.

daemon run -- Start the daemon in the foreground
bash
nefia daemon run

Starts the Nefia daemon in the foreground. The daemon manages scheduled playbook execution, VPN monitoring, host sync, idle sweep, and key rotation scheduling. Acquires an exclusive PID lock to prevent multiple instances.

Also available as nefia daemon (no subcommand).

daemon install -- Generate platform-specific service configuration
bash
nefia daemon install

Generates a service configuration file for the current platform and prints it to stdout:

  • macOS: launchd plist (~/Library/LaunchAgents/ai.nefia.daemon.plist)
  • Linux: systemd unit (~/.config/systemd/user/nefia-daemon.service)
  • Windows: Task Scheduler (schtasks) command

mcp serve

Start the MCP (Model Context Protocol) server for AI agent integration.

bash
nefia mcp serve

Starts a JSON-RPC 2.0 server over stdio. AI agents like Claude can connect to this server to execute commands and manage files within the policy engine's guardrails. The MCP server hot-reloads configuration changes and starts background VPN monitoring, idle sweep, and host sync.

mcp serve-mtls

Start the MCP server over mTLS TCP.

bash
nefia mcp serve-mtls

Starts the MCP server as a network gateway using mutual TLS authentication instead of stdio. Requires mcp.mtls.enabled: true in configuration (set up via nefia mtls init). Each client connection is authenticated by its client certificate CN, which is used as the agent identity for audit and policy purposes.

docs

Open the documentation site in your default browser.

bash
nefia docs [topic]

Available topics are audit, config, exec, fs, mcp, playbook, policy, push, schedule, and vpn. In JSON output mode, the command returns the resolved URL instead of launching a browser.

completion

Generate shell completion scripts.

bash
nefia completion [bash|zsh|fish|powershell]
FlagTypeDefaultDescription
--installbooleanfalseInstall the generated completion file to the standard location
--pathstringCustom installation path (overrides the standard location)
bash
# Bash (add to ~/.bashrc)
eval "$(nefia completion bash)"
 
# Zsh (add to ~/.zshrc)
eval "$(nefia completion zsh)"
 
# Fish
nefia completion fish | source
powershell
# PowerShell (add to $PROFILE)
nefia completion powershell | Out-String | Invoke-Expression

device-lock

Cryptographic device verification for the VPN mesh (Tailnet Lock style). Uses an Ed25519 authority keypair to sign each host's WireGuard public key. Only hosts with a valid, non-revoked signature are permitted to connect when device lock is enabled.

Alias: dl

device-lock init -- Generate authority keypair
bash
nefia device-lock init

Generates a new Ed25519 authority keypair for device lock. The private key is stored in the OS keyring (macOS Keychain, Windows Credential Manager, or file-based fallback on Linux). The public key is stored in the device lock trust store file.

Also sets device_lock.enabled: true and device_lock.mode: log in the config.

device-lock sign -- Sign a host's WireGuard key
bash
nefia device-lock sign <host-id>

Signs the specified host's WireGuard public key with the authority key and adds the attestation to the trust store. The host must have an active VPN enrollment with a public key.

device-lock verify -- Verify all hosts' signatures
bash
nefia device-lock verify

Verifies the device lock status of all configured hosts. Each host is classified as trusted, untrusted, pending, or no_vpn.

device-lock revoke -- Revoke a host's attestation
bash
nefia device-lock revoke <host-id>

Revokes a host's device attestation. The host will be blocked on the next connection attempt when device lock is in enforce mode. Prompts for confirmation.

device-lock status -- Show device lock status
bash
nefia device-lock status

Displays device lock status including enabled state, mode (log or enforce), authority key, trusted count, revoked count, and total hosts.

posture

Check device posture compliance against configured policies.

posture check -- Check posture of target hosts
bash
nefia posture check [--target <selector>]

Evaluates device posture for target hosts. Displays firewall status, disk encryption status, pass/fail result, and any violations. Defaults to all if no target is specified.

posture policy -- Show current posture policy
bash
nefia posture policy

Displays the current posture policy configuration including enabled state, mode, firewall requirement, and disk encryption requirement.

ssh-ca

Manage the SSH Certificate Authority for short-lived certificate-based authentication.

ssh-ca init -- Initialize SSH CA keypair
bash
nefia ssh-ca init

Generates a new Ed25519 SSH CA keypair. The private key is stored in the OS keyring and the public key is saved to the state directory. Also enables ssh_ca.enabled: true, ssh_ca.auto_sign: true, and sets default certificate durations when unset.

ssh-ca sign-user -- Sign operator SSH key with the CA

Alias: ssh-ca sign

bash
nefia ssh-ca sign-user [--duration <duration>] [--principals <list>]
FlagTypeDefaultDescription
--durationstringfrom config or 24hCertificate validity duration
--principalsstringcurrent userComma-separated list of principals

Signs the operator's SSH public key with the CA to produce a short-lived user certificate. The certificate is saved alongside the identity file (e.g., ~/.ssh/id_ed25519-cert.pub).

bash
# Sign with defaults (current user, 24h)
nefia ssh-ca sign-user
 
# Sign with custom duration and principals
nefia ssh-ca sign-user --duration 8h --principals deploy,admin
ssh-ca sign-host -- Sign a host SSH public key
bash
nefia ssh-ca sign-host --host <host-id>

Reads the host SSH public key and signs a host certificate. The output is written under the state directory by default.

ssh-ca trust-known-hosts -- Add managed CA trust entries
bash
nefia ssh-ca trust-known-hosts [--host <host-id>]

Adds managed @cert-authority lines to the operator's known_hosts file so host certificates signed by the SSH CA are accepted.

ssh-ca server-snippet -- Print sshd_config snippet
bash
nefia ssh-ca server-snippet [--host <host-id>] [--os <linux|macos|windows>]

Prints the TrustedUserCAKeys, HostKey, and HostCertificate lines to add to sshd_config, along with the recommended reload command.

ssh-ca status -- Show SSH CA status
bash
nefia ssh-ca status

Displays SSH CA status including initialization state, fingerprint, enabled state, auto-sign setting, cert duration, current user certificate validity, and managed SSH CA trust entries in known_hosts.

mtls

Manage mTLS certificates for the MCP gateway. Uses ECDSA P-256 CA and TLS 1.3.

mtls init -- Initialize mTLS CA and server certificate
bash
nefia mtls init [--hosts <san-list>]
FlagTypeDefaultDescription
--hostsstring[]localhost,127.0.0.1Server certificate SANs (DNS names or IPs)

Generates a new ECDSA P-256 CA keypair and server certificate for the MCP mTLS gateway. The CA and certificates are stored in the state directory. Also enables mTLS in the config with listen_addr: 127.0.0.1:19821.

bash
# Initialize with default SANs
nefia mtls init
 
# Initialize with custom SANs
nefia mtls init --hosts "my-host.local,10.0.0.5"
mtls issue-client -- Issue a client certificate
bash
nefia mtls issue-client --name <cn> [--duration <duration>] [--out-dir <dir>]
FlagTypeDefaultDescription
--namestringClient common name (required)
--durationstring24hCertificate validity duration
--out-dirstringnefia-client-certsOutput directory for certificate files

Issues a client certificate for an MCP agent. Writes the client cert, key, and CA cert to the output directory.

bash
nefia mtls issue-client --name my-agent
nefia mtls issue-client --name ci-bot --duration 168h --out-dir ./certs
mtls status -- Show mTLS CA and certificate status
bash
nefia mtls status

Displays mTLS CA status including CA common name, expiry, server certificate details, SANs, enabled state, and listen address.

secrets

Manage dynamic credential injection for secret references in commands and playbooks.

secrets list -- List configured secret providers
bash
nefia secrets list

Lists all configured secret providers with their name and type (e.g., env, file, vault, aws-sm, op).

secrets test -- Test resolving a secret reference
bash
nefia secrets test <reference> [--reveal]
FlagTypeDefaultDescription
--revealbooleanfalseShow the resolved secret value (use with caution)

Tests resolving a secret reference like ${env:MY_VAR} or ${file:key#field}. By default, the resolved value is masked.

bash
nefia secrets test '${env:DATABASE_URL}'
nefia secrets test --reveal '${env:API_KEY}'

cluster

Manage HA cluster with leader election and state replication via Raft consensus.

In cluster mode, one node is elected as leader and owns the VPN tunnel. State (sessions, queue) is replicated across all nodes. If the leader fails, a standby node is automatically promoted.

cluster init -- Bootstrap a new cluster
bash
nefia cluster init

Bootstraps Raft consensus and makes this node the initial leader of a new cluster. Requires cluster.enabled: true in config with node_id and bind_addr set.

bash
# Config prerequisite:
#   cluster:
#     enabled: true
#     node_id: "node-1"
#     bind_addr: "0.0.0.0:9700"
nefia cluster init
cluster status -- Show cluster status
bash
nefia cluster status

Shows cluster status including node ID, Raft state, leader status, and leader ID. Requires the daemon to be running.

cluster members -- List cluster members
bash
nefia cluster members

Lists all cluster members with their ID, address, Raft state, and whether they are the local node. Requires the daemon to be running.

cluster add-peer -- Add a peer to the cluster
bash
nefia cluster add-peer --id <node-id> --addr <raft-addr>
FlagTypeDefaultDescription
--idstringPeer node ID (required)
--addrstringPeer Raft address, e.g. 10.99.0.2:9700 (required)

Adds a peer to the cluster. Must be run on the leader node. The peer is persisted to the config file. Requires the daemon to be running.

cluster remove-peer -- Remove a peer from the cluster
bash
nefia cluster remove-peer --id <node-id>
FlagTypeDefaultDescription
--idstringPeer node ID to remove (required)

Removes a peer from the cluster. Must be run on the leader node. The peer is also removed from the config file. Requires the daemon to be running.

reactor

View the event-driven automation reactor status and rules.

The reactor runs as part of the daemon (nefia daemon) and receives events from agents via TCP on the VPN interface. Events are matched against rules to trigger automated actions (exec, playbook, alert).

reactor status -- Show configured reactor rules
bash
nefia reactor status

Displays reactor configuration including enabled state, listen port, and configured rules (name, event pattern, host pattern, action type).

bash
nefia reactor status
nefia reactor status --json
reactor events -- Show recent reactor events
bash
nefia reactor events

Display recent events processed by the reactor engine. The reactor must be running as part of the daemon (nefia daemon) for events to be available. Events are kept in memory and show the most recent processing activity.

Displays event time, type, host, severity, matched rule, action taken, and any errors.

bash
nefia reactor events
nefia reactor events --json

access

Manage Just-in-Time (JIT) temporary elevated access requests. Requires jit.enabled: true in config.

access request -- Request temporary elevated access
bash
nefia access request --role <role> --hosts <patterns> [--duration <duration>] [--reason <text>]
FlagTypeDefaultDescription
--rolestringRole to request (required)
--hostsstringHost patterns, comma-separated (required)
--durationstringfrom config or 1hAccess duration (e.g., 1h, 30m)
--reasonstringReason for access request (may be required by policy)

Creates a JIT access request in pending status. Must be approved by an admin. When approved, a time-limited grant allows policy-denied operations for the specified role and host patterns.

bash
nefia access request --role admin --hosts "prod-*" --duration 1h --reason "deploy hotfix"
nefia access request --role admin --hosts "web-01,web-02" --duration 30m --reason "debug"
access list -- List access requests and grants
bash
nefia access list [--status <state>]
FlagTypeDefaultDescription
--statusstringFilter by status: pending, approved, denied, expired, revoked

Lists JIT access requests with ID, status, requester, role, hosts, duration, creation time, and expiry.

bash
nefia access list
nefia access list --status pending
access approve -- Approve a pending access request
bash
nefia access approve <request-id>

Approves a pending JIT access request and creates a time-limited grant. The grant duration was specified when the request was created.

access deny -- Deny a pending access request
bash
nefia access deny <request-id> [--reason <text>]
FlagTypeDefaultDescription
--reasonstringReason for denial

Denies a pending JIT access request.

access revoke -- Revoke an active access grant
bash
nefia access revoke <request-id>

Revokes a previously approved JIT access grant before it expires.

compliance

Generate advisory compliance reports evaluating Nefia's configuration and audit evidence against common security frameworks. Reports are tools to assist compliance efforts and do not constitute a certification or legal guarantee of compliance.

compliance report -- Generate a compliance report
bash
nefia compliance report --framework <framework> [--period <range>] [--format <fmt>] [--out <path>]
FlagTypeDefaultDescription
--frameworkstringCompliance framework: soc2, iso27001, hipaa (required)
--periodstring30dReport period: Nd or YYYY-MM-DD..YYYY-MM-DD
--formatstringtableOutput format: table, json, yaml, html
--outstringOutput file path (required for HTML format)

Evaluates controls for the specified framework against current configuration and audit evidence. Displays compliance score, control statuses (pass, partial, fail, n/a), and a disclaimer.

bash
nefia compliance report --framework soc2
nefia compliance report --framework iso27001 --period 30d
nefia compliance report --framework hipaa --period 2026-01-01..2026-03-10
nefia compliance report --framework soc2 --format html --out report.html

verify

Verify binary or SBOM integrity against the signed release manifest.

bash
nefia verify [file] [--self] [--version <version>]
FlagTypeDefaultDescription
--selfbooleanfalseVerify the currently running nefia binary
--versionstringcurrent build versionRelease version to verify against

Downloads the signed release manifest from GitHub and checks the SHA-256 hash of the specified file against the expected value. The manifest itself is verified with the Ed25519 public key embedded at build time.

bash
# Verify a downloaded binary
nefia verify ./nefia-linux-amd64
 
# Verify the currently running binary
nefia verify --self
 
# Verify against a specific version
nefia verify ./nefia-darwin-arm64 --version 1.2.3

Configuration

Complete reference for the nefia.yaml configuration file.

Exit Codes

Reference for CLI exit codes and their meanings.

Remote Execution Guide

Practical guide to executing commands across multiple hosts.