Declarative Configuration
SecretSpec uses secretspec.toml
to declare what secrets your application needs, separating requirements from storage mechanisms for portability across environments.
Basic Structure
Section titled “Basic Structure”[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 }LOG_LEVEL = { description = "Logging verbosity", required = false, default = "info" }
Secret Declarations
Section titled “Secret Declarations”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)required
: Whether the secret must be provided (default:true
)default
: Fallback value for optional secrets
Configuration Inheritance
Section titled “Configuration Inheritance”SecretSpec supports sharing common secrets across projects through the extends
field.
Basic Example
Section titled “Basic Example”[project]name = "common"
[profiles.default]DATABASE_URL = { description = "Main database", required = true }LOG_LEVEL = { description = "Log verbosity", required = false, default = "info" }
[project]name = "myapp"extends = ["../shared/common"]
[profiles.default]DATABASE_URL = { description = "MyApp database", required = true } # OverrideAPI_KEY = { description = "External API key", required = true } # Add new
Monorepo Structure
Section titled “Monorepo Structure”monorepo/├── shared/│ ├── base/secretspec.toml # Common secrets│ └── database/secretspec.toml # DB-specific (extends base)└── services/ ├── api/secretspec.toml # API service (extends database) └── frontend/secretspec.toml # Frontend (extends base)
Multiple Inheritance
Section titled “Multiple Inheritance”[project]name = "api-service"extends = ["../../shared/base", "../../shared/database", "../../shared/auth"]
Rules:
- Child definitions completely replace parent definitions
- Later sources in
extends
override earlier ones - Each profile is merged independently
- Paths are relative to the containing file
Best Practices
Section titled “Best Practices”- Descriptive names: Use
STRIPE_API_KEY
instead of genericAPI_KEY
- Clear descriptions: Help developers understand each secret’s purpose
- Sensible defaults: Provide development defaults, require production values
- Modular inheritance: Create reusable base configurations for common patterns
Complete Example
Section titled “Complete Example”[project]name = "web-api"revision = "2.1.0"extends = ["../shared/base", "../shared/auth"]
[profiles.default]# Inherits DATABASE_URL, LOG_LEVEL 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" }