Add support for different claims for authentication#5336
Add support for different claims for authentication#5336pranav shah (prashah-confluent) wants to merge 21 commits intomasterfrom
Conversation
|
🎉 All Contributor License Agreements have been signed. Ready to merge. |
Emanuele Sabellico (emasab)
left a comment
There was a problem hiding this comment.
Thanks Pranav! This is my feedback:
src/rdkafka_conf.c
Outdated
| "JWT claim name to use as the subject (principal) when validating " | ||
| "OIDC access tokens. Must be present in the JWT payload with a " | ||
| "non-empty value. Should match the broker's " | ||
| "sasl.oauthbearer.sub.claim.name configuration for consistent " |
There was a problem hiding this comment.
| "sasl.oauthbearer.sub.claim.name configuration for consistent " | |
| "`sasl.oauthbearer.sub.claim.name` configuration for consistent " |
There was a problem hiding this comment.
rebuild CONFIGURATION.md as well.
There was a problem hiding this comment.
Changed to "sasl.oauthbearer.sub.claim.name" and rebuilt CONFIGURATION.md
src/rdkafka_sasl_oauthbearer_oidc.c
Outdated
| /* Safety check to default to "sub" if not set */ | ||
| if (!sub_claim_name || !*sub_claim_name) | ||
| sub_claim_name = "sub"; |
There was a problem hiding this comment.
it shoud be a rd_dassert here, not reverting to the default. The configuration should be validated in rd_kafka_conf_finalize_oauthbearer_oidc and using rd_kafka_conf_is_modified on the field and then check for NULL or a an empty string or whitespace string ("\s+") you can write a function like the Java method ClaimValidationUtils.validateString.
There was a problem hiding this comment.
Added rd_dassert and as suggested added helper api which validates string only if config is modified.
tests/0126-oauthbearer_oidc.c
Outdated
| do_test_produce_consumer_with_OIDC(test_name, | ||
| sub_claim_conf); | ||
| } else { | ||
| /* These variations should fail due to missing claim */ |
There was a problem hiding this comment.
This function should be agnostic to the failure cause (at the moment it's only this one but in future there can be other test cases).
| /* These variations should fail due to missing claim */ | |
| /* These variations should fail */ |
There was a problem hiding this comment.
Modified the comment to make the function failure agnostic
CHANGELOG.md
Outdated
|
|
||
| librdkafka v2.14.0 is a feature release: | ||
|
|
||
| * [KIP-768](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=186877575#KIP768:ExtendSASL/OAUTHBEARERwithSupportforOIDC-ClientConfiguration) Extend SASL/OAUTHBEARER to support OIDC claim mapping beyond the default `sub` claim [(#5336)](https://github.com/confluentinc/librdkafka/pull/5336) |
There was a problem hiding this comment.
| * [KIP-768](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=186877575#KIP768:ExtendSASL/OAUTHBEARERwithSupportforOIDC-ClientConfiguration) Extend SASL/OAUTHBEARER to support OIDC claim mapping beyond the default `sub` claim [(#5336)](https://github.com/confluentinc/librdkafka/pull/5336) | |
| * [KIP-768](https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=186877575#KIP768:ExtendSASL/OAUTHBEARERwithSupportforOIDC-ClientConfiguration) Extend SASL/OAUTHBEARER to support OIDC claim mapping beyond the default `sub` claim (#5336). |
The link is already added by GH in the release page, so we don't put the link here.
There was a problem hiding this comment.
Removed the link
src/rdkafka_sasl_oauthbearer_oidc.c
Outdated
| {"NULL sub_claim_name defaults to 'sub'", UT_JWT_SUB_ONLY, NULL, | ||
| rd_true, "subject"}, | ||
| {"Empty sub_claim_name defaults to 'sub'", UT_JWT_SUB_ONLY, "", | ||
| rd_true, "subject"}, |
There was a problem hiding this comment.
We can remove these two cases after putting an assert there as it must not reach this function if those preconditions aren't satisfied.
| {"NULL sub_claim_name defaults to 'sub'", UT_JWT_SUB_ONLY, NULL, | |
| rd_true, "subject"}, | |
| {"Empty sub_claim_name defaults to 'sub'", UT_JWT_SUB_ONLY, "", | |
| rd_true, "subject"}, |
There was a problem hiding this comment.
Removed the test cases since they can't be valid at this point.
| case OIDC_CONFIGURATION_SUB_CLAIM_VARIATION_EMPTY_STRING: | ||
| test_conf_set(conf, "sasl.oauthbearer.sub.claim.name", ""); | ||
| break; |
There was a problem hiding this comment.
This one should fail as well. Similarly to the Java client, in case it's set it should be valid otherwise the user could want to set something but there was a bug in their code so an empty string was received instead.
There was a problem hiding this comment.
This should pass due to librdkafka convention which sets the config to default values if empty/NULL string is provided.
PR description
Problem
For OIDC / SASL_OAUTHBEARER flows using librdkafka’s built‑in OIDC helper, we currently hard‑require that the JWT payload contain a sub claim. If the IdP omits sub or uses another claim (for example client_id) as the primary subject, librdkafka fails token acquisition with an error such as:
Failed to acquire SASL OAUTHBEARER token: Expected JSON JWT response with "sub" fieldFix
We have introduced a new config
sub_claim_nameusing which customers can provide a different claim. The claim value will be honored and used for client side validation.Note
Requires users to keep broker and client configs aligned for the subject claim name to avoid confusion and consistency.
Testing
Unit tests
To test the core JWT payload parsing and claim extraction logic inside rd_kafka_oidc_token_try_validate() in isolation (no broker, network, oidc server).
Default Configuration & Backward Compatibility
Implicit Default Behavior: Validate that when sub.claim.name is not provided, the system defaults to extracting the subject from the "sub" claim.
Legacy Parity: Ensure that existing JWTs containing only the "sub" claim continue to be processed correctly, maintaining no regressions for standard OIDC flows.
Explicit Claim Configuration (KIP-768 Parity)
Custom Claim Extraction: Verify that setting sub.claim.name (e.g., to client_id) successfully extracts the value from the specified field instead of the hardcoded "sub" key.
Configuration Precedence: Test that when both "sub" and a custom claim (e.g., "client_id") coexist in a JWT, the system honors the user-defined configuration over the OIDC default.
Error Handling & Validation Logic
Missing Claim Detection: Verify that providing a sub.claim.name that does not exist in the JWT triggers a specific "Claim not found" error, rather than failing on a hardcoded "sub".
Empty Value Rejection: Ensure the system rejects empty string subjects with a "non-empty value required" error, addressing previous bugs where empty strings passed silently.
Invalid Configuration Recovery: Validate that if sub.claim.name is set to an empty string, the system gracefully falls back to the OIDC default ("sub") to ensure continuous operation.
librdkafka & Java Client Alignment
Functional Parity: Ensure all scenarios are cross-validated against the Java KIP-768 implementation to guarantee identical extraction logic and exception triggers (e.g., ValidateException equivalents).
Integration tests
Design Doc