Skip to content

feat(scim): add source storage and provisioning contracts - #43725

Open
joshua-berri wants to merge 15 commits into
litellm_agent_split_budgetsfrom
litellm_agent_split_scim_contracts
Open

joshua-berri wants to merge 15 commits into
litellm_agent_split_budgetsfrom
litellm_agent_split_scim_contracts

Conversation

@joshua-berri

@joshua-berri joshua-berri commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

TLDR

Problem this solves:

  • SCIM provisioning needs durable source and resource contracts

How it solves it:

  • Add source storage, migrations and provisioning types

Adds the SCIM source/resource migration, request contracts and source configuration building blocks. Source-bound public provisioning is activated in PR8, not by this prerequisite

Stack 6/9. Depends on #43724, targeting litellm_agent_split_budgets. Current head f8fac3e6659c9f2007c7f5fa8aedce2163ba7daf; parent boundary 7a1343178ebf0f5601821b641300a8b201a7cd03. Own diff: +721/-0 across 12 files

User Flow

Before: the immediate parent provides the following experience

  1. Open https://litellm-domain/ui/ and navigate to SCIM
  2. Use the existing SCIM settings

After: this PR provides the following experience

  1. Open https://litellm-domain/ui/ and navigate to SCIM
  2. Use the existing settings; source dashboard controls arrive in PR9

Relevant issues

Splits the approved scope from #43230 into the smaller review stack below. The nine PRs collectively replace #43149, #43229, #43230 and #43459; this PR covers only the scope described above. Original PRs remain open pending replacement review

  1. feat(agents): add identity storage and validation contracts #43720
  2. feat(agents): enforce authoritative agent permissions #43721
  3. feat(agents): authenticate Entra identities and delegated requests #43722
  4. feat(agents): add identity registration and dashboard controls #43723
  5. feat(agents): enforce agent budgets #43724
  6. feat(scim): add source storage and provisioning contracts #43725
  7. feat(scim): add atomic agent and human provisioning operations #43726
  8. feat(scim): activate source-bound provisioning and authorization #43727
  9. feat(scim): add provisioning source dashboard controls #43728

Linear ticket

Fixes LIT-8961

Pre-Submission checklist

  • I have added meaningful tests
  • Full current-tip affected verification complete
  • My PR passes all required CI/CD checks
  • This PR isolates the stated part of the approved stack
  • Greptile confidence is at least4/5 before maintainer review

Verification

Restacked bottom-up after #43724 was rebased onto main c168199e33af584e33198714fd4bff716c866ae0. Old parent boundaries and backup refs were retained, and only this branch's own commits were replayed

Current head: f8fac3e6659c9f2007c7f5fa8aedce2163ba7daf. Immediate parent: 7a1343178ebf0f5601821b641300a8b201a7cd03. The preceding stack tip passed 2,281 backend and 59 dashboard tests. The preceding main restack passed 139 affected header/native/chat/version tests. The current restack carries the narrowly scoped chat model-pricing correction; its own current-tip readiness remains pending. This PR’s own patches are unchanged by range-diff. The financial fixes in #43724 remain inherited

Previous tip-specific CI, coverage, independent execution, and bot evidence is superseded. This PR still needs its own current-tip readiness checks before maintainer review

Screenshots / Proof of Fix

Fresh PR-specific before/after evidence remains pending for parent 7a1343178ebf0f5601821b641300a8b201a7cd03 and head f8fac3e6659c9f2007c7f5fa8aedce2163ba7daf. Previous screenshots and measured runs predate this rewrite and have been removed from the current proof section

Type

New Feature

Caveats (if any)

Medium

  • Full source-bound provisioning requires later activation PRs

Final Attestation

  • Final current-tip CI, coverage and automated review checks complete

Latest restack includes #43724 resolved admission, token pricing, and request compatibility repairs at 7a1343178ebf0f5601821b641300a8b201a7cd03. This PR’s own patches are unchanged by range-diff; tip-specific readiness remains pending

@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

[Critical risk] Adds database schema and provisioning API for SCIM identity sources.

The PR should not merge until source mappings accept the directory IDs that provisioning supports.

Findings

  1. P1 Opaque group IDs rejected ▶
  2. P2 Agent schema mismatch accepted ▶

Summary

This PR adds durable SCIM source and resource schemas, a migration, source-management building blocks, and agent-user request contracts.

  • The group-mapping contract excludes valid opaque directory IDs needed by stacked provisioning.
  • Agent extension validation permits a resource whose schema declaration disagrees with its body.

Reviews (1) · Last reviewed commit: "feat(agents): scim source storage and co..."

class SCIMGroupMapping(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")

external_group_id: UUID

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.

P1 Opaque group IDs rejected
SCIM groups can have non-UUID external IDs, but this field requires a UUID. If a directory group uses an ID such as engineering, an administrator cannot save its access-group mapping. Agents in that group then receive no mapped entitlement.

Comment on lines +126 to +130
@model_validator(mode="after")
def validate_agent_extension(self) -> "SCIMUser":
if SCIM_AGENT_USER_SCHEMA in self.schemas and self.agent_user is None:
raise ValueError("The agent-user schema requires identityParentId")
return self

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.

P2 Agent schema mismatch accepted
A user payload can include the agent extension without declaring its schema in schemas. Provisioning treats it as an agent, but later SCIM reads retain the inconsistent schema declaration. This can confuse directory clients about what kind of user they received.

Suggested change
@model_validator(mode="after")
def validate_agent_extension(self) -> "SCIMUser":
if SCIM_AGENT_USER_SCHEMA in self.schemas and self.agent_user is None:
raise ValueError("The agent-user schema requires identityParentId")
return self
@model_validator(mode="after")
def validate_agent_extension(self) -> "SCIMUser":
if SCIM_AGENT_USER_SCHEMA in self.schemas and self.agent_user is None:
raise ValueError("The agent-user schema requires identityParentId")
if self.agent_user is not None and SCIM_AGENT_USER_SCHEMA not in self.schemas:
raise ValueError("The agent-user extension requires its schema in schemas")
return self

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@codecov

codecov Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@joshua-berri
joshua-berri force-pushed the litellm_agent_split_budgets branch from 67a4f68 to 8f6d78d Compare September 30, 2026 23:28
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from 80e8682 to 01d81a2 Compare September 30, 2026 23:32
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from 01d81a2 to cf1cb69 Compare September 30, 2026 23:57
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from cf1cb69 to 47510ae Compare October 1, 2026 00:39
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from 47510ae to 2706ed0 Compare October 1, 2026 01:46
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from 2706ed0 to 4611985 Compare October 1, 2026 01:59
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from 4611985 to e02ac4e Compare October 1, 2026 02:18
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_budgets branch from 3453468 to 7409ffa Compare October 1, 2026 02:33
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from e02ac4e to 74d17f8 Compare October 1, 2026 02:33
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_scim_contracts branch from 74d17f8 to f8fac3e Compare October 1, 2026 02:50
@joshua-berri
joshua-berri force-pushed the litellm_agent_split_budgets branch from 51cc903 to 9a5fb0c Compare October 1, 2026 20:03

This branch is waiting to be deployed

1 waiting deployment
e2e-changed — f8fac3e6 Waiting Oct 1, 2026 by joshua-berri via oauth #2251
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.

1 participant