Secret Generation
Secrets can be declared with type and generate to be auto-generated when missing. This is useful for passwords, tokens, and keys that do not need to be shared across developers.
Basic Usage
Section titled “Basic Usage”[profiles.default]DB_PASSWORD = { description = "Database password", type = "password", generate = true }API_TOKEN = { description = "API token", type = "hex", generate = { bytes = 32 } }SESSION_KEY = { description = "Session key", type = "base64", generate = { bytes = 64 } }REQUEST_ID = { description = "Request ID prefix", type = "uuid", generate = true }Generation Types
Section titled “Generation Types”| Type | Default Output | Options |
|---|---|---|
password | 32 alphanumeric chars | length (int), charset ("alphanumeric" or "ascii") |
hex | 64 hex chars (32 bytes) | bytes (int) |
base64 | 44 chars (32 bytes) | bytes (int) |
uuid | UUID v4 (36 chars) | none |
command | stdout of command | command (string, required) |
rsa_private_key | 2048-bit RSA private key (PKCS1 PEM) | bits (int) |
openpgp_private_key (0.21+) | ASCII-armored OpenPGP transferable secret key | user_id (required), algorithm ("ed25519" or "rsa"), bits (RSA only), capabilities (["sign"], ["encrypt"], or both) |
ssh_private_key (0.21+) | Unencrypted OpenSSH Ed25519 private key | algorithm ("ed25519" or "rsa"), bits (RSA only), comment (string) |
Command type
Section titled “Command type”The command type runs a shell command and uses its stdout as the generated value:
MONGO_KEY = { description = "MongoDB keyfile", type = "command", generate = { command = "openssl rand -base64 765" } }command requires generate = { command = "..." } rather than just generate = true.
OpenPGP private keys
Section titled “OpenPGP private keys”openpgp_private_key generates a GnuPG-compatible OpenPGP v4 key entirely in
process; neither gpg nor another executable is required. Its modern default
uses an Ed25519 certification-only primary key and puts routine operations on
separate Ed25519 signing and Curve25519 encryption subkeys.
The User ID is required. With no capabilities, SecretSpec creates both
signing and encryption subkeys:
[profiles.default]GENERAL_KEY = { description = "Service OpenPGP key", type = "openpgp_private_key", generate = { user_id = "Service Bot <service@example.com>" } }
# A signing-only key has no encryption subkey.RELEASE_KEY = { description = "Release signing key", type = "openpgp_private_key", generate = { user_id = "Release Bot <releases@example.com>", capabilities = ["sign"] } }
# RSA is available for consumers that require it; 3072 bits is the default.LEGACY_KEY = { description = "Legacy-compatible OpenPGP key", type = "openpgp_private_key", generate = { user_id = "Legacy Bot <legacy@example.com>", algorithm = "rsa", bits = 4096 } }capabilities must be a non-empty list containing "sign", "encrypt", or
both without duplicates. algorithm defaults to "ed25519". Selecting
"rsa" uses RSA for the primary key and every requested subkey; bits
defaults to 3072 and accepts values from 2048 through 8192. bits is invalid
with "ed25519".
The result is one -----BEGIN PGP PRIVATE KEY BLOCK----- value that can be imported by GnuPG and other OpenPGP tools. It has
no OpenPGP passphrase and no expiration; protect it with an encrypted provider
and rotate it according to the consuming system’s policy. Set as_path = true
when a command needs a temporary key file rather than the armored value in an
environment variable.
SSH private keys
Section titled “SSH private keys”ssh_private_key generates an unencrypted OpenSSH private key entirely in
process. generate = true uses Ed25519, the sensible default for new SSH keys:
[profiles.default]DEPLOY_KEY = { description = "Deployment SSH key", type = "ssh_private_key", generate = true }
# RSA is available for compatibility; 3072 bits is the default.LEGACY_DEPLOY_KEY = { description = "Legacy deployment key", type = "ssh_private_key", generate = { algorithm = "rsa", bits = 4096, comment = "deploy@example.com" } }RSA sizes from 2048 through 8192 bits are accepted. bits is invalid with
Ed25519. comment is optional and cannot contain control characters. Generated
keys are not passphrase-encrypted, so store them in an encrypted provider. Set
as_path = true when a command needs the key in a temporary file rather than in
an environment variable.
How it works
Section titled “How it works”- Generation only triggers when a secret is missing. Existing secrets are never overwritten.
- Generated values are stored via the secret’s configured provider (or the default provider).
- Subsequent runs find the stored value and skip generation (idempotent).
- The
nullprovider (0.19+) instead returns a fresh generated value for only the current resolution. generateanddefaultcannot both be set on the same secret.- Setting
typewithoutgenerateis informational only and does not trigger auto-generation.
Ephemeral generation with null
Section titled “Ephemeral generation with null”Use providers = ["null"] when the value should be generated on demand and
never written to provider storage:
[profiles.default]SESSION_SECRET = { description = "Per-run session secret", type = "base64", generate = { bytes = 32 }, providers = ["null"] }One materializing resolution receives one value. The next run, get,
check, or SDK value-carrying resolution receives a new one. Value-free
reports describe the value as generated without minting it. Use a writable
provider instead when another process or later invocation must retrieve the
same value.
Example
Section titled “Example”[profiles.default]# Auto-generated on first run, reused after thatDB_PASSWORD = { description = "Database password", type = "password", generate = true }
# Custom length and character setADMIN_PASSWORD = { description = "Admin password", type = "password", generate = { length = 64, charset = "ascii" } }
# 64-byte key encoded as base64ENCRYPTION_KEY = { description = "Encryption key", type = "base64", generate = { bytes = 64 } }
# RSA private key (default 2048-bit)JWT_SIGNING_KEY = { description = "JWT signing key", type = "rsa_private_key", generate = true }
# RSA private key with custom key sizeTLS_KEY = { description = "TLS private key", type = "rsa_private_key", generate = { bits = 4096 } }
# OpenPGP signing key (requires SecretSpec 0.21+)RELEASE_KEY = { description = "Release signing key", type = "openpgp_private_key", generate = { user_id = "Release Bot <releases@example.com>", capabilities = ["sign"] } }
# OpenSSH Ed25519 private key (requires SecretSpec 0.21+)DEPLOY_KEY = { description = "Deployment SSH key", type = "ssh_private_key", generate = true }
# Informational type only, no generationEXTERNAL_API_KEY = { description = "Provided by vendor", type = "password" }See the configuration reference for the full specification.