fix(vault): rename applications.policies → ops_policies (cms CI was silently missing its R2 policy) #4

Merged
arcodange merged 1 commits from claude/fix-cms-ops-policies-key into main 2026-06-28 19:22:07 +02:00
Owner

The bug

The applications object field is declared policies in variables.tf, but everything else uses the name ops_policies:

  • the cms tfvars entry: ops_policies = ["factory__cf_r2_arcodange_tf"]
  • the runbook: doc/runbooks/new-web-app/03-vault-platform.md:28,82
  • the guidebook: vibe/guidebooks/tools/secrets-and-vso.md:112
  • the module input: modules/app_policy variable ops_policies

Terraform silently drops unknown attributes when converting a value to an object() type, so cms's ops_policies was discarded and each.value.policies (main.tf:82) fell back to []. Net effect: gitea_cicd_cms never received the factory__cf_r2_arcodange_tf token policy (read on kvv1/cloudflare/r2/arcodange-tf + kvv1/zoho/self_client, defined in factory iac/cloudflare.tf:52). cms CI has been missing its Cloudflare R2 Terraform-state permissions.

The fix (root-cause, not symptom)

Rename the schema field policiesops_policies + its single reference (main.tf:82 each.value.policieseach.value.ops_policies). This aligns the whole chain.

I chose this over renaming the tfvars key (the obvious alternative) because:

  • it's lower churn — 2 lines, no tfvars change, no doc changes;
  • the runbook + guidebook already document ops_policies, so renaming the tfvars would also require fixing both docs to prevent the next app from copying the broken key again. Renaming the schema fixes it at the source.
-    policies                   = optional(list(string), [])
+    ops_policies               = optional(list(string), [])
...
-  ops_policies               = each.value.policies
+  ops_policies               = each.value.ops_policies

Behavioural change + merge gate

gitea_cicd_cms gains factory__cf_r2_arcodange_tf in its token_policies. No other app sets this field (all default []), so no other role changes. The CI tofu apply must show only vault_jwt_auth_backend_role.gitea_jwt_cicd["cms"] updated in-place (token_policies gains the R2 policy) and 0 destroyed — I'll dispatch + confirm before merging.

Reviewer: please confirm factory__cf_r2_arcodange_tf is the intended grant for cms CI (it is per secrets-and-vso.md:112, but it's your prod permission so worth a glance).

🤖 Generated with Claude Code

## The bug The `applications` object field is declared `policies` in `variables.tf`, but **everything else uses the name `ops_policies`**: - the `cms` tfvars entry: `ops_policies = ["factory__cf_r2_arcodange_tf"]` - the runbook: `doc/runbooks/new-web-app/03-vault-platform.md:28,82` - the guidebook: `vibe/guidebooks/tools/secrets-and-vso.md:112` - the module input: `modules/app_policy` variable `ops_policies` Terraform **silently drops** unknown attributes when converting a value to an `object()` type, so cms's `ops_policies` was discarded and `each.value.policies` (`main.tf:82`) fell back to `[]`. Net effect: **`gitea_cicd_cms` never received the `factory__cf_r2_arcodange_tf` token policy** (read on `kvv1/cloudflare/r2/arcodange-tf` + `kvv1/zoho/self_client`, defined in factory `iac/cloudflare.tf:52`). cms CI has been missing its Cloudflare R2 Terraform-state permissions. ## The fix (root-cause, not symptom) Rename the schema field `policies` → `ops_policies` + its single reference (`main.tf:82` `each.value.policies` → `each.value.ops_policies`). This aligns the whole chain. I chose this over renaming the tfvars key (the obvious alternative) because: - it's **lower churn** — 2 lines, no tfvars change, no doc changes; - the runbook + guidebook **already** document `ops_policies`, so renaming the tfvars would *also* require fixing both docs to prevent the next app from copying the broken key again. Renaming the schema fixes it at the source. ```diff - policies = optional(list(string), []) + ops_policies = optional(list(string), []) ... - ops_policies = each.value.policies + ops_policies = each.value.ops_policies ``` ## Behavioural change + merge gate `gitea_cicd_cms` gains `factory__cf_r2_arcodange_tf` in its `token_policies`. No other app sets this field (all default `[]`), so no other role changes. The CI `tofu apply` must show **only** `vault_jwt_auth_backend_role.gitea_jwt_cicd["cms"]` updated in-place (token_policies gains the R2 policy) and **0 destroyed** — I'll dispatch + confirm before merging. **Reviewer:** please confirm `factory__cf_r2_arcodange_tf` is the intended grant for cms CI (it is per `secrets-and-vso.md:112`, but it's your prod permission so worth a glance). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
arcodange added 1 commit 2026-06-28 19:18:48 +02:00
fix(vault): rename applications.policies field to ops_policies (cms CI was silently missing its R2 policy)
Some checks failed
Helm Charts / Library charts tool (push) Blocked by required conditions
Helm Charts / Application charts pgcat (push) Blocked by required conditions
Helm Charts / Detect changed charts (pull_request) Successful in 19s
Helm Charts / Library charts tool (pull_request) Has been skipped
Helm Charts / Application charts pgcat (pull_request) Has been skipped
Helm Charts / Detect changed charts (push) Failing after 13m59s
3170a341d1
The `applications` object field was declared `policies` in variables.tf, but
the cms tfvars entry, the runbook (doc/runbooks/new-web-app/03-vault-platform.md),
the guidebook (vibe/guidebooks/tools/secrets-and-vso.md) and the module input
(modules/app_policy variable `ops_policies`) all use the name `ops_policies`.

Because Terraform silently drops unknown attributes when converting a value to
an object() type, cms's `ops_policies = ["factory__cf_r2_arcodange_tf"]` was
discarded and `each.value.policies` fell back to [] — so gitea_cicd_cms never
received the `factory__cf_r2_arcodange_tf` token policy (read on
kvv1/cloudflare/r2/arcodange-tf + kvv1/zoho/self_client, defined in
factory iac/cloudflare.tf). cms CI was missing its Cloudflare R2 Terraform-state
permissions.

Fix at the root: rename the schema field `policies` -> `ops_policies` (and its
single reference main.tf:82 `each.value.policies` -> `each.value.ops_policies`),
aligning the whole chain. This is lower-churn than renaming the tfvars key (the
chosen alternative would also have required fixing the runbook + guidebook, which
both already document `ops_policies`) and prevents the next app created from the
runbook from re-introducing the same silently-dropped key.

Behavioural change: gitea_cicd_cms gains `factory__cf_r2_arcodange_tf` in its
token_policies. No other app sets this field (all default []), so no other role
changes. Reviewer: confirm the R2 policy is the intended grant for cms CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
arcodange merged commit 06c5eb4391 into main 2026-06-28 19:22:07 +02:00
arcodange deleted branch claude/fix-cms-ops-policies-key 2026-06-28 19:22:15 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arcodange-org/tools#4