Skip to content

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.

[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 }
TypeDefault OutputOptions
password32 alphanumeric charslength (int), charset ("alphanumeric" or "ascii")
hex64 hex chars (32 bytes)bytes (int)
base6444 chars (32 bytes)bytes (int)
uuidUUID v4 (36 chars)none
commandstdout of command; exact bytes in 0.21+command (string, required)
rsa_private_key2048-bit RSA private key (PKCS1 PEM)bits (int)
openpgp_private_key (0.21+)ASCII-armored OpenPGP transferable secret keyuser_id (required), algorithm ("ed25519" or "rsa"), bits (RSA only), capabilities (["sign"], ["encrypt"], or both)
ssh_private_key (0.21+)Unencrypted OpenSSH Ed25519 private keyalgorithm ("ed25519" or "rsa"), bits (RSA only), comment (string)

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_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_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.

  • 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 null provider (0.19+) instead returns a fresh generated value for only the current resolution.
  • generate and default cannot both be set on the same secret.
  • Setting type without generate is informational only and does not trigger auto-generation.

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.

[profiles.default]
# Auto-generated on first run, reused after that
DB_PASSWORD = { description = "Database password", type = "password", generate = true }
# Custom length and character set
ADMIN_PASSWORD = { description = "Admin password", type = "password", generate = { length = 64, charset = "ascii" } }
# 64-byte key encoded as base64
ENCRYPTION_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 size
TLS_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 generation
EXTERNAL_API_KEY = { description = "Provided by vendor", type = "password" }

See the configuration reference for the full specification.