Skip to content

fix(scim): Add scimType and status to SCIM error responses#117869

Closed
Asynchronite wants to merge 2 commits into
getsentry:masterfrom
Asynchronite:fix/sentry-scim-attributes
Closed

fix(scim): Add scimType and status to SCIM error responses#117869
Asynchronite wants to merge 2 commits into
getsentry:masterfrom
Asynchronite:fix/sentry-scim-attributes

Conversation

@Asynchronite

Copy link
Copy Markdown
Contributor

Summary

Sentry's SCIM error responses were missing two members that RFC 7644
§3.12
requires:

  • status — the HTTP status code, as a string, on every SCIM error body.
  • scimType"uniqueness" for unique-attribute collisions.

Why this matters

When an IdP provisions a user whose email already exists in the org, Sentry
correctly returns 409, but the body omits scimType: "uniqueness". Spec-
compliant IdPs (e.g. Microsoft Entra) rely on that value to recognize "this user
already exists" and fall back from POST to PATCH/PUT against the existing
record. Without it, the operation hard-fails. This is the normal initial-sync
path: any org that had SAML2 SSO before enabling SCIM already has members (via
JIT or manual invite), so the IdP's first pass POSTs users that already exist.

Before

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
  "detail": "User already exists in the database."
}

After

{
  "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"],
  "scimType": "uniqueness",
  "status": "409",
  "detail": "User already exists in the database."
}

Changes

  • Add status (string) in the shared SCIMApiError builder and the static SCIM
    error constants, so all SCIM error responses are compliant.
  • Set scimType: "uniqueness" on both unique-attribute 409 paths: duplicate
    user (member create) and duplicate team/group slug (team create).
  • The team-create duplicate path previously returned a non-SCIM body (no schema
    URN); it now raises SCIMApiError for a proper SCIM error envelope.

Additive only: the 409 status code, detail text, and schema URN are
unchanged, so existing clients are unaffected.

Tests

  • Updated the SCIM member/team endpoint tests to assert the new scimType /
    status fields on the uniqueness cases.
  • Added a regression test confirming non-uniqueness SCIM errors still return
    valid bodies that include a string status (and no spurious scimType).

Legal Boilerplate

Look, I get it. The entity doing business as "Sentry" was incorporated in the State of Delaware in 2015 as Functional Software, Inc. and is gonna need some rights from me in order to utilize my contributions in this here PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Sentry can use, modify, copy, and redistribute my contributions, under Sentry's choice of terms.

SCIM error bodies were missing two members RFC 7644 §3.12 requires:
`status` (the HTTP status code as a string) on every error, and
`scimType` on uniqueness collisions. Without `scimType: "uniqueness"`,
spec-compliant IdPs (e.g. Microsoft Entra) can't recognize a 409 as a
duplicate and fall back from POST to PATCH/PUT, so initial-sync of
members that already exist (via SAML JIT or manual invite) hard-fails.

Add `status` in the shared SCIMApiError builder and the static SCIM
error constants so all SCIM error responses are compliant, and set
`scimType: "uniqueness"` on the duplicate-user (409) and duplicate
team/group slug (409) paths. The team-create duplicate path previously
returned a non-SCIM body with no schema URN; it now raises SCIMApiError
for a proper error envelope.

Additive only: the 409 status code, detail text, and schema URN are
unchanged.
@Asynchronite Asynchronite requested a review from a team as a code owner June 16, 2026 21:55
@github-actions github-actions Bot added the Scope: Backend Automatically applied to PRs that change backend components label Jun 16, 2026
@Asynchronite

Copy link
Copy Markdown
Contributor Author

Holy shit this is just a few thousand commits behind, might wanna update this rq..

@Asynchronite

Copy link
Copy Markdown
Contributor Author

See #117870 for new PR.

@cursor cursor Bot 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 384842e. Configure here.

{
"non_field_errors": [CONFLICTING_SLUG_ERROR],
"detail": CONFLICTING_SLUG_ERROR,
},

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.

Snowflake retry errors tagged uniqueness

Medium Severity

Team SCIM create maps both IntegrityError and MaxSnowflakeRetryError to SCIMApiError with scim_type="uniqueness". Snowflake retry exhaustion is a transient ID allocation failure, not a duplicate slug, so IdPs may treat it as an existing group and run the wrong reconcile path.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 384842e. Configure here.

@Asynchronite Asynchronite deleted the fix/sentry-scim-attributes branch June 18, 2026 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant