Skip to content

docs: clarify SSO claim source and Entra guest/app-role mapping#4958

Open
drernie wants to merge 3 commits into
masterfrom
docs-sso-claim-source-entra-groups
Open

docs: clarify SSO claim source and Entra guest/app-role mapping#4958
drernie wants to merge 3 commits into
masterfrom
docs-sso-claim-source-entra-groups

Conversation

@drernie

@drernie drernie commented Jun 9, 2026

Copy link
Copy Markdown
Member

Clarifies how Quilt reads OIDC claims for SSO permission mapping, and adds Entra guidance for guest / multi-tenant deployments where the groups claim does not populate.

What the docs didn't say

  • SSO mappings are validated against the decoded ID token only. Quilt does not read the access token, call the userinfo endpoint, or resolve OIDC distributed/overage claims (the _claim_sources pointer Entra emits past ~200 groups). If a value isn't in the ID token, a mapping can't match on it.
  • A mapping can match on any ID-token claim — not just email/groups. (Mappings are arbitrary JSON Schema validated against the whole token.)
  • For Entra B2B guest / multi-tenant sign-ins, the groups claim only carries the issuing tenant's groups, so a guest's home-tenant security groups are absent and group-based mappings silently fail to match.

Change

advanced-features/sso-permissions.md:

  • New "Which claims are matched" section: ID-token-only, no userinfo/overage resolution, and match-on-any-claim with a roles-claim example.
  • jwt.ms / QUILT_LOG_LEVEL=DEBUG tip for confirming what arrives in the token.

technical-reference.md (Entra setup):

  • Guest/multi-tenant caveat on the groups claim, with App roles (roles claim defined on the resource app) as the recommended alternative that populates for guests, plus a note on the group-overage limit.

Docs-only; no behavior change.

Greptile Summary

Documentation-only PR that clarifies how Quilt evaluates SSO permission mappings and adds Microsoft Entra guidance for guest/multi-tenant deployments.

  • sso-permissions.md: Adds a "Which claims are matched" section explaining that only the decoded ID token is inspected (no access-token, userinfo-endpoint, or overage-claim resolution), provides a roles-claim YAML example for Entra App roles, and adds a jwt.ms / QUILT_LOG_LEVEL=DEBUG debugging tip.
  • technical-reference.md: Inserts a blockquote under the Entra groups-claim step warning that B2B-guest sign-ins won't carry home-tenant groups, and recommends App roles as the alternative that populates for guests and avoids the ~200-group overage limit; cross-links to the new section above.

Confidence Score: 5/5

Safe to merge — documentation only, no code or behavior changes.

Both changed files are Markdown documentation. The new 'Which claims are matched' section is technically accurate (ID-token-only, no userinfo/overage resolution), the YAML example is well-formed and consistent with existing examples, the anchor cross-link resolves correctly, and the Entra B2B guest guidance accurately reflects how the groups and roles claims differ across tenant boundaries.

No files require special attention.

Important Files Changed

Filename Overview
docs/advanced-features/sso-permissions.md Adds 'Which claims are matched' section clarifying ID-token-only validation, app-roles YAML example, and jwt.ms/debug-log tip; no logic issues found.
docs/technical-reference.md Adds a blockquote caveat about B2B-guest group claim limitations and recommends App roles as an alternative; anchor link to new sso-permissions section is correct.

Sequence Diagram

sequenceDiagram
    participant User
    participant IdP as Identity Provider (Entra / Okta)
    participant Registry as Quilt Registry

    User->>IdP: Login (OIDC Authorization Code flow)
    IdP-->>User: Authorization code
    User->>Registry: Authorization code
    Registry->>IdP: Exchange code for tokens
    IdP-->>Registry: ID token + Access token
    Note over Registry: Only ID token is used for mapping
    Registry->>Registry: Decode ID token claims
    Registry->>Registry: Validate each mapping schema against claims
    Note over Registry: First match (or union if union_roles:true) wins
    Registry-->>User: Assign matching Quilt roles

    Note over IdP,Registry: Entra B2B guests: groups claim = issuing-tenant only
    Note over IdP,Registry: App roles (roles claim) populate for guests too
    Note over Registry: >~200 groups → Entra overage (_claim_sources) — NOT resolved
