Daily use
The CLI works mostly from local state. fd0 sync is the explicit network command; the agent can also sync after unlock when on_unlock = true.
One grammar for every module
Six modules hold items: secret, pass, ssh, key, kube, and talos. They take the same verbs, so learning one teaches the rest.
$ fd0 <module> add <name> ... # create; refuses an existing name $ fd0 <module> edit <name> --flag value # change only the fields you name $ fd0 <module> show <name> # human-readable, secrets masked $ fd0 <module> list # alias: ls $ fd0 <module> rename <name> <new-name> $ fd0 <module> move <name> --to-scope <scope> $ fd0 <module> rm <name> # tombstone $ fd0 <module> history show <name> # versions, newest first $ fd0 <module> history restore <name> <seq>
list takes --json on every module, with the same key names throughout and [] rather than null when empty. Secret material is never in that output — fd0 key list --json carries the fingerprint and the authorized_keys line, never the private half.
edit patches; add --force replaces. An edit leaves every field you did not name alone, and passing an empty value clears exactly that one field. A forced add rewrites the whole record, so anything the command did not carry returns to its default. An edit that changes nothing writes nothing and does not burn a revision.
Restore writes forward. history restore appends a new version carrying the old content instead of rewinding the chain, so the history stays append-only and the undo is itself auditable.
Module-specific commands sit alongside the shared verbs, not instead of them: pass field/notes/totp/file, ssh connect/tag/enable, kube sync, talos secrets.
Plain secrets
A plain secret is a name and a value. Everything richer belongs to one of the other modules.
Store a string secret in a scope. Use - as the value to read it from stdin. Without --scope, fd0 uses the only live scope, asks interactively, or requires --scope in non-interactive use.
Print a secret. Without a name, fd0 opens the interactive picker. --raw drops the trailing newline.
Copy a secret to the clipboard and clear it after the timeout.
List plain secret names across scopes. --all also lists records owned by other modules — hosts, keys, pass items, clusters. Values stay encrypted until you request one.
Write a tombstone for a secret. The old event remains audit history.
Each module owns its own records, and the secret commands say so rather than acting on someone else's:
$ fd0 secret rm host:prod ✗ "host:prod" is a host, not a plain secret use: fd0 ssh rm prod
Item history
Every module keeps earlier versions of its items. The listing gives you the sequence numbers restore takes.
$ fd0 secret history show DEPLOY_KEY $ fd0 secret history restore DEPLOY_KEY 4 $ fd0 ssh history show prod-db --json
Scopes and sharing
A scope is the sharing boundary. Add a member to share every current secret in the scope. Remove a member to rotate the scope key for future writes.
# Alice exports her card. $ fd0 card export # Bob imports Alice, Alice imports Bob, then Alice grants access. $ fd0 card import "fd0://card/..." --label bob $ fd0 scope add-member bob --scope work $ fd0 sync # Bob discovers the scope on his next sync. $ fd0 sync $ fd0 secret list
Print your signed card and safety number. Share the card over any channel; verify the safety number over a trusted channel.
Pin another identity under a local label.
Grant a pinned card access to the scope.
Remove access and rotate the scope key.
Unlock methods
Auth methods are stored in the vault. The default unlock method is a local device preference in ~/.fd0/config.toml; it is not synced to other machines. When several methods are available and no default or --method override is set, an interactive unlock asks which method to use.
List enrolled unlock methods. The current session is marked with *, and the local default is marked with default.
Show the default unlock method for this device.
Use YubiKey unlock by default on this device. Use passphrase or a method_id instead when needed.
Clear the local default. Interactive unlocks ask which enrolled method to use; non-interactive commands retain a deterministic fallback.
Local health
Show whether the agent is running and whether the vault is unlocked.
Replay local chains, check vault tips, auth wraps, scope keys, YubiKey flavor state, orphan chain files, and SSH socket health.
Lock the vault in the running agent and zeroize in-memory keys.
Show fd0-agent process, vault, agent socket, and SSH socket state.
Replace fd0-agent with the current binary and repair stale agent sockets.
Stop fd0-agent and clean stale sockets when safe.