-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
featureTriggers Simple Forge's Product Manager role to start working on the issueTriggers Simple Forge's Product Manager role to start working on the issue
Description
Problem
Currently, secrets defined in .sc/stacks/<parent-stack>/secrets.yaml are available globally to all environments. This creates challenges:
- Security: Production secrets (API keys, passwords) shouldn't be accessible in dev/staging
- Isolation: Some secrets should only exist in specific environments
- Naming: Same secret name (e.g.,
DATABASE_PASSWORD) needs different values per environment while services expect a consistent name
Example of the Problem
# Current: .sc/stacks/devops/secrets.yaml
values:
DATABASE_PASSWORD: "prod-password-123" # Available everywhere - wrong for dev/staging
STRIPE_API_KEY: "sk_live_xxx" # Production key exposed to all envs
SLACK_WEBHOOK: "https://hooks.slack.com/..." # Maybe OK to shareA developer deploying to staging inadvertently gets access to production secrets.
Proposed Solution
Add a secrets section to server.yaml that controls per-environment secret availability and mapping.
Syntax
# .sc/stacks/devops/server.yaml
schemaVersion: 1.0
secrets:
inheritAll: false # Default: true (backwards compatible)
environments:
staging:
include:
# null (~) means "use same key from secrets.yaml"
SLACK_WEBHOOK: ~
# Reference another key in secrets.yaml
DATABASE_PASSWORD: "${secret:DATABASE_PASSWORD_STAGING}"
STRIPE_API_KEY: "${secret:STRIPE_TEST_KEY}"
# Literal value (no ${secret:} wrapper)
LOG_LEVEL: "debug"
ENABLE_PROFILING: "true"
production:
include:
SLACK_WEBHOOK: ~
DATABASE_PASSWORD: "${secret:DATABASE_PASSWORD_PROD}"
STRIPE_API_KEY: "${secret:STRIPE_LIVE_KEY}"
DATADOG_API_KEY: ~
LOG_LEVEL: "warn"
resources:
staging:
template: stack-per-app
# ...
production:
template: stack-per-app
# ...secrets.yaml (encrypted):
values:
DATABASE_PASSWORD_PROD: "super-secret-prod-password"
DATABASE_PASSWORD_STAGING: "staging-password-123"
STRIPE_LIVE_KEY: "sk_live_xxx"
STRIPE_TEST_KEY: "sk_test_yyy"
SLACK_WEBHOOK: "https://hooks.slack.com/..."
DATADOG_API_KEY: "dd-api-xxx"Syntax Reference
| Pattern | Type | Description |
|---|---|---|
SECRET_NAME: ~ |
Reference | Use value of SECRET_NAME from secrets.yaml |
NAME: "${secret:KEY}" |
Mapped Reference | Expose as NAME, fetch value from KEY in secrets.yaml |
NAME: "value" |
Literal | Expose as NAME with hardcoded value |
Behavior
| Setting | Description |
|---|---|
inheritAll: true (default) |
All secrets.yaml values available in all envs (current behavior) |
inheritAll: false |
Only explicitly listed secrets available per environment |
exclude: [names] |
Block specific secrets (only with inheritAll: true) |
Example with Exclusions
secrets:
inheritAll: true # Start with all secrets
environments:
staging:
exclude:
- DATADOG_API_KEY # Not needed in staging
- STRIPE_LIVE_KEY # Security: no prod keys in staging
override:
STRIPE_API_KEY: "${secret:STRIPE_TEST_KEY}"
production:
# Gets everything, no overrides neededService Usage (No Changes)
Client configurations remain unchanged:
# client.yaml
stacks:
production:
parent: company/devops
secrets:
DB_PASS: "${secret:DATABASE_PASSWORD}" # Resolves to prod value
STRIPE: "${secret:STRIPE_API_KEY}" # Resolves to live key# Same client.yaml deployed to staging
stacks:
staging:
parent: company/devops
secrets:
DB_PASS: "${secret:DATABASE_PASSWORD}" # Resolves to staging value
STRIPE: "${secret:STRIPE_API_KEY}" # Resolves to test keyValidation
sc validate should:
- Warn if a secret referenced in client.yaml isn't available for target environment
- Error if
${secret:KEY}references a non-existent key in secrets.yaml - Warn about unused secrets in secrets.yaml
Migration
- Backwards compatible: Without
secretssection, all secrets available everywhere - Opt-in: Teams adopt incrementally
- No client changes: Existing service configs work without modification
Benefits
- Secret values stay encrypted in secrets.yaml
- Mapping logic in version-controlled server.yaml
- Supports both references and literals
- No changes to service configurations
- Clear separation of environments
- Backwards compatible
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
featureTriggers Simple Forge's Product Manager role to start working on the issueTriggers Simple Forge's Product Manager role to start working on the issue