Loading

Reviews (1): Last reviewed commit: "docs: clarify SSO claim source and Entra..." | Re-trigger Greptile

SSO permission mappings are validated against the decoded ID token only —
Quilt does not read the access token, call userinfo, or resolve OIDC
distributed/overage claims (`_claim_sources`). Document this, and that a
mapping can match on any ID-token claim, not just `email`/`groups`.

Add Entra guidance for B2B guest / multi-tenant users, whose home-tenant
security groups are absent from the `groups` claim: use App roles (a `roles`
claim defined on the resource app) and map on `roles` instead. Also note the
group-overage limit. Include a jwt.ms / DEBUG-logging tip for confirming
which claims actually arrive.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 46.76%. Comparing base (11b84f9) to head (bf2674b).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4958      +/-   ##
==========================================
+ Coverage   46.50%   46.76%   +0.26%     
==========================================
  Files         832      837       +5     
  Lines       34090    34290     +200     
  Branches     5833     5892      +59     
==========================================
+ Hits        15854    16037     +183     
- Misses      16237    16253      +16     
- Partials     1999     2000       +1     
Flag Coverage Δ
api-python 93.14% <ø> (ø)
catalog 22.01% <ø> (+0.46%) ⬆️
lambda 96.69% <ø> (+0.05%) ⬆️
py-shared 98.02% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Group/role claims aren't pulled in via a scope — they must be emitted into
the ID token directly via the provider's token/claim configuration, or a
mapping has nothing to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Documentation-only update clarifying how Quilt evaluates SSO permission mappings against OIDC claims, with additional Microsoft Entra guidance for guest/multi-tenant scenarios where the groups claim may not contain expected groups.

Changes:

  • Documented that SSO permission mappings are matched against the decoded ID token claims (and not access token / userinfo / overage-resolution).
  • Added an example mapping using an Entra app-role roles claim plus tips for inspecting received claims.
  • Added Entra-specific guidance for B2B guest / multi-tenant deployments and linked to the new claims section.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
docs/technical-reference.md Adds Entra guest/multi-tenant caveat for groups and recommends app roles / roles claim as an alternative.
docs/advanced-features/sso-permissions.md Adds “Which claims are matched” section clarifying ID-token-only matching and provides a roles claim mapping example + debugging tip.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/advanced-features/sso-permissions.md
Copilot review: the roles-claim YAML fragment omitted the required
version and default_role keys, so copy-pasting it as-is fails schema
validation. Add both so the snippet validates standalone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@drernie

drernie commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

Thanks @Copilot — fixed in bf2674b. The app-role roles-claim example now includes the required version: "1.0" and default_role: ReadQuiltBucket, so it validates standalone against the linked schema rather than erroring on copy-paste.

@sir-sigurd sir-sigurd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things worth tightening before merge — both in the new guidance, neither a blocker.

Entra App-roles step — worth double-checking the exact portal path. The guest/multi-tenant note says to emit app roles "via Token configuration → Add a roles claim to the ID token." That step may not exist: Microsoft's optional-claims reference doesn't list roles among the addable optional claims, and the Token configuration blade only offers "Add optional claim" (a fixed list without roles) and "Add groups claim." Per the app-roles docs, once an app role is Enabled and the user/group is assigned, the roles claim is included in the ID token automatically — no token-configuration step. Could you verify in the portal? If it's automatic, suggest dropping the "Add a roles claim" instruction and just covering define → enable → assign.

QUILT_LOG_LEVEL=DEBUG tip isn't reachable on a managed stack. The debugging tip points readers at the registry's DEBUG logs, but the registry log level is hardcoded to INFO in the deployment template (no stack parameter to change it), and the mapping-match logs are all emitted at DEBUG — so on a standard deployment a customer can't surface them. Recommend dropping that sentence; the jwt.ms tip just above it works and is enough.

Reviewed against bf2674b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants