---ci---
project: acdl
phase: 8
milestone: v1.1
status: plan-as-execute
persona: security-engineer+platform-engineer
task: [T-8.1, T-8.2, T-8.3, T-8.4]
requirements.covered: [REQ-23]
---/ci---
Waves 1+2: IAM policy + state backend + IAM user creation scripts.
- T-8.1 (security): terraform/bootstrap/spike_runner_policy.json —
least-privilege IAM policy: Allow S3 r/w on the state bucket, DynamoDB
r/w on the outbox table, sts:GetCallerIdentity; final Deny statement
(Action *, NotResource = the above ARNs) enforcing least privilege. No
terraform apply permission (plan-only spike).
- T-8.2/T-8.3 (platform): terraform/bootstrap/create_state_backend.py —
boto3, idempotent: creates S3 bucket acdl-tfstate-581513795199-us-east-1
(versioning enabled) + DynamoDB table acdl-outbox (PAY_PER_REQUEST, PK
contractId, SK eventType#eventTs per D-P08-1 one table for both lock
+ outbox). Writes .bootstrap_state.json marker.
- T-8.4 (platform + security review): terraform/bootstrap/create_iam_user.py
— boto3, idempotent: creates IAM user acdl-spike-runner, attaches the
inline policy from spike_runner_policy.json, creates an initial access
key if none active exists (prints to stdout for the orchestrator to
capture; NEVER committed).
py_compile + policy JSON valid.