Skip to content

Secret manager env#3800

Open
ntner wants to merge 2 commits into
masterfrom
secret-manager-env
Open

Secret manager env#3800
ntner wants to merge 2 commits into
masterfrom
secret-manager-env

Conversation

@ntner
Copy link
Copy Markdown
Contributor

@ntner ntner commented May 25, 2026

Summary

Adds optional AWS Secrets Manager integration for injecting environment variables into ECS tasks via native secrets blocks, replacing runtime S3 fetch and KMS decrypt for env vars.

  • Write-through model: S3 remains source of truth, SM is a deployment-time overlay populated during ReleasePromote
  • ECS secrets injection uses ARN:key:: format to pull individual keys from a single per-app JSON secret ({rack}/{app})
  • When SM is active, CONVOX_ENV_KEY/URL/VARS are suppressed from task definitions, disabling the S3 fetch path in convox-env
  • One-off tasks (convox run) also get SM injection when enabled, with graceful S3 fallback if SM lookup fails
  • SM write failure during promote logs a warning and falls back to S3 injection (deploy is not blocked)
  • SM secret is cleaned up on app deletion
  • Tolerant to downgrade: racks without the SecretsManagerEnv parameter silently default to No
  • Gen1 apps excluded (they use a separate promote path)

Configuration levels

Level Command Precedence
Rack convox rack params set SecretsManagerEnv=Yes Default for all apps
App convox apps params set SecretsManagerEnv=Yes -a myapp Opt-in override (only "Yes" is honored; default "No" does not override rack)
convox.yml params: { SecretsManagerEnv: "Yes" } Overrides both rack and app

App-level setting is opt-in only: setting SecretsManagerEnv=Yes on an app enables SM even if the rack default is No, but setting No does not disable SM when the rack default is Yes. Use convox.yml params to explicitly disable SM for a specific app when the rack default is Yes.

Changes

File Change
provider/aws/secrets.go New SM backend: write/update/delete/restore with retry and failure counter
provider/aws/releases.go SM write during ReleasePromote with graceful S3 fallback on failure; opt-in-only parameter precedence
provider/aws/processes.go SM injection in one-off task definitions with S3 fallback
provider/aws/apps.go SM secret cleanup on app delete
provider/aws/formation/rack.json SecretsManagerEnv parameter + IAM policy for rack API role
provider/aws/formation/app.json.tmpl SecretsManagerEnv parameter, ExecutionRole SM policy (exact ARN), ExecutionRole output
provider/aws/formation/service.json.tmpl ExecutionRole SM policy (exact ARN), CONVOX_ENV suppression, Secrets block
provider/aws/formation/timer.json.tmpl CONVOX_ENV suppression, Secrets block (uses app-level ExecutionRole)

How env injection works

SM setting CONVOX_ENV vars Secrets block Env source
Off (default) Present Absent convox-env fetches from S3, decrypts with KMS
On Suppressed Present ECS resolves from Secrets Manager at task launch
On (SM write fails) Present Absent Falls back to S3 with warning log

Suppressing CONVOX_ENV_KEY/URL/VARS causes the convox-env wrapper to short-circuit (it checks CONVOX_ENV_URL at startup). Without this suppression, convox-env would fetch from S3 and overwrite SM-injected values via mergeEnv().

CloudFormation Impact

  • rack.json: New SecretsManagerEnv parameter (Default No), new inline IAM policy on ApiRole. No resource renames, no output changes.
  • app.json.tmpl: New parameter, ExecutionRole output, SM policy via Go template guard scoped to exact ARN. No resource renames.
  • service.json.tmpl: SM policy, CONVOX_ENV suppression, and Secrets block via Go template guards. No new CF parameters. No resource renames.
  • timer.json.tmpl: CONVOX_ENV suppression and Secrets block via Go template guard only. No CF parameter changes.
  • All changes are additive. Existing racks see no behavior change until SecretsManagerEnv=Yes is set.
  • Downgrade safe: missing parameter defaults to No, Go template guards produce no output when ARN is empty.

IAM Policy Scoping

Role Scope Actions
Rack ApiRole {rack}/* (all secrets under rack prefix) Full SM CRUD (create, read, update, delete, restore, tag)
App ExecutionRole Exact secret ARN GetSecretValue only
Service ExecutionRole Exact secret ARN GetSecretValue only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant