Repository navigation
feat(identity): carry workload credential claims into policy and support optional authentication - #117
feat(identity): carry workload credential claims into policy and support optional authentication#117hexfusion wants to merge 2 commits into
Conversation
|
cc @araujof |
debc8b5 to
04ddea2
Compare
WorkloadIdentity gains a claims map and a claim_str accessor mirroring SubjectExtension, and extract_workload flattens those claims into the bag under caller_workload.claim.<name> through the same walker as subject and client claims. Registered JWT claims (iss, iat, and the rest) and the structured-field sources stay reserved, so a token's protocol fields never reach the claim namespace a policy reads. The configured mapper carries only its explicitly mapped fields. Signed-off-by: Sam Batschelet <sbatsche@redhat.com>
A required flag (default true, fail closed) turns the resolver into an optional authenticator: when false, a request with no token resolves no identity and continues, letting a later filter resolve a different credential, with a downstream default-deny gate as the backstop. A token that is present but invalid is still denied. Tests pin the present-but-invalid denial under required:false and the fail-closed default. Signed-off-by: Sam Batschelet <sbatsche@redhat.com>
04ddea2 to
2156d7c
Compare
|
Hi @hexfusion, Can we understand a bit more about why claims are going on the workloadIdentity? We handle it a bit differently in PPE with role: client. The identity design keeps
The test token here is a SPIFFE Is there a reason that does not work for the grid case? For example, the token has no 2. The claims do not reach policy on the runtime pathThe resolver always builds a The new tests call
3. Conflicts with #119#119 moved Smaller points
|
| /// resolves no identity and continues, but a present-but-invalid token | ||
| /// is still denied. | ||
| #[serde(default = "default_required")] | ||
| pub required: bool, |
There was a problem hiding this comment.
Document required: false including absent vs. invalid/empty headers, the need for a positive auth gate, and that missing identity attributes evaluate false so negated predicates still pass.
| selectors, | ||
| client_id, | ||
| // Explicit fields only, no preset-style remaining-claims carry. | ||
| claims: Default::default(), |
There was a problem hiding this comment.
Use self.claims_bag(section, claims) for caller_workload instead of map_workload; otherwise workload JWT claims are discarded and policy checks always deny. Remove the obsolete no-claims warnings in resolver.rs/config.rs and the corresponding docs. Add a resolver-level test that passes a workload token through JwtIdentityResolver::handle and verifies a custom claim reaches policy, plus a preset-vs-StandardClaimMap test covering non-registered claims.
| async fn an_optional_resolver_continues_on_a_missing_header() { | ||
| // required: false lets a request with no token through, so a shared | ||
| // chain can fall to another credential (e.g. a peer certificate) with | ||
| // a downstream default-deny gate as the backstop. A token that IS |
There was a problem hiding this comment.
We'll wanna update the section comment: required: true denies missing headers, while false continues with an empty identity. Also clarify that require(authenticated) denies when subject.id is absent.
| // sec.caller_workload.attestor → caller_workload.attestor : String | ||
| // sec.caller_workload.selectors → caller_workload.selectors : StringSet (always) | ||
| // sec.caller_workload.client_id → caller_workload.client_id : String | ||
| // sec.caller_workload.claims → caller_workload.claim.<k> : flattened JSON |
There was a problem hiding this comment.
We should document <ns>.claim.<dotted> in the workload table matching the Client table and optionally reference caller_workload.claim.<k> in the APL identity docs.
|
@hexfusion just a gentle nudge, are you planning to address the reviews on this one? Please ping me if you need any help. Thanks! |
Broadens what a policy can key on beyond the end-user subject, and lets the JWT resolver authenticate optionally. Additive to the identity plugins and the extension model. No existing behavior changes by default.
WorkloadIdentitygains aclaimsmap and aclaim_straccessor, mirroringSubjectExtension, so a policy can read a scalar claim from the workload credential. Strings borrow, numbers and booleans render, and structured claims returnNone.iss,iat, and the rest) stay out of the copied claims, so a token's protocol fields do not leak into the claim namespace a policy reads.requiredflag, defaulting to true. When false, the resolver continues on an absent token but still denies a present-but-invalid one, so the default stays fail-closed.Part of #115