Your vault in the terminal, with guardrails for agentic AI workflows
Use `authsia status` or `authsia status --format json` to check bridge, session, shell, and SSH agent health, or `authsia doctor` to diagnose setup issues.
Back to AuthsiaFresh installs default this setting to off. If a command fails before showing an approval prompt, open Authsia and enable CLI Access first.
# The CLI is bundled with the app automatically.
# Symlink it to your PATH:
ln -sf /Applications/Authsia.app/Contents/Helpers/authsia ~/.local/bin/authsia
# Or add to your PATH in ~/.zshrc:
export PATH="$HOME/.local/bin:$PATH"
# Enable shell integration:
eval "$(authsia init zsh)"
Open Authsia app, go to Settings → Security → Enable CLI Access
Run authsia unlock — enter biometric to start a session
$ authsia unlock
Touch ID prompt will appear in Authsia app...
Session started. Valid for 8 hours.
Run authsia list accounts — verify the connection works
$ authsia list accounts
github GitHub
aws-console Amazon Web Services
ms-365 Microsoft 365
Run authsia code github --copy — your first TOTP code, copied to clipboard
$ authsia code github --copy
482 391 (copied to clipboard, valid for 18s)
See the full workflow guide for Codex, Claude Code, Cursor, Windsurf, Copilot, and headless automation — including project rules, scoped credentials, and per-item access control.
| Workflow | Command |
|---|---|
| Copy TOTP code | authsia code github --copy |
| Get a password | authsia get password "AWS Console" |
| Use SSH keys with Git | git push origin main |
| Adopt existing SSH keys | authsia ssh adopt --path ~/.ssh --dry-run |
| Run with secrets | authsia exec --env-file .env -- npm start |
| Read a secret reference | authsia read "authsia://password/GitHub/password" |
| Scan dotfiles for secrets | authsia scrape --dry-run |
| Start a session | authsia unlock |
| Inject secrets into template | authsia inject < config.template.yaml > config.yaml |
| Check system health | authsia status |
| Diagnose issues | authsia doctor |
| Generate SSH key | authsia ssh generate --name deploy |
| Create automation credential | authsia access create --name ci --scope CI --ttl 2h --allow exec |
All commands require the Authsia app to be running.
| Command | Description |
|---|---|
authsia code <query> |
Generate TOTP code |
authsia get otp <query> |
Get OTP via get subcommand |
authsia list accounts |
List all TOTP accounts (no secrets) |
authsia export accounts |
Export all accounts as JSON |
| Command | Description |
|---|---|
authsia list passwords |
List all passwords (no secrets) |
authsia get password <query> |
Get password fields |
authsia add password |
Create a password item |
authsia edit password <query> |
Update a password |
authsia delete password <query> |
Delete a password |
| Command | Description |
|---|---|
authsia list certs |
List all certificates |
authsia get cert <query> |
Get certificate fields |
authsia add cert |
Add a certificate |
authsia edit cert <query> |
Update a certificate |
authsia delete cert <query> |
Delete a certificate |
| Command | Description |
|---|---|
authsia list notes |
List all notes |
authsia get note <query> |
Get note content |
authsia add note |
Create a note |
authsia edit note <query> |
Update a note |
authsia delete note <query> |
Delete a note |
Built-in SSH agent
When the Authsia app is running it listens on ~/.authsia/agent.sock and serves all vault SSH keys automatically — no authsia load ssh or ssh-add needed for normal Git and SSH. Shell integration (eval "$(authsia init zsh)" or bash) points SSH_AUTH_SOCK at that socket whenever it exists. Each key has a per-key approval policy and optional bound hosts list that the agent enforces at signing time.
authsia unlock)github.com, *.corp.internal, etc.; empty means any host# Lock a key down to GitHub and force a prompt on every use authsia edit ssh deploy --approval always --hosts "github.com" # Clear all host restrictions for a key authsia edit ssh deploy --hosts ""
# Verify the built-in agent and then use Git normally
eval "$(authsia init zsh)"
ssh-add -L
git push origin main
Adopt existing keys
Use authsia ssh adopt when a user already has private keys and ~/.ssh/config. Authsia discovers private-key-looking files even when they use custom names, reads matching .pub files, infers host bindings from IdentityFile entries, imports keys with session-based approval, replaces private key files with Authsia stubs, and reports existing stubs as already managed.
# Preview first; this does not modify files or the vault authsia ssh adopt --path ~/.ssh --dry-run # Apply after reviewing the plan authsia ssh adopt --path ~/.ssh --yes --folder Infra/SSH # New shells use the Authsia agent for Git and SSH eval "$(authsia init zsh)"
| Command | Description |
|---|---|
authsia list ssh |
List all SSH keys (shows type, approval, hosts) |
authsia get ssh <query> |
Get SSH key details |
authsia add ssh |
Add one SSH key; metadata is inferred from the matching .pub file when available |
authsia ssh adopt |
Adopt existing SSH private keys and replace disk keys with Authsia stubs |
authsia edit ssh <query> |
Update SSH key metadata, approval policy, or bound hosts |
authsia delete ssh <query> |
Delete SSH key |
authsia load ssh [<query>] --system-agent --ttl 300 |
Unsafe compatibility path for tools that cannot use SSH_AUTH_SOCK; normal Git and SSH should use the built-in agent |
Git and SSH troubleshooting
If git push waits without output, Authsia may be waiting for signing approval or the app may need to recreate the agent socket. Bring Authsia to the foreground, approve the prompt, then verify the socket directly.
SSH_AUTH_SOCK="$HOME/.authsia/agent.sock" ssh-add -L SSH_AUTH_SOCK="$HOME/.authsia/agent.sock" git ls-remote --heads origin
agent refused operation usually means approval was denied or timed out, the key is not eligible, host binding rejected the host, or signing failed.Permission denied (publickey) means the remote did not accept an offered public key, or the host is outside the key's bound-host list.
Use load to export secrets as shell variables for interactive sessions. Use exec to inject secrets into a single command with automatic output masking. Use env profiles to default repeated work to a folder, then override it with --query, --folder, or --all when you need something more specific. Use read to resolve a secret reference URI directly. For agentic AI and automation, prefer exec plus authsia:// references so plaintext secrets stay out of prompts, checked-in files, and long-lived shells.
Secret Reference URIs
authsia://type/item[/field][?folder=path]
Reference any vault secret by URI. Works as an env var value, inside .env files, or directly with authsia read. All references are resolved via biometric approval — the URI itself contains no secret data.
| Command | Description |
|---|---|
authsia load <type> [<query>] |
Export secrets as shell variables |
authsia exec [--type <type>] |
Run command with secrets injected & masked |
authsia read <uri> |
Resolve a secret reference URI |
authsia integration show <tool> |
Show Authsia-native setup guidance for common CLIs and SDKs |
.env filesStore authsia:// references instead of plaintext secrets. Safe to commit — the file contains no secret data, which makes this pattern a much better fit for agent-generated scripts and shared repo automation.
# .env — safe to commit DB_HOST=localhost DB_PASS=authsia://password/Prod-DB/password API_KEY=authsia://password/GitHub/password TLS_KEY=authsia://cert/TLS/privateKey
# All references resolved before launch; secrets masked in output
authsia exec --env-file .env -- make deploy
# Default repeated work to a reusable environment profile
authsia env add --name Production --folder Team/API
authsia env use Production
authsia load password --env Production
authsia exec --type password --env Production -- npm start
# Scoped automation for a trusted local agent or editor workflow authsia access create --name claude-code --scope Team/API --ttl 15m --allow exec,ssh export AUTHSIA_ACCESS_CREDENTIAL=8D6A3B75-61A4-4F8A-9D67-11A8E4AA4D48 GITHUB_TOKEN=authsia://password/GitHub/password authsia exec --env-file .env -- gh auth status authsia exec -- git push
# Built-in integration guidance, SSH aliases, and repo-local Git signing authsia integration show gh authsia ssh adopt --path ~/.ssh --dry-run authsia ssh adopt --path ~/.ssh --yes --folder Infra/SSH authsia ssh generate --name github-work authsia ssh generate --name corp-key --type rsa --bits 4096 authsia ssh config --host github.com --alias github-work --user git --key github-work authsia ssh git-signing --principal dev@example.com --public-key ~/.ssh/github-work.pub # Tighten a high-value key: prompt every use, only for GitHub authsia edit ssh github-work --approval always --hosts "github.com"
load vs exec — Which to Useload |
exec |
|
|---|---|---|
| Where secrets live | Parent shell (persists until unset) |
Target process only |
| Stdout exposure | Emits export KEY='value' |
No stdout; secrets masked in subprocess output |
.env file support |
— | --env-file .env |
| Best for | Interactive sessions, multiple commands | CI/CD, single commands, security-sensitive |
| Command | Description |
|---|---|
authsia scrape |
Scan and migrate hardcoded secrets; auto-rewrites .env files with authsia:// references; skips SSH keys with adoption guidance |
authsia scrape --revert <path> |
Revert a modified file |
authsia scrape --revert-all |
Revert all files |
authsia scrape --list-modified |
List files modified by scrape |
By default, scrape scans project .env files, shell startup files such as ~/.zshrc and ~/.bashrc, and ~/.kube/config. It does not scan ~/.ssh by default, and even explicit SSH key detections are skipped; use authsia ssh adopt so Authsia can preserve key metadata and host bindings.
.env files are auto-rewritten
When scrape finds secrets in a .env file, it replaces each secret line with an authsia:// reference — safe to commit. A diff preview is shown before any changes are applied. The original file is backed up in your vault (one backup per file; re-running updates the backup).
# Before API_KEY=sk-prod-abc123 # After (safe to commit) # Migrated to Authsia - Original: API_KEY API_KEY=authsia://password/API_KEY/password
# Run your app with secrets resolved at launch:
authsia exec --env-file .env -- npm start
SSH key migration is explicit
To migrate SSH keys, use authsia ssh adopt instead of the generic secret scanner. Scrape skips SSH private keys and prints adoption guidance; adopt reads matching .pub files, maps IdentityFile entries from SSH config to bound hosts, imports each private key into the vault, then replaces private key files with Authsia-managed stubs.
# SSH keys are skipped by scrape; adopt handles them authsia ssh adopt --path ~/.ssh --dry-run authsia ssh adopt --path ~/.ssh --yes --folder Infra/SSH # Verify the Authsia agent path after adoption eval "$(authsia init zsh)" ssh-add -L
| Command | Description |
|---|---|
authsia unlock |
Biometric auth once; establishes session for subsequent commands |
authsia access create --name Claude --scope Team/API --ttl 15m --allow exec,ssh |
Create a scoped, TTL-bound automation credential for trusted local agents, editor tooling, and Git over SSH |
authsia access list --format table |
Review active automation credentials and their scopes, expiry, and machine binding |
authsia access revoke <id> |
Revoke an automation credential without deleting the audit trail of its creation |
authsia init zsh |
Install shell integration (required for --silent); also routes SSH_AUTH_SOCK to Authsia's built-in SSH agent when ~/.authsia/agent.sock exists. Use authsia init bash for bash. |
authsia audit verify |
Validate integrity of the audit log chain |
authsia audit list |
Review recent audit events locally with filtering and JSON output |
authsia audit export --out-file audit.json |
Export audit records for investigations, reviews, or external retention |
authsia env add --name Production --folder Team/API |
Create a reusable environment profile that maps an app or stage to a vault folder path |
authsia env list --format table |
Inspect saved environment profiles and see which one is currently active on this machine |
authsia env use Production |
Set the active environment so load and exec can resolve folder scope without repeating flags |
authsia integration list |
See built-in setup recipes for gh, aws, docker, vercel, and openai |
authsia ssh adopt --path ~/.ssh --dry-run |
Preview adoption of existing private keys, matching public keys, and host bindings before changing files |
authsia ssh generate --name github-work |
Generate an ed25519 keypair, store the private key in the vault, and leave a public key plus Authsia-managed stub on disk |
authsia ssh config --host github.com --alias github-work --user git --key github-work |
Write a friendlier SSH alias with HostName, optional User, and Authsia agent guidance |
authsia ssh git-signing --principal dev@example.com --public-key ~/.ssh/github-work.pub |
Enable repo-local Git SSH commit and tag signing, and create a local allowed_signers file for verification |
| Command | Description |
|---|---|
authsia access create |
Create a scoped automation credential |
authsia access list |
List automation credentials |
authsia access revoke <id> |
Revoke a credential |
authsia env add |
Add an environment profile |
authsia env list |
List profiles |
authsia env use <name> |
Set active profile |
| Command | Description |
|---|---|
authsia ssh adopt |
Adopt existing SSH private keys into Authsia, infer host bindings, and replace disk keys with Authsia-managed stubs. |
authsia ssh generate |
Generate an ed25519 (default) or RSA keypair, store the private key in the vault, and leave a public key plus Authsia-managed private-key stub on disk. |
authsia ssh config |
Add/update an SSH config host entry that uses the Authsia agent socket |
authsia ssh git-signing |
Configure repo-local Git SSH signing |
| Command | Description |
|---|---|
authsia status |
Show bridge, session, shell, and SSH agent status |
authsia doctor |
Diagnose common setup issues |
authsia audit list |
List audit events |
authsia audit export |
Export audit log |
| Command | Description |
|---|---|
authsia integration list |
List supported tool integrations |
authsia integration show <id> |
Show setup guide for a tool |
authsia completion <shell> |
Generate shell completions (zsh/bash/fish) |
How to use Authsia CLI with AI coding agents so secrets stay out of prompts, generated code, and normal masked terminal output.
AI coding agents observe everything in your terminal session: environment variables, command output, file contents, and shell history. Any plaintext secret that appears in any of these surfaces is captured by the agent's context window and may be sent to a remote API.
Common leaks in agent sessions
export API_KEY=sk-prod-abc... — visible to any tool reading envcurl -H "Authorization: Bearer sk-..." — in shell history and agent context.env with real secrets — committed to repo, visible in diffecho $DB_PASSWORD for debugging — plaintext in terminal output
Use authsia:// URIs everywhere a secret would go. These references contain no secret data — they're safe to display, commit, and share with agents. Secrets are only resolved at the final approved authsia exec launch.
Agent writes references
authsia://password/API/password
You approve once
Touch ID / session unlock
Exec resolves & masks
<concealed by authsia>
# .env — agent can read/write this freely, no secrets DB_HOST=localhost DB_PASS=authsia://password/Prod-DB/password API_KEY=authsia://password/GitHub/password # Resolve all references at launch; mask secrets in output $ authsia exec --env-file .env -- npm start > Server listening on :3000 > Connected to DB with password <concealed by authsia>
In the intended exec flow, the agent sees the reference URIs and masked text output, not the plaintext secret values.
Security boundary
authsia exec keeps secrets out of the assistant's observed context; it does not make the launched program unable to read secrets it was given. Use trusted commands, keep masking enabled, and avoid --no-masking in agent sessions. Grant automation credentials only exec, plus ssh when Git or SSH signing is required; do not grant load, read, get, or inject to AI agents because those commands intentionally emit plaintext.
Add rules to your project so the agent uses authsia:// references by default and never inlines plaintext secrets.
AGENTS.md## Secret Management - Never inline plaintext secrets in code, env files, shell commands, logs, or final answers. - Use authsia:// reference URIs for secret values: - authsia://password/<name>/password - authsia://cert/<name>/privateKey - authsia://note/<name>/content - Run commands that need secrets through: - authsia exec --env-file .env -- <command> - For background runs, use scoped credentials with --allow exec, plus ssh only when Git/SSH signing is required. - Keep masking enabled. Never use --no-masking in agentic sessions. - Do not use authsia get/load/read/inject to expose plaintext secrets to the agent context. - List non-secret item names with: authsia list passwords --format table
CLAUDE.md# Secret Management # - NEVER inline plaintext secrets in code, env files, or shell commands. # - Use authsia:// reference URIs for all secret values: # authsia://password/<name>/password # authsia://cert/<name>/privateKey # authsia://note/<name>/content # - Run commands that need secrets via: # authsia exec --env-file .env -- <command> # - Only run trusted commands under authsia exec; that child process receives the secret. # - Keep masking enabled. Never use --no-masking in agent sessions. # - Grant automation credentials only exec, plus ssh when Git/SSH signing is needed. # - NEVER grant load, read, get, or inject to AI agents. # - NEVER run: export SECRET=..., echo $SECRET, or cat credentials. # - Available secrets: authsia list passwords --format table
.cursor/rules# Secret Management # Never inline plaintext secrets. Use authsia:// URIs: # authsia://password/<name>/password # Run: authsia exec --env-file .env -- <command> # Keep masking enabled. Do not grant load/read/get/inject to agents. # List: authsia list passwords --format table
.windsurfrules / GitHub Copilot .github/copilot-instructions.md# Secret Management # Never hardcode secrets. Reference them via authsia:// URIs. # Pattern: authsia://password/<name>/password # Execute trusted commands with masking: authsia exec --env-file .env -- <command> # Do not grant load/read/get/inject to AI agents.
Already have plaintext secrets in your project?
Run authsia scrape --path .env --dry-run to scan for secrets and preview what would be migrated. Add --replace-all to auto-rewrite files with authsia:// references.
For background agents, CI runners, or editor integrations that need secrets without interactive biometric approval, create a scoped automation credential. Each credential is folder-bound, TTL-limited, revocable, and grants only the capabilities listed in --allow.
# Create a 15-minute credential scoped to the Team/API folder $ authsia access create --name claude-code --scope Team/API --ttl 15m --allow exec,ssh Created credential 8D6A3B75-... (expires in 15m, scope: Team/API, allow: exec,ssh) # Set the env var so Authsia CLI and SSH agent can validate this session $ export AUTHSIA_ACCESS_CREDENTIAL=8D6A3B75-... # Agent can now resolve secrets within scope — no biometric prompt $ authsia exec --env-file .env -- npm test # Agent can also use scoped SSH keys for Git $ authsia exec -- git push # Review active credentials $ authsia access list --format table # Revoke early if no longer needed $ authsia access revoke 8D6A3B75-...
A normal CLI unlock does not automatically approve SSH signing. The built-in Authsia SSH agent checks for an active local credential with the ssh capability, a matching folder scope, a CLI-enabled SSH key, and any configured host binding before it signs. Without an automation credential, session-based SSH approval prompts through the app and caches per key for the same configured CLI session TTL.
| Guardrail | How it protects you |
|---|---|
--allow |
Only listed capabilities are granted; add ssh only when the agent needs Git or SSH signing |
--scope |
Agent can only read items inside the specified folder — everything else is invisible |
--ttl |
Credential auto-expires after the window closes — no stale tokens |
| SSH marker only | authsia exec strips AUTHSIA_ACCESS_CREDENTIAL from children and forwards only AUTHSIA_SSH_ACCESS_CREDENTIAL when ssh is allowed |
| SSH scope checks | Signing requires a CLI-enabled SSH key inside scope and a matching bound host when host bindings are configured |
| Local only | Credential is bound to this machine — cannot be exfiltrated and used elsewhere |
| Audit logged | Every create, use, and revoke is recorded in the tamper-evident audit log |
Recommended patterns for popular AI coding tools. All follow the same principle: references in, trusted exec at the boundary.
| Tool | Rules file |
|---|---|
| Codex | AGENTS.md |
| Claude Code | CLAUDE.md |
| Cursor | .cursor/rules |
| Windsurf | .windsurfrules |
| GitHub Copilot | .github/copilot-instructions.md |
| GitHub Actions | .github/workflows/*.yml |
| Any terminal agent | — |
Per-item CLI access control
Every vault item has an individual CLI toggle in the Authsia app. Disable it for anything an agent should never be allowed to resolve — even with a valid automation credential, the CLI will refuse to return that item.
The Authsia Chrome extension brings your vault to the browser. When you focus on a login field, Authsia shows matching credentials from your vault in an inline menu. No cloud, no servers — all local.
Note: Passwords must have a Website URL and CLI Access enabled to appear in browser autofill.