Add Azure Entra ID scp claim support#2300
Conversation
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Reviewer's GuideAdds support for Azure Entra ID's Sequence diagram for token conversion with combined scope and scp claimssequenceDiagram
actor IdP
participant AuthClient as AuthenticatorClient
participant AccessToken as AccessTokenClaims
participant Validator as ValidatedAccessToken
IdP->>AccessToken: Issue token with scope and_or_scp
AccessToken->>AuthClient: convert_token(access_token)
activate AuthClient
AuthClient->>AuthClient: extract_scopes(access_token)
note over AuthClient: Build scopes String from scope and scp
AuthClient->>AuthClient: map_scopes(scopes, scope_mappings)
note over AuthClient: Map raw scopes to permissions
AuthClient->>AuthClient: extend permissions with additional_permissions
AuthClient->>AuthClient: extract_groups(extended_claims, group_selector)
AuthClient->>Validator: construct ValidatedAccessToken
deactivate AuthClient
Validator-->>IdP: ValidatedAccessToken (permissions, groups)
Class diagram for updated AccessTokenClaims and AuthenticatorClientclassDiagram
class AccessTokenClaims {
String azp
String sub
Url iss
Option~String~ aud
i64 exp
i64 iat
Option~i64~ auth_time
Value extended_claims
String scope
Option~SingleOrMultiple~scp~ scp
}
class SingleOrMultiple {
+SingleOrMultiple~T~
T Single
T[] Multiple
}
class AuthenticatorClient {
+convert_token(access_token AccessTokenClaims) ValidatedAccessToken
-extract_scopes(access_token AccessTokenClaims) String
-map_scopes(scopes String, scope_mappings ScopeMappings) Vec~String~
additional_permissions Vec~String~
scope_mappings ScopeMappings
group_selector JpQuery
}
class ValidatedAccessToken {
Vec~String~ permissions
Vec~String~ groups
}
class ScopeMappings
class JpQuery
class Value
class Url
AccessTokenClaims --> SingleOrMultiple : uses
AuthenticatorClient --> AccessTokenClaims : converts
AuthenticatorClient --> ValidatedAccessToken : creates
AuthenticatorClient --> ScopeMappings : uses
AuthenticatorClient --> JpQuery : uses
AccessTokenClaims --> Url : uses
AccessTokenClaims --> Value : uses
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- When concatenating
scopeandscpinextract_scopes, consider normalizing and de-duplicating individual scopes to avoid mapping the same permission multiple times if both claims contain overlapping values. extract_scopescurrently allocates intermediateStrings (clones andformat!); if this path is performance-sensitive, you could refactor it (andmap_scopes) to work on an iterator orVec<&str>/Vec<String>instead of a single concatenated string.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- When concatenating `scope` and `scp` in `extract_scopes`, consider normalizing and de-duplicating individual scopes to avoid mapping the same permission multiple times if both claims contain overlapping values.
- `extract_scopes` currently allocates intermediate `String`s (clones and `format!`); if this path is performance-sensitive, you could refactor it (and `map_scopes`) to work on an iterator or `Vec<&str>`/`Vec<String>` instead of a single concatenated string.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
ctron
left a comment
There was a problem hiding this comment.
Thanks for the PR. I think, as discussed the call, we should make this configurable if possible. And I think it should be possible.
Similar to the groups, we could extract this using a JSON path, and then take the values and split by whitespace (like we do now). The default JSON path being $['scope','scp']
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #2300 +/- ##
==========================================
+ Coverage 67.66% 67.72% +0.06%
==========================================
Files 433 433
Lines 24851 24875 +24
Branches 24851 24875 +24
==========================================
+ Hits 16815 16847 +32
+ Misses 7114 7101 -13
- Partials 922 927 +5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Thanks @ctron I have made the changes, Please let me know. |
42d4fff to
b60c86c
Compare
- Remove dedicated `scope` field from AccessTokenClaims so it falls into `extended_claims` via serde(flatten), making it visible to the JSON-path selector in extract_scopes - Move DEFAULT_SCOPE_SELECTOR constant to config.rs where it belongs alongside the config struct that owns the field - Change scope_selector from Option<String> to String with a serde default, avoiding the unwrap-or dance at runtime - Extract scopes directly from extended_claims instead of round-tripping through serde_json::to_value on the full token - Return Vec<String> from extract_scopes instead of a joined String to avoid split→join→split round-trips through map_scopes - Unify map_scopes and map_groups behind a private map_items helper to eliminate duplicated lookup logic and align their signatures Made-with: Cursor
Signed-off-by: mrrajan <86094767+mrrajan@users.noreply.github.com.>
b60c86c to
9509ae1
Compare
|
@ctron Thanks for the review. I have addressed the requested changes. And refactored the map_scope and map_group functions into a single map_items function. Let me know your thoughts. |
|
/backport |
|
Backport failed for Please cherry-pick the changes locally and resolve any conflicts. git fetch origin release/0.4.z
git worktree add -d .worktree/backport-2300-to-release/0.4.z origin/release/0.4.z
cd .worktree/backport-2300-to-release/0.4.z
git switch --create backport-2300-to-release/0.4.z
git cherry-pick -x 9fa8f3bcf0ea39409282288f68a2e566569c7fbe 88f05d7f2976d37ef144fb042b156de8ef3d154d fc8d690c771fc79019ac3f90c376b0a021a7e664 |
Added support for Azure Entra ID's scp claim format while maintaining compatibility with the standard scope claim
JIRA: https://redhat.atlassian.net/browse/TC-3762
Summary by Sourcery
Add support for interpreting scopes from both standard OAuth 'scope' and Azure Entra ID 'scp' claims when validating access tokens.
New Features:
Tests: