Support nested map claims in Cedar authorization for act claim#5713
Open
jhrozek wants to merge 1 commit into
Open
Support nested map claims in Cedar authorization for act claim#5713jhrozek wants to merge 1 commit into
jhrozek wants to merge 1 commit into
Conversation
Add map[string]interface{} case to convertToCedarValue so that nested
JWT claims like the RFC 8693 act claim ({"sub": "spiffe://..."}) are
converted to Cedar Records instead of being silently dropped.
This enables delegation policies such as:
principal.claim_act.sub like "spiffe://toolhive.dev/ns/agents/sa/*"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5713 +/- ##
==========================================
+ Coverage 70.63% 70.67% +0.04%
==========================================
Files 667 667
Lines 67607 67622 +15
==========================================
+ Hits 47752 47792 +40
+ Misses 16399 16359 -40
- Partials 3456 3471 +15 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Cedar policies flatten JWT claims into
context/principalattributes, but nested map claims were silently dropped during conversion — most notably an RFC 8693 actor-delegation claim (act), shaped like{"act": {"sub": "spiffe://..."}}. This meant Cedar could never express delegation-aware policies such as "the user can write, but an agent acting on the user's behalf can only read."This PR adds recursive conversion of nested map/array claims into nested Cedar records/sets, bounded by a depth cap (
maxClaimNestingDepth = 10) so a claim from an unverified upstream JWT can't drive unbounded recursion. With this change, policies can now do:maxClaimNestingDepthguard and depth-tracked variants ofconvertMapToCedarRecord/convertToCedarValueactRefs #5194
Type of change
Test plan
task test)task test-e2e)task lint-fix)Does this introduce a user-facing change?
Yes. Cedar policies can now read nested JWT claims via dot-access (e.g.
context.claim_act.sub), not just flat scalar/array claims. Claims nested more than 10 levels deep are silently dropped (with a warning logged) rather than causing unbounded recursion.Special notes for reviewers
actclaim) as a standalone, additive slice. The producer side — the embedded AS's own RFC 8693 token-exchange handler that mintsactclaims, plusactor_tokenandoidc-trustsupport — is being developed separately ontoken-delegationand isn't part of this PR.actisn't dependent on that producer landing first: per Embedded auth server should support RFC 8693 token exchange so agents can act on behalf of users #5194's federated trust model,actcan also arrive on a subject token issued by any external IdP the deployment already trusts, so this is useful standalone.parseUpstreamJWTClaimsincore.gousesjwt.ParseUnverified, relying on the token having already been validated upstream), so nesting depth has no other bound.Generated with Claude Code