Secure Secret Access
1. Context
Section titled “1. Context”A service needs credentials or provider configuration — database credentials, JWT signing configuration, payment provider configuration — that must never appear in the DSL or generated source as literal values.
2. Problem
Section titled “2. Problem”How do you give a service typed, named access to secret values from potentially different secret backends, without hardcoding any secret value anywhere in the model?
3. Forces
Section titled “3. Forces”- Coupling — services should depend on a typed secret contract, not on a specific secret-backend product.
- Reuse — related secrets (auth, payment) are easier to maintain as small, focused vaults than as one large flat set.
- Security — secret values must never be written into the DSL; only their type and shape are declared.
- Composition — one physical backend often needs to serve several logical secret groups at once.
4. Solution
Section titled “4. Solution”Declare small, focused @vault blocks per concern (for example AuthVault,
PaymentVault), each with the required engine and configType attributes
and typed Secret declarations (type = <TypeRef>, never a value). Compose
them into one primary vault using includes. A service then
use vaults the vaults it needs and connects an expression to retrieve each
secret through its typed contract.
5. Structure
Section titled “5. Structure”flowchart LR MainVault -- includes --> AuthVault["AuthVault<br/>Secret JwtCfg"] MainVault -- includes --> PaymentVault["PaymentVault<br/>Secret PaymentCfg"] MainVault["MainVault (primary)<br/>engine: hashicorp<br/>Secret DbCredentials"] SecretService -- use vault --> MainVault SecretService -- use vault --> AuthVault SecretService -- use vault --> PaymentVault6. DSL Sketch
Section titled “6. DSL Sketch”@vault
Vault AuthVault primary = false engine = hashicorp configType = VaultConfig Secret JwtCfg type = JwtConfig
Vault PaymentVault primary = false engine = hashicorp configType = VaultConfig Secret PaymentCfg type = PaymentApiConfig
Vault MainVault primary = true includes = AuthVault, PaymentVault engine = hashicorp configType = VaultConfig Secret DbCredentials type = DatabaseCredentials
@service
SecretService use vault MainVault use vault AuthVault use vault PaymentVault use expression GetDbCredentials use expression GetJwtConfig
connect api.getDbCredentials -> GetDbCredentials connect api.getJwtConfig -> GetJwtConfigThis is a minimal illustrative fragment, not a complete duplicated example — see Working Examples for the full, runnable model.
7. Consequences
Section titled “7. Consequences”Benefits
Section titled “Benefits”- Secret values never appear in the DSL — only typed contracts do.
- Splitting vaults by concern keeps each one small and independently owned.
- A primary composition can map several logical vaults to one physical backend while preserving their qualified identities.
Trade-offs
Section titled “Trade-offs”- Each vault must declare a valid engine and compatible configuration schema; the corresponding environment values must be supplied correctly at deployment time.
- A service that composes many vaults takes on a dependency on all of their secret contracts being resolvable at runtime.
8. Alternatives
Section titled “8. Alternatives”- If a value is genuinely not secret (feature flags, timeouts, ports), model
it with
@configinstead of@vault— see the Config DSL Reference. Most real services combine both:@configfor non-secret settings,@vaultfor secret ones.
9. Related DSL
Section titled “9. Related DSL”- Vault DSL Reference — vault composition,
includes, and typed secrets. - Config DSL Reference — non-secret typed configuration used alongside vaults.
- Service DSL Reference — using vaults from a service.
10. Working Examples
Section titled “10. Working Examples”- Simple Vault Usage — typed database, authentication, and payment secrets in focused vaults, composed into one primary vault for service access.
11. Related Patterns
Section titled “11. Related Patterns”- Database-Backed CRUD — a common consumer of vault-protected database credentials.