Skip to content

fix(authorization): approve the rendered surface per document so HelmRelease PRs stop conflicting - #4251

Merged
devantler merged 1 commit into
mainfrom
claude/eks-surface-ledger-3182
Sep 29, 2026
Merged

devantler merged 1 commit into
mainfrom
claude/eks-surface-ledger-3182

Conversation

@devantler

Copy link
Copy Markdown
Contributor

🤖 Generated by the Agentic Engineer

Why

The production authorization check approves everything it guards with one single fingerprint. Every change that touches a guarded component had to rewrite that same line, so any two such changes collided and each merge forced the other to redo its approval. Chart and image updates queued behind one another.

What

The approval is now a list with one entry per guarded component, and the check stays exactly as strict, so two changes to different components edit different entries and merge cleanly. A failing check now names the exact entries to change, which removes the extra step that only existed to explain a failure. The existing approval history moves into its own file, unchanged.

Fixes #3182

…Release PRs stop conflicting

The EKS authorization validator approved the whole rendered surface as one
aggregate SHA-256 constant in main.go. Every PR that moved any selected
document had to rewrite that one line, so any two such PRs conflicted by
construction and each merge re-invalidated the other's approval (#3182).

Replace the constant with an embedded ledger, approved-surface.txt: one
`<apiVersion>|<kind>|<namespace>|<name> <sha256>` entry per selected document,
sorted and separated by blank lines. The rendered surface must equal it as a
multiset, which is exactly as strict as the aggregate (same entries, same
multiplicity), but a change now touches only its own documents' lines. The
blank separators keep approvals of neighbouring documents mergeable, and the
merge queue validates the combined render.

On a mismatch the validator prints the exact "-"/"+" lines to apply, so the
approval-base mode and the HEAD^1 checkout that existed only to explain an
aggregate mismatch are removed. The 3,225-line approval rationale that sat
above the constant moves verbatim into approved-surface-history.md.

The ledger was generated from the same render as the current approval and
reproduces its aggregate (e5d7a55b…) exactly.

Fixes #3182

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 1eaeab86-1d15-434a-a285-f17df3fd0512

📥 Commits

Reviewing files that changed from the base of the PR and between b376cdf and 819b34c.

📒 Files selected for processing (9)
  • .github/workflows/ci.yaml
  • k8s/providers/hetzner/infrastructure/controllers/longhorn/helm-release.yaml
  • scripts/tests/test-authorization-gate-diagnostics.sh
  • scripts/validate-eks-ci-role-policy/approval_base_test.go
  • scripts/validate-eks-ci-role-policy/approved-surface-history.md
  • scripts/validate-eks-ci-role-policy/approved-surface.txt
  • scripts/validate-eks-ci-role-policy/main.go
  • scripts/validate-eks-ci-role-policy/surface_delta_test.go
  • scripts/validate-eks-ci-role-policy/surface_ledger_test.go
💤 Files with no reviewable changes (2)
  • scripts/validate-eks-ci-role-policy/approval_base_test.go
  • scripts/validate-eks-ci-role-policy/surface_delta_test.go

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📜 Recent review details
🧰 Additional context used
🪛 LanguageTool
scripts/validate-eks-ci-role-policy/approved-surface.txt

[grammar] ~327-~327: Use a hyphen to join words.
Context: ...lkit.fluxcd.io/v1|HelmRepository|dex|dex d251b34144fb4d376b47526e24b3520a1cc69615...

(QB_NEW_EN_HYPHEN)


[grammar] ~379-~379: Use a hyphen to join words.
Context: ....fluxcd.io/v1|HelmRepository|umami|umami ca5626705a569e5e728e26714300d39f07eb8c2e...

(QB_NEW_EN_HYPHEN)


[grammar] ~389-~389: Use a hyphen to join words.
Context: ...olkit.fluxcd.io/v1|OCIRepository|aws|aws f900dbd1860a7494381bb0fe0bd044ebedeaa157...

(QB_NEW_EN_HYPHEN)


📝 Walkthrough

Walkthrough

