Skip to content

Declarative Configuration

SecretSpec uses secretspec.toml to declare what secrets your application needs, separating requirements from storage mechanisms for portability across environments.

[project]
name = "my-app"
revision = "1.0"
extends = ["../shared/common"] # Optional: inherit from other configs
[profiles.default]
DATABASE_URL = { description = "PostgreSQL connection string", required = true }
API_KEY = { description = "External API key", required = true }
SESSION_SECRET = { description = "Session signing secret", required = true, type = "password", generate = true }

Each secret is declared with configuration options:

SECRET_NAME = {
description = "Human-readable explanation", # Required: shown in prompts
required = true, # Optional: defaults to true
default = "value" # Optional: fallback if not set
}

Options:

  • description: Explains the secret’s purpose (required in the default profile; profile overrides inherit it when omitted)
  • required: Whether the secret must be provided (default: true)
  • default: Fallback value for optional secrets
  • composed (0.16+): Derive a read-only value from other declared secrets (see Composed Secrets for the strict template and dependency semantics)
  • type: Secret type for auto-generation (password, hex, base64, uuid, command, rsa_private_key; passphrase, mnemonic, openpgp_private_key, ssh_private_key, wireguard_private_key, jwk_private_key, age_identity, and x509_identity require 0.21+)
  • generate: Enable auto-generation when the secret is missing (true or a table with options)
  • prompt (0.19+): Securely ask for a missing value during secretspec run and let the selected provider decide whether to save the answer
  • from (0.21+): Derive a read-only value from another declared secret, either by selecting a field with extract or by converting an x509_identity into a pkcs12, pkcs8_private_key, x509_certificate, x509_certificate_chain, or x509_issuer_chain (see the configuration reference)
  • format (0.21+): Choose pem (default) or der for a converted key or certificate
  • credentials (0.21+): Bind the password that opens a stored x509_identity or protects a derived pkcs12 to another declared secret
  1. Descriptive names: Use STRIPE_API_KEY instead of generic API_KEY
  2. Clear descriptions: Help developers understand each secret’s purpose
  3. Sensible defaults: Provide development defaults, require production values
  4. Modular inheritance: Create reusable base configurations for common patterns
[project]
name = "web-api"
revision = "1.0"
extends = ["../shared/base", "../shared/auth"]
[profiles.default]
# Inherits DATABASE_URL, INTERNAL_API_KEY from base
# Inherits JWT_SECRET, SESSION_SECRET from auth
# Service-specific additions:
STRIPE_API_KEY = { description = "Stripe payment API", required = true }
REDIS_URL = { description = "Redis cache connection", required = true }
PORT = { description = "Server port", required = false, default = "3000" }