---ci--- project: acdl phase: 0 milestone: v1.2 status: fix ---/ci--- The expanded policy (4727 chars pretty / 3464 compact) exceeded the AWS 2048-char inline policy limit (total across all inline policies on a user). Compressed to 1667 chars by: (1) removing DenyEverythingElse (redundant — IAM is default-deny; the user has no other inline policies), (2) using action-prefix wildcards (ecs:Create*, ecr:Get*, etc.) instead of listing every action, (3) removing SIDs. The compressed policy grants the same effective permissions. The repo file now matches what should be applied in the AWS Console.
ACDL v1.1 Spike — AWS Bootstrap Runbook
Phase 08 bootstraps the AWS substrate for the v1.1 spike. It uses the root account credential for account 581513795199 exactly once, then closes D-034 by having the user manually rotate the root key afterward.
Spike scope (D-039): the spike uses a per-run-rotated IAM user key (
acdl-spike-runner), NOT OIDC. Real OIDC federation is deferred to v1.2 (blocked on go-gitea/gitea#36988 — Gitea Actions does not supportid-token: write). Theacdl-spike-runneruser + its key are deleted in v1.2 cleanup when the OIDC role lands.
Steps
-
Set the bootstrap root key in env (never commit, never echo):
export ACDL_BOOTSTRAP_AWS_ACCESS_KEY_ID="<root key>" export ACDL_BOOTSTRAP_AWS_SECRET_ACCESS_KEY="<root secret>" export AWS_DEFAULT_REGION="us-east-1" -
Create the state backend (S3 bucket + DynamoDB outbox table):
python3 terraform/bootstrap/create_state_backend.pyIdempotent; writes
terraform/bootstrap/.bootstrap_state.jsonmarker. -
Create the IAM user + scoped policy + initial key:
python3 terraform/bootstrap/create_iam_user.pyPrints
ACDL_AWS_ACCESS_KEY_ID=<...>+ACDL_AWS_SECRET_ACCESS_KEY=<...>to stdout (capture if you want the initial key;rotate_spike_key.shcreates a fresh one anyway). -
Rotate the spike key (creates a new key, deactivates+deletes old, writes the new key to gitignored
.env.secrets):bash scripts/rotate_spike_key.shOptionally uploads to Gitea Actions secrets if
ACDL_GITEA_TOKENis set. -
Verify:
bash scripts/verify_phase08.shAsserts: caller identity is
acdl-spike-runner(not root); S3 bucket + DynamoDB table + IAM user + scoped policy all exist;.env.secrets+.bootstrap_state.jsonare gitignored. -
MANUAL — D-034 closure: rotate/deactivate the root key in the AWS IAM console (the user does this, not the script). The bootstrap root key has now served its one-shot purpose; the spike uses the rotated
acdl-spike-runnerkey for Phases 09-10.
What the spike uses for Phases 09-10
- State backend: S3 bucket
acdl-tfstate-581513795199-us-east-1+ DynamoDB tableacdl-outbox(one table for both lock + outbox, D-P08-1). - Auth: the rotated
acdl-spike-runnerkey in.env.secrets(gitignored, chmod 600). Re-rotate after each spike run viarotate_spike_key.sh(D-039).
Spike scope vs v1.2 boundary
| Concern | Spike (Phase 08) | v1.2 |
|---|---|---|
| AWS auth | per-run-rotated long-lived key (D-039 waiver) | real OIDC federation (go-gitea/gitea#36988) |
| IAM | minimal user acdl-spike-runner + scoped policy |
OIDC role + trust policy (no user, no key) |
| State backend | S3 + DynamoDB single-region (us-east-1) | multi-region |
| Secret storage | gitignored .env.secrets + optional Gitea secret |
Gitea OIDC-issued web-identity token (no secret) |