▸ Agent Skills
1 min read

Configuration Inheritance

SecretSpec supports sharing common secrets across projects through the extends field in [project]. This avoids duplicating secret definitions in monorepos or multi-service setups.

Basic Example

A shared base configuration:

[project]name = "common"
[profiles.default]DATABASE_URL = { description = "Main database", required = true }INTERNAL_API_KEY = { description = "Internal service API key", required = true }

shared/common/secretspec.toml

A project that extends it:

[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

myapp/secretspec.toml

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

A project can extend multiple configurations. Later sources take precedence over earlier ones:

[project]name = "api-service"extends = ["../../shared/base", "../../shared/database", "../../shared/auth"]

Rules

  • Child definitions completely replace parent definitions for the same secret
  • Later sources in extends override earlier ones
  • Shared ancestors are applied once, so diamond-shaped inheritance is supported
  • Each profile is merged independently
  • Profile [defaults] inherit field by field across source files
  • The inherit profile-default field (0.19+) follows that same extends precedence. A child profile keeps an inherited inherit = false unless a later source explicitly sets it to true.
  • A child [scopes.\<name\>] completely replaces the parent scope of the same name — its secrets list wins outright; the two lists are not unioned. Scopes defined only in a parent are inherited. (Whole-value replacement is the safe default for an allowlist: extending a config cannot silently widen a scope the parent narrowed.) Available from SecretSpec 0.17.
  • Paths are relative to the containing secretspec.toml file

Last updated Oct 08, 2026