Skip to content

secretspec.toml Reference

The secretspec.toml file defines project-specific secret requirements. This file should be checked into version control.

[project]
name = "my-app" # Project name (required)
revision = "1.0" # Format version (required, must be "1.0")
extends = ["../shared"] # Paths to parent configs for inheritance (optional)
FieldTypeRequiredDescription
namestringYesProject identifier
revisionstringYesFormat version (must be “1.0”)
extendsarray[string]NoPaths to parent configuration files

Defines secret variables for different environments. At least a [profiles.default] section is required.

[profiles.default] # Default profile (required)
DATABASE_URL = { description = "PostgreSQL connection", required = true }
API_KEY = { description = "External API key", required = true }
REDIS_URL = { description = "Redis cache", required = false, default = "redis://localhost:6379" }
[profiles.production] # Additional profile (optional)
DATABASE_URL = { description = "Production database", required = true }

Each secret variable is defined as a table with the following fields:

FieldTypeRequiredDescription
descriptionstringYesHuman-readable description of the secret
requiredbooleanNo*Whether the value must be provided (default: true)
defaultstringNo**Default value if not provided
providersarray[string]NoList of provider aliases to use in fallback order
as_pathbooleanNoWrite secret to temp file and return file path (default: false)
typestringNo***Secret type for generation: password, hex, base64, uuid, command, rsa_private_key
generateboolean or tableNo***Enable auto-generation when secret is missing

*If default is provided, required defaults to false **Only valid when required = false ***type is required when generate is enabled; generate and default cannot both be set

secretspec.toml
[project]
name = "web-api"
revision = "1.0"
extends = ["../shared/secretspec.toml"] # Optional inheritance
# Default profile - always loaded first
[profiles.default]
APP_NAME = { description = "Application name", required = false, default = "MyApp" }
LOG_LEVEL = { description = "Log verbosity", required = false, default = "info" }
GITHUB_TOKEN = { description = "GitHub token", required = true, providers = ["env"] }
# Development profile - extends default
[profiles.development]
DATABASE_URL = { description = "Database connection", required = false, default = "sqlite://./dev.db" }
API_URL = { description = "API endpoint", required = false, default = "http://localhost:3000" }
DEBUG = { description = "Debug mode", required = false, default = "true" }
# Production profile - extends default
[profiles.production]
DATABASE_URL = { description = "PostgreSQL cluster connection", required = true, providers = ["prod_vault", "keyring"] }
API_URL = { description = "Production API endpoint", required = true }
SENTRY_DSN = { description = "Error tracking service", required = true, providers = ["shared_vault"] }
REDIS_URL = { description = "Redis cache connection", required = true }

When using per-secret provider configuration, provider aliases must be defined in your user configuration file at ~/.config/secretspec/config.toml:

[defaults]
provider = "keyring"
[providers]
prod_vault = "onepassword://vault/Production"
shared_vault = "onepassword://vault/Shared"
env = "env://"

Manage provider aliases using CLI commands:

Terminal window
# Add a provider alias
$ secretspec config provider add prod_vault "onepassword://vault/Production"
# List all aliases
$ secretspec config provider list
# Remove an alias
$ secretspec config provider remove prod_vault

When as_path = true, the secret value is written to a temporary file and the file path is returned instead of the value:

[profiles.default]
TLS_CERT = { description = "TLS certificate", as_path = true }
GOOGLE_APPLICATION_CREDENTIALS = { description = "GCP service account", as_path = true }
ContextBehavior
CLI (get, check, run)Files are persisted (not deleted after command exits)
Rust SDKFiles cleaned up when ValidatedSecrets is dropped; use keep_temp_files() to persist
Rust SDK typesPathBuf or Option<PathBuf> instead of String

When type and generate are set, missing secrets are automatically generated during check or run and stored via the configured provider:

[profiles.default]
# Simple: generate with type defaults
DB_PASSWORD = { description = "Database password", type = "password", generate = true }
REQUEST_ID = { description = "Request ID prefix", type = "uuid", generate = true }
# Custom options
API_TOKEN = { description = "API token", type = "hex", generate = { bytes = 32 } }
SESSION_KEY = { description = "Session key", type = "base64", generate = { bytes = 64 } }
# Shell command
MONGO_KEY = { description = "MongoDB keyfile", type = "command", generate = { command = "openssl rand -base64 765" } }
# RSA private key (PKCS1 PEM)
JWT_SIGNING_KEY = { description = "JWT signing key", type = "rsa_private_key", generate = true }
# Type without generate: informational only, no auto-generation
MANUAL_SECRET = { description = "Manually managed", type = "password" }
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 commandcommand (string, required)
rsa_private_key2048-bit RSA private key (PKCS1 PEM)bits (int)
  • 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)
  • generate and default cannot both be set on the same secret
  • type = "command" requires generate = { command = "..." } (not just generate = true)
  • All profiles automatically inherit from [profiles.default]
  • Profile-specific values override default values
  • Use the extends field in [project] to inherit from other secretspec.toml files