Secrets
Fleet uses age encryption for secrets at rest. Each app’s secrets are stored as .age files in the vault/ directory. On boot, fleet-unseal.service decrypts them to /run/fleet-secrets/ (tmpfs — never touches persistent disk).
fleet secrets init
Initialise the secrets vault. Generates an age keypair at /etc/fleet/age.key, writes the public key to the manifest, and installs fleet-unseal.service.
Usage
fleet secrets initExamples
$ fleet secrets init✓ Vault initialised Public key: age1...✓ Installed fleet-unseal.servicefleet secrets list
Show managed secrets for one or all apps. Values are masked.
Usage
fleet secrets list [app] [--json]Arguments
| Argument | Required | Description |
|---|---|---|
app | No | App name. Omit to list all apps. |
Examples
$ fleet secrets list myappSecrets: myapp (3)
KEY VALUEDATABASE_URL ****...API_KEY ****...SECRET_TOKEN ****...Related
- MCP tool:
fleet_secrets_list
fleet secrets get
Print a single decrypted secret value to stdout.
Usage
fleet secrets get <app> <KEY>Arguments
| Argument | Required | Description |
|---|---|---|
app | Yes | App name |
KEY | Yes | Secret key name |
Examples
$ fleet secrets get myapp DATABASE_URLpostgres://user:pass@localhost/dbRelated
- MCP tool:
fleet_secrets_get
fleet secrets import
Import a .env file or a directory of secret files into the vault.
Usage
fleet secrets import <app> [path]Arguments
| Argument | Required | Description |
|---|---|---|
app | Yes | App name |
path | No | Path to .env file or secrets directory. Defaults to <composePath>/.env. |
Examples
$ fleet secrets import myapp✓ Imported 5 keys from /srv/myapp/.env$ fleet secrets import myapp /srv/myapp/.env.production✓ Imported 5 keys from /srv/myapp/.env.productionfleet secrets export
Print the full decrypted .env for an app to stdout.
Usage
fleet secrets export <app>Arguments
| Argument | Required | Description |
|---|---|---|
app | Yes | App name |
Examples
$ fleet secrets export myappDATABASE_URL=postgres://...API_KEY=sk-...SECRET_TOKEN=...fleet secrets seal
Re-encrypt the current runtime secrets (/run/fleet-secrets/) back to the vault. Backups are created automatically before any seal operation.
fleet secrets seal-runtime is an accepted alias for this command.
Usage
fleet secrets seal [app]Arguments
| Argument | Required | Description |
|---|---|---|
app | No | App name. Omit to seal all apps. |
Examples
$ fleet secrets seal myapp✓ Sealed myapp$ fleet secrets seal✓ Sealed myapp✓ Sealed api✓ Sealed workerRelated
- MCP tool:
fleet_secrets_seal
fleet secrets unseal
Decrypt all vault files to /run/fleet-secrets/. This is run automatically on boot by fleet-unseal.service.
Usage
fleet secrets unsealExamples
$ fleet secrets unseal✓ Unsealed 3 apps to /run/fleet-secrets/Related
- MCP tool:
fleet_secrets_unseal
fleet secrets validate
Check that all secret references in docker-compose.yml files have matching entries in the vault.
Usage
fleet secrets validate [app] [--json]Arguments
| Argument | Required | Description |
|---|---|---|
app | No | App name. Omit to validate all apps. |
Examples
$ fleet secrets validate myappSecrets Validation ok myapp✓ All secrets validated$ fleet secrets validateSecrets Validation✗ myapp: missing from vault: NEW_API_KEY api: extra in vault (not in compose): OLD_KEY✗ 1 app(s) have missing secretsRelated
- MCP tool:
fleet_secrets_validate
fleet secrets drift
Detect differences between the encrypted vault (persists across reboots) and the runtime at /run/fleet-secrets/ (lost on reboot).
Usage
fleet secrets drift [app] [--json]Arguments
| Argument | Required | Description |
|---|---|---|
app | No | App name. Omit to check all apps. |
Examples
$ fleet secrets driftVault / Runtime Drift in-sync myapp✗ api: drifted added at runtime: NEW_KEY changed at runtime: API_SECRET! Run "fleet secrets seal" to persist runtime changes to vault! Run "fleet secrets unseal" to revert runtime to vault stateRelated
- MCP tool:
fleet_secrets_drift
fleet secrets restore
Restore the vault for an app from its automatically-created backup (.bak file).
Usage
fleet secrets restore <app>Arguments
| Argument | Required | Description |
|---|---|---|
app | Yes | App name |
Examples
$ fleet secrets restore myapp✓ Restored vault backup for myapp Run "fleet secrets unseal" to apply to runtimeRelated
- MCP tool:
fleet_secrets_restore
fleet secrets status
Show overall vault state: initialisation status, sealed/unsealed, key path, app count, and total key count.
Usage
fleet secrets status [--json]Examples
$ fleet secrets statusSecrets Status Vault: initialised State: unsealed Key: /etc/fleet/age.key Vault: /path/to/vault Runtime: /run/fleet-secrets/ Apps: 3 | Keys: 12Related
- MCP tool:
fleet_secrets_status
fleet secrets set
Set a single secret value for an app. Interactive paste is the default — the secret value is never accepted as a positional argv argument because process arguments are world-readable via /proc/<pid>/cmdline and land in shell history.
Usage
fleet secrets set <app> <KEY> # interactive (recommended)printf '%s' "$NEW_VALUE" | fleet secrets set <app> <KEY> --from-stdinFlags
| Flag | Description |
|---|---|
--from-stdin | Read the value from stdin (terminating newline stripped). |
--allow-weak | Skip the entropy / placeholder check (rejects of changeme, password, etc.). |
Why no <VALUE> positional?
The legacy fleet secrets set <app> <KEY> <VALUE> form is rejected since fleet v1.6: argv leaks the value via /proc/<pid>/cmdline, ps, shell history, atop accounting, and similar. Use the interactive prompt or --from-stdin.
fleet secrets ages
Show every managed secret with its age, provider classification, rotation frequency, sensitivity, and freshness status. Read-only.
Usage
fleet secrets ages [<app>] [--json] [--stale-only] [--motd]Status legend
fresh— under 80% of the provider’srotationFrequencyDaysaging— between 80% and 100% of the frequencySTALE— at or past the frequency, time to rotateunknown— secret name didn’t match any known provider
Examples
$ fleet secrets ages --stale-onlySecret ages (4 secrets) APP SECRET AGE ROTATE EVERY PROVIDER SENS STATUS poolside STRIPE_SECRET_KEY 200 days 90d Stripe Secret Key critical STALE ...
$ fleet secrets ages --motd-- Fleet Secrets ---------------------------------------- 4 secrets need rotation (1 critical, 3 high) across 2 apps !! poolside: STRIPE_SECRET_KEY (200d old) ...fleet secrets motd-init
Install /etc/update-motd.d/99-fleet-secrets so the next shell login summarises stale-secret status alongside fleet deps.
Usage
sudo fleet secrets motd-initfleet secrets rotate
Interactive walkthrough that rotates one or every secret in an app. Safety rails are mandatory — pre-rotation snapshot, hidden input, format validation, entropy check, masked confirmation, atomic restore on failure, post-rotation health gate.
Usage
fleet secrets rotate <app> # walk every secretfleet secrets rotate <app> <KEY> # one specific secretfleet secrets rotate <app> <KEY> --dry-run # show what would happenfleet secrets rotate <app> <KEY> --no-restart # skip auto-restartfleet secrets rotate <app> ENCRYPTION_KEY --data-migrated # at-rest-key strategyRotation strategies
The provider registry classifies each secret name and picks one of:
| Strategy | Examples | Behaviour |
|---|---|---|
immediate | STRIPE_SECRET_KEY, GITHUB_TOKEN, OPENAI_API_KEY, BOOKWHEN_API_TOKEN | Drop-in replace. Old dies. Safe for upstream API keys. |
dual-mode | JWT_SECRET, NEXTAUTH_SECRET, AUTH_SECRET, SESSION_SECRET, CSRF_SECRET | New value becomes primary; old saved as <NAME>_PREVIOUS. App must read both for verification so existing user sessions stay valid through the grace period. |
at-rest-key | ENCRYPTION_KEY, FIELD_ENCRYPTION_KEY | Refused unless --data-migrated is passed. Rotating without re-encrypting stored data first will brick reads. |
user-issued | USER_API_TOKEN, CUSTOMER_API_KEYS | Refused entirely. Rotate per-user inside your app. |
Audit + rollback
Every rotation creates a snapshot at vault/.snapshots/<app>-<ts>.env.age before any change. If reseal fails, the snapshot is automatically restored. An audit entry is appended to /var/log/fleet/secrets-audit.jsonl (file mode 0600 in a root-owned 0700 directory, never logs the value — only the secret name, the operation, and the trusted login uid). Override the directory with FLEET_AUDIT_DIR. History from the pre-v1.14.0 location (~/.local/share/fleet/audit.jsonl) is not migrated.
To restore manually:
fleet secrets snapshots <app> # list snapshots, newest firstfleet secrets rollback <app> # restore the newestfleet secrets rollback <app> --to <TIMESTAMP>The rollback itself takes a pre-rollback safety snapshot — the rollback is reversible.
fleet secrets snapshots
List all snapshots for an app, newest first. Snapshots are created automatically before every rotation, seal, or rollback operation.
Usage
fleet secrets snapshots <app> [--json]Arguments
| Argument | Required | Description |
|---|---|---|
app | Yes | App name |
Examples
$ fleet secrets snapshots myappSnapshots for myapp (3)
TIMESTAMP SIZE PATH2026-06-22T14:30:00Z 1.2K .snapshots/myapp-2026-06-22T14:30:00Z.env.age2026-06-21T09:00:00Z 1.1K .snapshots/myapp-2026-06-21T09:00:00Z.env.age2026-06-20T18:15:00Z 1.1K .snapshots/myapp-2026-06-20T18:15:00Z.env.age
Restore the newest with: fleet secrets rollback myapp Restore a specific one: fleet secrets rollback myapp --to <TIMESTAMP>fleet secrets rollback
Restore an app’s vault from a snapshot. Takes a pre-rollback safety snapshot first, so the rollback itself is reversible.
Usage
fleet secrets rollback <app> [-y]fleet secrets rollback <app> --to <TIMESTAMP> [-y]Arguments
| Argument | Required | Description |
|---|---|---|
app | Yes | App name |
Flags
| Flag | Description |
|---|---|
--to <TIMESTAMP> | Restore from a specific snapshot timestamp (use fleet secrets snapshots to list). Defaults to the newest snapshot. |
-y, --yes | Skip the confirmation prompt |
Examples
$ fleet secrets rollback myappPre-rollback safety snapshot: myapp-2026-06-22T14:35:00Z.env.age✓ Restored myapp from 2026-06-22T14:30:00ZRe-unsealing vault...✓ Runtime updated$ fleet secrets rollback myapp --to 2026-06-20T18:15:00Z -y✓ Restored myapp from 2026-06-20T18:15:00Zfleet secrets rotate-key
Legacy command that rotates the AGE master key (re-encrypts every vault file with a fresh key). Different concept from fleet secrets rotate — that one rotates application secret values; this one rotates the encryption key the vault uses.
Usage
fleet secrets rotate-key [-y]