Post-rename deploy verified green from seahaven-org-baseline (run
29355616637, both account jobs). The freed repo name must not stay
trusted (namespace-reuse window, security review IAC-02).
* Add stacks input to cd-cdk for multi-account apps
cdk deploy was hardcoded to --all, which breaks when one CDK app defines
stacks for two AWS accounts: whichever role the job assumed fails on the
other account's stacks. Callers can now pass per-job stack selectors;
default stays --all so existing callers are unaffected.
* Trust seahaven-org-baseline sub on account-baseline deploy role
Transition pair for the repo rename: OIDC sub claims carry the repo full
name, so the renamed repo cannot assume the role until its sub is
trusted. Old sub is removed after a post-rename deploy verifies green.
* Pass stacks selector via env var, not expression interpolation
Defense-in-depth from the security review: expression interpolation
into run: is pre-shell text substitution, so metacharacters in the
input would execute as script. Env-var expansion never re-parses shell
syntax; word-splitting for multiple selectors is preserved.
The CFN execution role held IAMFullAccess + seven *FullAccess managed
policies, giving it unconstrained AWS admin access. This replaces all
of those with per-service inline statements covering exactly what the
five SAM stacks require during a CloudFormation deploy.
PRIMARY ESCALATION CONTROL: iam:CreateRole, iam:AttachRolePolicy, and
iam:PutRolePolicy are now conditioned on iam:PermissionsBoundary
StringEquals the seahaven-lambda-execution-boundary ARN. Any role the
CFN execution role creates must carry that boundary, capping its
effective permissions at the boundary's ceiling.
SAM RolePath note: AWS::Serverless::Function does not support a custom
RolePath on auto-generated execution roles. Path scoping (e.g.
/cfn-managed/) cannot be used as the escalation guard for SAM auto-roles.
The iam:PermissionsBoundary condition achieves the same security goal.
DEPLOY ORDER DEPENDENCY: the seahaven-lambda-execution-boundary policy
(INFRA-103, PR #45) MUST exist before this stack is deployed. See the
PR description for the mandatory three-step deploy sequence.
Refs: INFRA-97
* Add seahaven-lambda-execution-boundary managed policy
Lambda execution roles auto-generated by SAM have no ceiling today —
a misconfigured Policies block could grant excessive permissions that
persist at runtime. This boundary caps every SAM function execution
role at the union of what the five stacks actually need, so the
effective permissions are always the intersection of the role's own
policies and this document.
The policy is a deliberate superset rather than exact-minimum: being
slightly broad is safer than a boundary that breaks functions at
runtime. Per-service scoping will tighten in follow-up work.
SAM template agents: add
PermissionsBoundary: arn:aws:iam::328440206208:policy/seahaven-lambda-execution-boundary
to Globals.Function in all five stacks after this stack deploys.
Refs: INFRA-103
* Fix boundary gaps found in GPT-4.1 cross-review
Three issues from the mandatory IAM cross-review (BLOCK/FIX):
1. Add KMS statement — PaymentsDashboard DynamoDB table and
payments-dashboard CloudWatch log groups use CMKs. Without
kms:Decrypt + kms:GenerateDataKey in the boundary, those Lambda
calls fail at the KMS layer at runtime. Scoped to account keys only.
2. Add table/*/index/* to DynamoDB resource — dynamodb:Query on a GSI
requires the index ARN; covering only table/* silently denied GSI
queries at the boundary.
3. Fix EC2 ENI statement — remove AssignPrivateIpAddresses /
UnassignPrivateIpAddresses (EFA-only, not part of Lambda ENI
lifecycle); add DescribeSubnets + DescribeSecurityGroups + DescribeVpcs
which are required by the Lambda service during VPC attachment and are
present in AWSLambdaVPCAccessExecutionRole.
4. Add SES configuration-set/* resource — ses:SendRawEmail requires
permission on the configuration set if one is passed at send time.
Refs: INFRA-103
Adds read + (dis)associate wafv2 actions so SAM/CFN deploys can attach the shared
seahaven-app-waf CloudFront WebACL to app distributions (meal-order orders).
Without it, the WebACL association fails 'Unable to verify read permissions on
Web ACL'. IAM cross-reviewed (no BLOCK). Not wafv2:* — scoped to read +
associate. Same manual-changeset deploy path as the H-16 change.
- New githubdeploy-seahaven-account-baseline OIDC role (CDK pattern: assumes
cdk-hnb659fds-*, scoped to the repo's main branch). Wires CD for the shared
account-baseline repo (CloudTrail C-1 + AWS Backup C-7).
- Codify cloudfront:* and ssm:* on github-cfn-execution-role to reconcile
out-of-band drift (audit H-16). These are needed by live SAM deploys
(meal-order CloudFront; afterhours/payments/meal-order SSM params).
Deployed via change set wire-account-baseline-and-h16; stack now IN_SYNC.
IAM cross-review completed (new role confirmed; cfn-exec breadth documented).
Mirrors the existing per-repo deploy roles (StringLike sub claim, scoped to
repo:<org>/apm-wo-analysis:ref:refs/heads/main, sts:AssumeRole on
cdk-hnb659fds-* only). Cross-reviewed (cross_reviewer): additive, no existing
role modified; the one flagged item (StringLike->StringEquals) was a false
positive — all 8 existing roles use StringLike, so this is consistent.
- SQS/EC2/SNS as inline policy (managed policy quota is 10)
- cd-sam.yaml now accepts optional parameter-overrides input for
SAM templates with required parameters
- Add cloudformation:CreateChangeSet on aws:transform/* to the shared
CFN execution role (required for SAM's Serverless transform)
- Remove working-directory from pip install step so it finds
requirements.txt at repo root (not just cdk-dir)