The change adds a committed ledger of approved rendered Kubernetes documents, with tests for ledger parsing, comparison, and mismatch diagnostics. The CI workflow no longer fetches or checks out a base tree for authorization validation. It runs the tests and validator against the current checkout. Diagnostic tests now expect added ledger lines, and a HelmRelease comment refers to approved-surface entries.

Priority: ⬆️ High

Severity of issue fixed: High

Merge Risk: ⚪ Minimal · up to 819b3

The change moves the authorization approval check to per-document entries and validates the current checkout. No merge-blocking issue was identified in the supplied context.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to 819b3

The new gate still requires rendered authorization documents to match committed approvals, and no new bypass was established. Because this is a production authorization control, the initial approval migration and the policy governing who may approve ledger changes warrant design review.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The affected control covers selected authorization-capable objects across production overlays, including objects relevant to the protected AWS service-account authorization path. The inspected CI change does not itself grant runtime credentials.

Security Findings and Attack Paths

  • inferred — A repository author can submit matching rendered changes and approval data for review. That capability alone is not a newly demonstrated bypass: the prior approval digest was also editable in the repository, while the head gate still requires an exact match. Whether a separate reviewer must approve either form of change is unverified.

Trust Boundaries and Controls

  • observed — Repository-authored manifests cross into the CI renderer, then into role, boundary, per-object and ledger checks. The authorization job’s path filter includes changes to the ledger and validator.

Resilience and Maintainability Implications

  • inferred — Sorted comparison cannot express order-dependent effects of two different documents with the same identity. Its security significance depends on downstream handling of duplicates; the old sorted aggregate shared the limitation, and the current committed approval was reported to contain no duplicate identities.

Hardening Proposals

  • proposed — Consider explicitly rejecting duplicate identities across the entire selected surface, and verify that approval-file changes require the intended independent review. These would strengthen or document controls, not remedy a verified PR-introduced bypass.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed For [#3182], the validator now uses an embedded per-document ledger and requires the rendered surface to match it exactly. This keeps document identities, digests, and multiplicity guarded while allow…
Out of Scope Changes check ✅ Passed The ledger, validator tests, CI changes, approval-history file, and post-renderer documentation all support replacing the aggregate fingerprint with per-document approvals for [#3182]. The removed app…
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 14 functions across 2 files. (3 skipped: 3…
Title check ✅ Passed The title clearly summarizes the main change: per-document authorization approval prevents HelmRelease pull requests from conflicting.
Description check ✅ Passed The description directly explains the authorization approval change, the reason for the change, and the expected effect on HelmRelease and dependency pull requests.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Agentic Engineer

Readiness at 819b34c7f34097f06cd405a5bdd13429d042691b

  • CI: all 24 checks pass (7 skipped are merge-group-only). 🔐 Validate Production Authorization passes on CI's checksum-pinned kubectl v1.36.2 render, so the committed ledger equals the production render exactly.
  • Review: CodeRabbit finished at this head with no actionable comments, and there are no review threads.
  • Tried as a user: I rendered all five authorization overlays and got the aggregate this PR replaces (e5d7a55b…, 193 documents), so the ledger starts from exactly the approved state. Flipping one digest in the ledger makes the validator fail and print the exact lines to change:
    unapproved rendered authorization surface: 2 ledger line(s) differ from scripts/validate-eks-ci-role-policy/approved-surface.txt ...
      - helm.toolkit.fluxcd.io/v2|HelmRelease|kube-system|tetragon 8cc1b89c…a9e5ba0
      + helm.toolkit.fluxcd.io/v2|HelmRelease|kube-system|tetragon 8cc1b89c…a9e5ba4
    
    Dropping a line and duplicating a line fail the same way. I also changed two neighbouring entries on separate copies and merged them with git merge-file: the result had no conflict and kept both changes. The same test without the blank separators conflicts, which is why the file requires them.
  • Deploy effect: none. Production manifests are unchanged; the only manifest edit is a YAML comment, which the render drops.

@devantler
devantler marked this pull request as ready for review September 29, 2026 20:10
@devantler
devantler added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit 8e243cf Sep 29, 2026
31 checks passed
@devantler
devantler deleted the claude/eks-surface-ledger-3182 branch September 29, 2026 20:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

Validate EKS Authorization fails on every HelmRelease change, blocking all chart/image updates

1 participant