Repository navigation
feat: implement scim and oidc integration - #2674
Merged
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
cristianscheid
force-pushed
the
feat/1861/scim-oidc-integration
branch
from
July 24, 2026 14:30
af7cec3 to
3eb9581
Compare
cristianscheid
force-pushed
the
feat/1861/scim-oidc-integration
branch
2 times, most recently
from
August 7, 2026 11:42
2727221 to
bd9972c
Compare
cristianscheid
marked this pull request as ready for review
August 7, 2026 13:16
cristianscheid
requested review from
ArtificialOwl and
provokateurin
as code owners
August 7, 2026 13:16
cristianscheid
force-pushed
the
feat/1861/scim-oidc-integration
branch
13 times, most recently
from
August 9, 2026 15:52
a82249a to
33d6170
Compare
CarlSchwan
reviewed
Aug 10, 2026
cristianscheid
force-pushed
the
feat/1861/scim-oidc-integration
branch
from
August 10, 2026 15:24
33d6170 to
6ddcf96
Compare
Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
…ge CFG_THIRD_PARTY to CFG_SCIM Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
…dency Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
Signed-off-by: Cristian Scheid <cristianscheid@gmail.com>
cristianscheid
force-pushed
the
feat/1861/scim-oidc-integration
branch
from
August 11, 2026 10:33
6ddcf96 to
1b702ec
Compare
Member
Author
|
/compile |
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
artonge
approved these changes
Aug 11, 2026
This was referenced Aug 19, 2026
|
Hello, a few questions:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implement support for SCIM and OIDC integration.
This is the first iteration of development of this feature, and covers the following scenarios:
Single instance environment:
Federated environment:
Configurations
On the instance running SCIM integration (master, in a federated setup, or the single instance otherwise):
On the instance(s) running OIDC integration (slaves or local, in a federated setup, or the single instance otherwise):
In a federated setup, on the instance running SCIM, set the list of remote instances whose federation agent is trusted as a moderator on this instance's SCIM circles:
occ config:app:set circles scim_federated_moderator_instances --type=array --value='["instance-two","instance-three"]'On each slave, enable its own federation agent, so it can act as moderator on the master's SCIM circles:
How a circle representing a SCIM group is identified across instances
If the instance running SCIM creates a circle from a SCIM group, how does an instance running OIDC know which circle corresponds to a membership fetched from OIDC?
A new method,
TStringTools::generateCircleIdFromString(), generates a circle ID (hash) from a string. Unliketoken()(also in this trait), which generates a hash randomly, this method always returns the same generated value for the same input.This means:
urn:geant:company.co:group:my_group#login.company.co) and generates a circle ID from it when creating the circleNew circle config flag
A new circle config flag,
Circle::CFG_SCIM, was introduced to mark circles managed by a SCIM server. Every circle created from a SCIM group gets this flag, andCircleRequest::getScim()fetches all of them.How groups from SCIM are synced
On the instance running SCIM, a request is made to the SCIM server to retrieve groups. For each group, a circle ID is generated (using
TStringTools::generateCircleIdFromString(), as mentioned above), and a circle is created with theCircle::CFG_SCIMflag, if it doesn't exist yet.It's also checked whether any existing SCIM circle no longer has a corresponding group on the SCIM server, and it's destroyed accordingly.
Triggered via:
occ circles:scim:sync-circlesOCA\Circles\BackgroundJob\ScimSyncCirclesThe federation agent
In a federated setup, for a slave to add its own users to a SCIM circle owned by another instance, two things are needed:
To solve this, a new entity was introduced: the
app:federation_agent:{singleId}circle. It represents an instance on federated/remote circles.On this specific SCIM/OIDC scenario, the slave's federation agent is added as a moderator on the master's SCIM circles. Once added, the slave knows those circles exist, and, having moderator rights, can add its own users to them.
It's meant to be a generic agent representing the instance, reusable by future features that might need an entity to act on remote circles, not just this SCIM/OIDC scenario.
It's created lazily, the first time
RemoteStreamService::getAppSignatory()runs, for example duringocc circles:remoteorocc circles:scim:sync-federated-moderators(more on this command below), and only iffederation_agent_enabledis set. Its singleId is included in the discovery payload already exchanged between trusted instances, so no extra endpoint or request is needed to look it up.On the instance running SCIM,
scim_federated_moderator_instanceslists which remote instances' federation agents are trusted as moderators on its SCIM circles, e.g.:For each configured instance, its federation agent's singleId is read from its (already cached, or freshly fetched if not yet known)
RemoteInstancerecord, and added as a moderator to every SCIM circle.Triggered via:
occ circles:scim:sync-federated-moderatorsOCA\Circles\BackgroundJob\ScimSyncFederatedModeratorsResolving the initiator
Whenever a member needs to be added to or removed from a circle,
OidcService::setInitiatorForCircle()resolves the correct initiator based on whether the circle is local or remote:Connecting with OIDC
On an instance running OIDC, a user can go to "Personal settings > Teams" and click "Connect" under "Connect to OIDC provider":
This redirects the user to the OIDC provider to authenticate. Once authenticated, the user is redirected back and their refresh token is stored.
How a user's memberships from OIDC are synced
On instances running OIDC, a request is made to the OIDC server for a given user, retrieving the group identifiers from the
oidc_membership_claim(e.g.entitlements). For each identifier, a circle ID is generated (usingTStringTools::generateCircleIdFromString(), as mentioned above), and the user is added to the corresponding SCIM circle.Memberships added this way are marked with
Member::setManagedBy('oidc'). This is also used to detect and remove memberships the user no longer has according to OIDC.A user's OIDC memberships are synced in any of the following situations:
occ circles:oidc:sync-membershipsOCA\Circles\BackgroundJob\OidcSyncMembershipsUserLoggedInlistener adds anOidcSyncMembershipsUserqueued jobOCC commands
circles:scim:sync-circlescircles:scim:sync-federated-moderatorscircles:oidc:sync-membershipsJobs
OCA\Circles\BackgroundJob\ScimSyncCirclesOCA\Circles\BackgroundJob\ScimSyncFederatedModeratorsOCA\Circles\BackgroundJob\OidcSyncMembershipsOCA\Circles\BackgroundJob\OidcSyncMembershipsUserUserLoggedInlistenerTODO
lib/Service/ScimService::fetchCircles()) still needs to be tested against a real SCIM server, and adjusted as needed once access is available.scim_federated_moderator_instances, there's no cleanup mechanism in place: its federation agent and any memberships it added remain on the SCIM circles.occcommand for adding/removing entries fromscim_federated_moderator_instancescould be a good place to trigger this cleanup.CFG_APP + CFG_SYSTEMinstead of the current config.lib/Service/FederationAgentService::ensureModerator(), if the federation agent is already a member but not a moderator, its level should be updated instead of being skipped.Checklist
3. to review, feature component)stable32)AI (if applicable)