Created
October 29, 2025 20:38
-
-
Save cwood/aaa93db6e3e91bf173d47b75bb3422b2 to your computer and use it in GitHub Desktop.
ECS Secrets Share
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ┌─────────────────────────────────────────────────────────────────────────────┐ | |
| │ DEPLOYMENT FLOW (Deploy Time) │ | |
| └─────────────────────────────────────────────────────────────────────────────┘ | |
| SOURCE ACCOUNT (Ephemeral Env) TARGET ACCOUNT (Production) | |
| ┌──────────────────────────┐ ┌──────────────────────────┐ | |
| │ │ │ │ | |
| │ 1. User runs deploy │ │ │ | |
| │ ephemeral deploy │ │ │ | |
| │ │ │ │ | |
| └────────────┬─────────────┘ └──────────────────────────┘ | |
| │ | |
| │ | |
| ┌────────────▼─────────────┐ | |
| │ 2. Parse alma.sd.yaml │ | |
| │ - inherit-from │ | |
| │ - role-arn │ | |
| └────────────┬─────────────┘ | |
| │ | |
| │ | |
| ┌────────────▼─────────────┐ ┌──────────────────────────┐ | |
| │ 3. Assume Role │───────STS────▶ │ EphemeralSecretsAccess │ | |
| │ (via role-arn) │ AssumeRole │ Role (trust policy │ | |
| │ │◀───temp creds──│ allows source account) │ | |
| └────────────┬─────────────┘ └──────────────────────────┘ | |
| │ | |
| │ | |
| ┌────────────▼─────────────┐ ┌──────────────────────────┐ | |
| │ 4. Fetch Secrets │ │ │ | |
| │ (Pulumi Provider │─────List──────▶│ production/myapp/* │ | |
| │ with assumed role) │ Secrets │ (Secrets Manager) │ | |
| │ │◀──Secret ARNs──│ │ | |
| └────────────┬─────────────┘ └──────────────────────────┘ | |
| │ | |
| │ | |
| ┌────────────▼─────────────┐ | |
| │ 5. Create IAM Resources │ | |
| │ - Execution Role │ | |
| │ - Task Role │ | |
| │ execution-role ARN │ | |
| │ = arn:...:role/ │ | |
| │ pr-123-ecs-exec... │ | |
| └────────────┬─────────────┘ | |
| │ | |
| │ | |
| ┌────────────▼─────────────┐ | |
| │ 6. Create Execution │ | |
| │ Role Policy │ | |
| │ Allow GetSecretValue │ | |
| │ on cross-acct ARNs │ | |
| └────────────┬─────────────┘ | |
| │ | |
| │ ┌──────────────────────────┐ | |
| ┌────────────▼─────────────┐ │ Each Secret │ | |
| │ 7. Grant Cross-Account │ │ ┌────────────────────┐ │ | |
| │ Access (AWS SDK) │────Assume─────▶│ │ Resource Policy: │ │ | |
| │ │ Role │ │ { │ │ | |
| │ For each secret ARN: │────Put────────▶│ │ Principal: { │ │ | |
| │ - GetResourcePolicy │ Resource │ │ AWS: [ │ │ | |
| │ - Merge principals │ Policy │ │ pr-123-exec │ │ | |
| │ - PutResourcePolicy │ │ │ ] │ │ | |
| │ │ │ │ } │ │ | |
| │ │ │ │ Action: │ │ | |
| │ │ │ │ GetSecretValue │ │ | |
| │ │ │ │ } │ │ | |
| └──────────────────────────┘ │ └────────────────────┘ │ | |
| └──────────────────────────┘ | |
| ┌─────────────────────────────────────────────────────────────────────────────┐ | |
| │ RUNTIME FLOW (Container Startup) │ | |
| └─────────────────────────────────────────────────────────────────────────────┘ | |
| SOURCE ACCOUNT TARGET ACCOUNT | |
| ┌──────────────────────────┐ ┌──────────────────────────┐ | |
| │ ECS Service │ │ │ | |
| │ ┌────────────────────┐ │ │ │ | |
| │ │ ECS Control Plane │ │ │ │ | |
| │ │ (uses Execution │ │────Get────────▶│ production/myapp/* │ | |
| │ │ Role) │ │ Secret │ (checks resource policy)│ | |
| │ │ │ │ Value │ │ | |
| │ │ ✓ Has identity- │ │◀───Secret──────│ ✓ Allows pr-123-exec │ | |
| │ │ based policy │ │ Value │ role │ | |
| │ └─────────┬──────────┘ │ │ │ | |
| │ │ │ └──────────────────────────┘ | |
| │ │ inject │ | |
| │ │ env vars │ | |
| │ ┌─────────▼──────────┐ │ | |
| │ │ App Container │ │ | |
| │ │ (Task Role) │ │ | |
| │ │ │ │ | |
| │ │ DATABASE_URL=... │ │ | |
| │ │ API_KEY=... │ │ | |
| │ └────────────────────┘ │ | |
| └──────────────────────────┘ | |
| ┌─────────────────────────────────────────────────────────────────────────────┐ | |
| │ DESTROY FLOW (Cleanup) │ | |
| └─────────────────────────────────────────────────────────────────────────────┘ | |
| SOURCE ACCOUNT TARGET ACCOUNT | |
| ┌──────────────────────────┐ | |
| │ 1. User runs destroy │ | |
| │ ephemeral destroy │ | |
| └────────────┬─────────────┘ | |
| │ | |
| │ | |
| ┌────────────▼─────────────┐ | |
| │ 2. Get Stack Outputs │ | |
| │ - secret ARNs │ | |
| │ - execution role ARN │ | |
| │ - cross-acct role │ | |
| └────────────┬─────────────┘ | |
| │ | |
| │ | |
| ┌────────────▼─────────────┐ ┌──────────────────────────┐ | |
| │ 3. Revoke Cross-Acct │ │ Each Secret │ | |
| │ Access (best-effort) │────Assume─────▶│ ┌────────────────────┐ │ | |
| │ │ Role │ │ Resource Policy: │ │ | |
| │ For each secret ARN: │────Put────────▶│ │ Remove pr-123-exec │ │ | |
| │ - GetResourcePolicy │ Resource │ │ from principals │ │ | |
| │ - Remove exec role │ Policy │ │ │ │ | |
| │ - PutResourcePolicy │ │ │ (or delete policy │ │ | |
| │ (log on failure) │ │ │ if last principal)│ │ | |
| └────────────┬─────────────┘ │ └────────────────────┘ │ | |
| │ └──────────────────────────┘ | |
| │ | |
| ┌────────────▼─────────────┐ | |
| │ 4. Pulumi Destroy │ | |
| │ (removes all infra) │ | |
| │ - Execution Role │ | |
| │ - Task Role │ | |
| │ - ECS Service │ | |
| └──────────────────────────┘ | |
| ┌─────────────────────────────────────────────────────────────────────────────┐ | |
| │ KEY PERMISSIONS │ | |
| └─────────────────────────────────────────────────────────────────────────────┘ | |
| SOURCE ACCOUNT: | |
| ┌────────────────────────────────────────────────────────────────┐ | |
| │ GitHub Actions Role / Deployment User │ | |
| │ - sts:AssumeRole on TARGET_ACCOUNT:role/EphemeralSecretsAccess│ | |
| └────────────────────────────────────────────────────────────────┘ | |
| ┌────────────────────────────────────────────────────────────────┐ | |
| │ ECS Execution Role (pr-123-ecs-execution-role) │ | |
| │ - secretsmanager:GetSecretValue on TARGET_ACCOUNT secrets │ | |
| └────────────────────────────────────────────────────────────────┘ | |
| TARGET ACCOUNT: | |
| ┌────────────────────────────────────────────────────────────────┐ | |
| │ EphemeralSecretsAccess Role │ | |
| │ Trust Policy: Allow SOURCE_ACCOUNT:root to AssumeRole │ | |
| │ Permissions: │ | |
| │ - secretsmanager:GetSecretValue │ | |
| │ - secretsmanager:ListSecrets │ | |
| │ - secretsmanager:GetResourcePolicy │ | |
| │ - secretsmanager:PutResourcePolicy │ | |
| │ - secretsmanager:DeleteResourcePolicy │ | |
| └────────────────────────────────────────────────────────────────┘ | |
| ┌────────────────────────────────────────────────────────────────┐ | |
| │ Each Secret Resource Policy (managed by tool) │ | |
| │ Principal: arn:aws:iam::SOURCE:role/pr-123-ecs-execution-role│ | |
| │ Action: secretsmanager:GetSecretValue │ | |
| └────────────────────────────────────────────────────────────────┘ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment