CLI Reference: Secrets
Commands for managing the Sealed Credential Store.
Secrets are sensitive values (API keys, tokens, passwords) encrypted with AES-256-GCM and stored in a SQLite database. At runtime, decrypted values live exclusively in agentd's heap memory as Zeroizing<String>; they are never included in IPC responses, never written to observation logs, and never appear in audit entries (only [REDACTED:<name>] placeholders are recorded).
See Secrets Overview for background on the full architecture.
ash secrets unlock
Unlock the encrypted store. On first run (no KDF params exist yet), this initialises the store with the supplied passphrase. On subsequent runs, it derives the master key from the stored salt, decrypts all blobs, and loads them into the runtime store.
ash secrets unlock
The passphrase is read via an echo-disabled prompt.
First run:
Enter master passphrase: [hidden]
Secret store initialised and unlocked.
Subsequent starts:
Enter master passphrase: [hidden]
Secret store unlocked. 3 secret(s) loaded.
Until
unlocksucceeds, all{{secret:<name>}}handle substitutions returnStoreLocked.
ash secrets lock
Immediately zeroize all in-memory plaintext. Subsequent secret resolutions return StoreLocked until ash secrets unlock is called again.
ash secrets lock
The encrypted database is not modified. Use this before stepping away from a running daemon or handing off a session.
ash secrets rekey
Rotate the master key. All encrypted blobs are re-encrypted in a single atomic SQLite transaction. The old passphrase is verified before any changes are made.
ash secrets rekey
Prompts (all echo-disabled):
Enter current passphrase: [hidden]
Enter new passphrase: [hidden]
Confirm new passphrase: [hidden]
Master key rotated. All secrets re-encrypted.
The daemon remains fully operational throughout. After rekey completes, the in-memory store is refreshed under the new key.
ash secrets add
Register a new secret in agentd's sealed store.
ash secrets add <name> [--description <text>]
| Argument/Flag | Description |
|---|---|
name | Logical name used in {{secret:<name>}} handles |
--description | Optional human-readable description |
The secret value is read via an echo-disabled (hidden) prompt. If the store is currently unlocked, the value is also encrypted and persisted to SQLite immediately.
Example:
ash secrets add openai-api-key --description "OpenAI production API key"
# Prompts: Enter secret value: [hidden]
ash secrets list
List all registered secret names. Values are never shown.
ash secrets list
Output: name, description (if set), and registered-at timestamp.
NAME DESCRIPTION REGISTERED AT
openai-api-key OpenAI production API key 2026-01-15T10:00:00Z
db-password Production database password 2026-01-10T08:00:00Z
ash secrets remove
Remove a registered secret.
ash secrets remove <name>
The plaintext is zeroized from heap memory and the encrypted blob is deleted from the SQLite store. Any agent that subsequently tries to resolve {{secret:<name>}} will receive a SecretNotFound error.
ash secrets grant
Grant a specific agent delegation access to a named secret. The agent will be able to use the secret in tool calls even if it does not have a standing secret.use:<name> capability, subject to existing pre-approval policies.
ash secrets grant <name> --to-agent <agent-id> [--ttl <seconds>]
| Argument/Flag | Description |
|---|---|
name | Name of the secret to delegate |
--to-agent | UUID of the agent receiving the grant |
--ttl | Optional TTL in seconds. If omitted, the grant is valid until explicitly revoked or the daemon restarts. |
Example:
ash secrets grant openai-api-key --to-agent f47ac10b-58cc-4372-a567-0e02b2c3d479 --ttl 3600
# Grant ID: 9b1deb4d-...
# Secret 'openai-api-key' delegated to agent f47ac10b-... (expires in 3600s)
Grants are ephemeral: they live only in daemon memory and do not survive a restart. Re-grant after
ash secrets unlockif needed.
ash secrets revoke
Revoke a previously issued delegation grant.
ash secrets revoke <grant-id>
The grant is removed immediately. The target agent can no longer use the delegated secret.
Example:
ash secrets revoke 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
# Grant 9b1deb4d-... revoked.
ash secrets policy add
Add a runtime pre-approval policy for automated secret resolution.
ash secrets policy add \
--label <text> \
[--secret <glob>] \
[--tool <glob>] \
[--host <glob>] \
[--expires <rfc3339>] \
[--max-uses <n>] \
[--trust-level <level>]
| Flag | Default | Description |
|---|---|---|
--label | - | Human-readable name for this policy (required) |
--secret | * | Glob matching secret names |
--tool | * | Glob matching tool names |
--host | (any) | Optional glob matching destination host |
--expires | (never) | RFC3339 expiry timestamp |
--max-uses | (unlimited) | Maximum auto-approvals before policy is exhausted |
--trust-level | (any) | Minimum trust level floor (untrusted/sandboxed/trusted/privileged) |
Policies are persisted to SQLite and survive daemon restarts.
Examples:
# Unlimited access for any agent using openai-key via web.fetch to api.openai.com
ash secrets policy add \
--label "OpenAI standard access" \
--secret "openai-api-key" \
--tool "web.fetch" \
--host "api.openai.com"
# Time-limited policy expiring at end of day
ash secrets policy add \
--label "Nightly batch" \
--secret "db-password" \
--tool "sandbox.exec" \
--expires "2026-01-16T06:00:00Z"
ash secrets policy list
List all registered pre-approval policies.
ash secrets policy list
Output: policy ID, label, secret pattern, tool pattern, host pattern, expiry, use count.
ash secrets policy show
Print full details for a single policy, including the current use count.
ash secrets policy show <policy-id>
Example:
ash secrets policy show a1b2c3d4-e5f6-7890-abcd-ef1234567890
# ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
# Label: OpenAI standard access
# Secret: openai-api-key
# Tool: web.fetch
# Host: api.openai.com
# Expires: never
# Max uses: unlimited
# Use count: 42
# Created by: operator
# Created at: 2026-01-15T10:00:00Z
ash secrets policy remove
Remove a pre-approval policy by UUID.
ash secrets policy remove <policy-id>
Immediately revokes the policy. Subsequent secret resolutions that would have matched this policy are denied.