fix(kas): accept spec-compliant policy bindings - #4081
pflynn-virtru wants to merge 1 commit into
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
The spec defines the policy binding as Base64(HMAC), but no released KAS can decode that form. #2095 added a dual-accept branch and it has never worked: base64.DecodedLen over-allocates, so a 44-character binding decodes 32 bytes into a 33-byte buffer. Only the hex branch replaced that buffer with a right-sized slice; the raw branch passed the untrimmed 33 bytes to VerifyBinding, which compares with hmac.Equal -- length sensitive, so it always failed. Extract decodePolicyBinding, trimmed to the bytes actually decoded, and use it on the rewrap path. Legacy hex stays accepted indefinitely; TDFs are archival. This only widens what KAS accepts and changes no output, so it is safe to deploy on its own. It is a prerequisite for fixing the SDK writer, which is deliberately left for a follow-up: nothing may emit raw bindings until a KAS that can read them is deployed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Paul Flynn <pflynn-virtru@users.noreply.github.com>
3077045 to
ca178b0
Compare
X-Test Failure Reportgovulncheck-failure-3 |
Benchmark results, click to expandBenchmark authorization.GetDecisions Results:
Benchmark authorization.v2.GetMultiResourceDecision Results:
Benchmark Statistics
Bulk Benchmark Results
TDF3 Benchmark Results:
|
|
Security review: no findingsReviewed this change specifically against the concern it invites — that relaxing policy-binding decoding opens a fail-open in an integrity control. It doesn't:
Entitlement is unaffected — One informational note, not a finding and not introduced here: the dead Worth saying plainly: this was an AI-assisted review, not a substitute for a human security sign-off on a change to an integrity check. 🤖 Generated with Claude Code |
Fixes the KAS half of #3578. Split out of #3597, which depends on this.
The bug
The spec defines the key access object's policy binding as
Base64(HMAC(KEY, POLICY))(spec). #2095 added a branch so KAS would accept that alongside the legacyBase64(hex(HMAC)). It has never worked:DecodedLenover-allocates. Only the hex branch swaps in a correctly-sized slice, so the raw branch hands 33 bytes toVerifyBinding, which compares withhmac.Equalagainst a 32-byte digest.hmac.Equalis length-sensitive, so it is always false. Confirmed present in releasedservice/v0.9.0.Net effect: no released KAS can accept a spec-compliant policy binding, and any SDK that starts emitting one becomes undecryptable against it.
The fix
Extract
decodePolicyBinding, trimmed to the bytes actually decoded, and use it on the rewrap path. Both encodings are accepted; length disambiguates them (32 vs 64), so no version signal is needed. Legacy hex stays accepted indefinitely — TDFs are archival.The extraction is there to make the fix testable; the inline block it replaces was 17 lines and is now 6.
Checklist
Testing
TestDecodePolicyBindingIsTrimmedis the regression test, and it asserts the decoded length, with the over-allocation written out as a precondition. That matters: the buggy code produced the right bytes and only the wrong length, so a content comparison alone passes against it. Verified by reverting the one-line trim — the test fails with a trailing0x0.TestDecodePolicyBindingcovers raw, legacy hex, and invalid base64.go test ./service/kas/... -racegreen;golangci-lintclean on both files (the onesloglinthit inrewrap_test.gois pre-existing, just line-shifted by two added imports);make fmtclean.Scope
Deliberately KAS-only: it widens what the server accepts and changes no output, so it can merge and deploy independently.
Left out on purpose, as separate concerns:
!marker. Noterelease-please-config.sdk.jsonusesalways-bump-patch, so the version number won't signal it.verifyPolicyBinding. It has no production callers and is likely why the broken dual-accept looked correct — it reads like the verification path and its own hex handling is fine. Worth removing, but it is cleanup, not this fix.Worth checking any third-party KAS for the same untrimmed-buffer bug before relying on raw bindings against it.
🤖 Generated with Claude Code