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
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" } }
# 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)
  • 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