* chore(infra): retarget prod to seahaven-prod account + OIDC deploy-role artifacts Retarget the CDK prod env from mgmt (328440206208, now frozen for workloads) to the dedicated seahaven-prod workload account (011934824531). proposal-system is the org's first prod tenant. Hard-block env=staging (still targets frozen mgmt) in resolveConfig until it is retargeted to seahaven-dev (710827005802). Add a WARN-only out-of-pipeline deploy guard in bin/app.ts. Add infra/deploy-role/: OIDC trust policy (sub scoped to Sea-Haven-Industries/proposal-system:ref:refs/heads/main), least-privilege permissions policy (AssumeRole on the verified cdk-hnb659fds bootstrap roles, deterministic site bucket, account-scoped CloudFront invalidation), and an idempotent creation script. Verified against live prod: bootstrap qualifier hnb659fds v32, OIDC provider present. Passed GPT-4.1 cross-review (APPROVE) and workflow red-team (CLEAN). Role NOT yet created — gated on /sh-security-review + the deploy go-ahead. Docs: README + CLAUDE.md reflect the prod account and pipeline-only deploy. * chore(infra): region-bound deploy-role DescribeStacks to us-east-1 (sh-security-review IAM-L2) * feat(infra): Aurora prod backup retention 14d + window; prod-only CDK context Bump Aurora automated-backup (PITR) retention 7->14d and set a preferred backup window for the prod tenant. Dedicated AWS Backup vault + cross-account restore test is a tracked follow-up (no org central-backup design exists yet). Prune the stale mgmt-account AZ context; prod (011934824531) is the only deploy target.
2.9 KiB
seahaven-prod OIDC deploy role — proposal-system
IAM artifacts for the GitHub Actions OIDC deploy role that lets the
Sea-Haven-Industries/proposal-system repo deploy the CDK stacks and sync the
frontend site bucket into seahaven-prod. Artifacts only — nothing here has
been applied to AWS.
Resolved facts (Phase 0, read-only verification)
| Field | Value |
|---|---|
| Account | 011934824531 (seahaven-prod) |
| Region | us-east-1 |
| CDK qualifier | hnb659fds (AWS CDK default — bootstrap v32; no custom synthesizer needed) |
| OIDC provider ARN | arn:aws:iam::011934824531:oidc-provider/token.actions.githubusercontent.com (EXISTS) |
| Role name | githubdeploy-proposal-system |
| Subject scope | repo:Sea-Haven-Industries/proposal-system:ref:refs/heads/main (exact, no wildcard) |
| Site bucket | proposal-system-web-011934824531 (frontend-stack convention) |
Files
-
trust-policy.json — Web-identity trust policy. Federated principal is the existing GitHub OIDC provider.
sts:AssumeRoleWithWebIdentitygated by two StringEquals conditions:aud == sts.amazonaws.comand an exactsubmatch on the proposal-system repo'smainbranch (noStringLike, no wildcard). Mirrors the structure of the existinggithubdeploy-seahaven-org-baselinerole. -
permissions-policy.json — Least-privilege inline policy:
sts:AssumeRoleon the four CDK bootstrap roles (deploy, file-publishing, lookup, image-publishing) scoped to qualifierhnb659fds, account, and region. This is how a CDK deploy actually gains its power — no direct service permissions are granted to the deploy role itself.cloudformation:DescribeStackson*for thecdk deploy/ change-set health check.s3:PutObject/DeleteObject/ListBucketon the site bucket and its objects for the frontend asset sync.cloudfront:CreateInvalidationon*, constrained byaws:ResourceAccount == 011934824531(distribution ARNs aren't known at author time; the account condition prevents cross-account use).
-
create-deploy-role.sh — Idempotent bash (
aws --profile prod). Verifies the profile resolves to011934824531, then create-role (or update-assume-role-policy if it exists) + put-role-policy. Safe to re-run. Gated: do not execute until GPT-4.1 cross-review AND/sh-security-reviewpass (IAM/trust change).
Applying (after gates pass)
./create-deploy-role.sh
Then point the GitHub Actions workflow's aws-actions/configure-aws-credentials
step at the printed role ARN.
Placeholders / follow-ups
- None outstanding. Qualifier resolved to the real value
hnb659fds; no<QUALIFIER>placeholder remains. OIDC provider exists, so no provider creation prerequisite. - CloudFront invalidation is scoped by account, not by distribution ARN — tighten to the specific distribution ARN once frontend-stack is deployed if you want per-resource least privilege.