scaleway/iam-policy v1.0.0
Context
terraform/modules/scaleway/iam-policy has supported bucket-scoped access (bucket_names/bucket_actions) independently of org/project grants since ADR-0049. But the one real prior attempt to use it for a read-only bucket key — the commented-out terraform/infrastructure/scaleway/fr-par/pigeon.dev/scratch/iam.tf (merged in verbatim from pigeon-do via ADR-0052) — combined bucket_names with a blanket project-level ObjectStorageObjectsRead/ObjectStorageObjectsWrite grant in the same call. Since Scaleway IAM rules are allow-only with no explicit deny (per ADR-0048's own findings), that blanket grant already covers every bucket in the project, making the bucket restriction decorative — exactly the "composition hazard" ADR-0048 documented but explicitly declined to enforce in code.
Decision
- Add a cross-variable
validationblock onbucket_namesrejecting any call that combines it with anObjectStorage*-familyorganization_permission_sets/project_permission_setsentry — verified against the exact broken prior-art pattern (now correctly rejected atplantime), the one live consumer (noisypigeon.com/terraform/iam.tf, unaffected since it never setsbucket_names), and the intended bucket-scoped read-only pattern (passes cleanly). - Document the correct bucket-scoped, read-only usage pattern in the module
README.md. - Breaking release →
release:major, next tagterraform/modules/scaleway/iam-policy/v1.0.0. - Full ADR:
docs/adr/0066-scaleway-iam-policy-prevent-bucket-scope-widening.md
Also included
- A pre-existing
terraform fmtalignment fix iniam_policy.tf(dynamic "rule"blocks), picked up incidentally while format-checking the module — unrelated to the validation change itself. - A fix to
.mise.toml: the ADR-0052 merge leftpigeon-do's terraformfmt/fmt-checktasks under the same names as the pre-existing Rust tasks (duplicate TOML keys), which brokemise's ability to parse its own config at all — blockingmise run ciand every othermise runcommand repo-wide. Renamed tofmt-terraform/fmt-check-terraform, matching whatCLAUDE.md's Commands section already documented.
Test plan
-
terraform validatepasses on the module. -
terraform planwith the broken prior-art pattern (bucket_names+ObjectStorageObjectsRead/Write) fails validation with the new error message. -
terraform planwith the livenoisypigeon.com/terraform/iam.tfpattern (org/project grants, nobucket_names) still plans cleanly. -
terraform planwith the intended read-only bucket-scoped pattern (bucket_names+bucket_actions = ["s3:ListBucket", "s3:GetObject"], no org/project grant) plans cleanly. -
mise run cipasses.