Working with secrets
Create, list, read, and inject secrets - including the commands that never print a value to your terminal.
Listing
shortspan secret list
shortspan secret list --group api-productionShows keys, templates, groups, and when each was last updated. It never shows values, and it needs only secrets:read - listing what exists is a different question from reading what it is.
Non-sensitive template fields are shown too. A database_url secret lists its host and port without decrypting anything, because those fields are stored as metadata alongside the ciphertext rather than inside it.
Creating and updating
# Prompts for the value without echoing it
shortspan secret set STRIPE_SECRET_KEY --template plain
# Non-interactive
shortspan secret set STRIPE_SECRET_KEY --template plain --value sk_live_xxx
# From a file - the right way to store a certificate or a key
shortspan secret set TLS_KEY --template plain --file ./server.key
# Into a group
shortspan secret set DATABASE_URL --template env --group api-productionMulti-field templates
Templates like tls_certificate have several fields. Supply each with a repeated --field:
shortspan secret set edge-cert \
--template tls_certificate \
--field certificate="$(cat fullchain.pem)" \
--field private_key="$(cat privkey.pem)"shortspan secret templates lists every template and its fields; Secret templates documents them in full.
Versions
Setting an existing key creates a new version rather than overwriting. On Pro and above the history is readable in the console and any previous version can be restored. Rolling back creates a new version whose value equals the old one - history is append-only, so a rollback is itself recorded.
Using a secret
Two ways out, and they are not equivalent.
Injection (preferred)
shortspan secret run DATABASE_URL -- ./migrate.shThe value is placed in the child process's environment under its own key and never rendered. Nothing reaches your terminal, your scrollback, your shell history, or a CI log. Needs secrets:read.
Reveal
shortspan secret get STRIPE_SECRET_KEYPrints the plaintext to stdout. Needs secrets:reveal, which is not in the default token's abilities, is rate limited separately at 60 a minute, and is recorded as a reveal in the audit log rather than as an ordinary read.
Groups
An application needs a set of variables, not one. A group names that set.
shortspan secret group create api-production \
--environment production \
--description "Runtime configuration for the production API"
shortspan secret group list
shortspan secret group show api-production
shortspan secret group update api-production --name api-prod
shortspan secret group delete api-production --force--environment takes production, staging, development, or custom. Deleting a group leaves its secrets in place and ungrouped - the group is a label, not a container, and deleting a label should never delete the things it was on.
Running a process with a whole group
shortspan run api-production -- npm start
shortspan run api-production --env NODE_ENV=production -- npm startEvery secret in the group is injected under its own key. --env adds extra variables that are not stored as secrets - a flag or a feature toggle that does not deserve encryption.
Deleting
Deletion is an admin action and is done in the console. It is deliberately not a CLI command: deleting a secret is irreversible, breaks whatever was consuming it, and is not something anyone should be one typo away from.
Rotating is almost always what was actually wanted. Set a new value, let the new version propagate, then revoke the old credential at its source.
Something here wrong or missing? Tell us.