Captain-P-Goldfish / scim-for-keycloak

a third party module that extends keycloak by SCIM functionality
BSD 3-Clause "New" or "Revised" License
188 stars 48 forks source link

Specify which users to export via SCIM client #124

Open ReneBeszon opened 2 months ago

ReneBeszon commented 2 months ago

We have a realm that collects users from multiple IdPs. And I want / have to export a certain subset of them to a separate SCIM server. Is there a way to specify that only a subset of users, e.g. with a certain attribute, is exported?

As I do have control of the remote server I can just ignore them, but it doesn't seem right.

Captain-P-Goldfish commented 2 months ago

yes, there is. Please check the documentation: exclude-to-include

saz commented 2 months ago

I'm having the issue, that I'd like to filter users and groups based on the SCIM client, not per realm.

For example, for one SCIM provider, all users and groups are fine, for another, it should be a subset of them. But in both cases, I'm already excluding specific users (by using the exclude roles)

Captain-P-Goldfish commented 2 months ago

Sorry, but I got trouble following you here. Could you maybe explain this a little bit more in detail?

saz commented 2 months ago

Sure!

I've got approx 250 user accounts in keycloak. Let's say, I'd like to exclude 50 in general, I can make use of the exclude roles, which is working fine.

Within the same realm, I've got a scim client, which should only sync a small part of those users (because I would need to buy a license for each sychronized user).

And there's not only one such case, but a couple of them.

It would be great to have a way to configure an exclude role per scim client, instead of having one role only.

Captain-P-Goldfish commented 2 months ago
  1. Why would you need to buy a license for each synchronized user?
  2. You can only have 1 SCIM Client per realm. Multi-assignment is not possible.
saz commented 2 months ago
  1. It's the service provider, who's making up that rules, e.g. bitwarden.
  2. Maybe it's a misunderstanding on my side, but shouldn't it be possible to have multiple scim clients?
SCIM Client

The SCIM Client functionality synchronizes your users/groups with other identity providers supporting the SCIM protocol.
Captain-P-Goldfish commented 2 months ago
  1. It is possible to configure several SCIM Clients. But you can assign a SCIM Client only to a single realm in Keycloak. The SCIM-protocol is not designed for synchronization to multiple systems at once.
saz commented 2 months ago

Okay, now you lost me. Isn't SCIM designed to provision users from a directory to e.g. all those SaaS apps?

I'm talking about this part within the plugin image

saz commented 2 months ago

Let me phrase it differently: I'd like to have multiple SCIM Clients, each of them with a different set of users, limited by e.g. a role specific to a client.

For example: Bitwarden. I'd like to sync only those users with a role e.g. bitwarden-sync set

Another client, sentry. I'd like to sync all users, except of those with a role sentry-exclude set.

My understanding is, that it's technically possible to do that, but it's currently not implemented within the plugin.

Captain-P-Goldfish commented 2 months ago

I think there is a misunderstanding.

One If you have a realm in keycloak - lets call it my-test-realm - then you can assign only a single Remote SCIM Provider configuration from above to the realm my-test-realm And therefore, the realm-exclude-roles could be - more or less - considered to be assigned to the specific Remote SCIM Provider.

If you have several Remote SCIM Providers you must also have several realms to manage your users.

SCIM does define the attribute externalId that is used as the ID of the remote-system to which users can be synchronized. The protocol never defined a mechanism that allows to distinguishe between several remote-providers. So each user can only be synchronized to a single remote-system.

If that was not a misunderstanding, than I simply did not understand what you asked 😅

saz commented 2 months ago

It's hard for me to wrap my head around that. I thought externalId is meant to be provided by the SCIM client (keycloak, in this case) and identifies a user.

It seems weird to me to have a separate realm per SCIM client, as this will result in a duplication of entities: User A needs to access SaaS1 and SaaS2 and will therefore exists in two realms.

Thanks for the support, I guess I need to find something else then.

saz commented 2 months ago

Checking scim.cloud and the rfc, it seems as I'm right about the externalID being an identifier from the scim client.

I don't want to be annoying on this topic, but is the 1:1 mapping a limitation of keycloak, your plugin or some RFC I'm missing?

I've taken a look at a couple of other implementations (e.g. authentik) and as far as I can see there's no such limitation. I'm just trying to have all details, before reconsidering using keycloak.

Captain-P-Goldfish commented 2 months ago

Yes, the externalId is an identifier that is used by the SCIM Client. It is the id of the resource on the remote server, not the keycloak resource id.

the 1:1 mapping is a limitation by SCIM. I originally even started implementing it in a way that synchronization to several servers could be possible until I noticed that the RFC is not covering this, and therefore I rolled this part back and stayed on a 1:1 relationship.

Or maybe you are talking about a completely different thing. I couldn't follow your details from above, why I can only guess what you are trying to do.

saz commented 2 months ago

The externalID is defined by the scim client (keycloak or your plugin) not the CSP (e.g. bitwarden). Otherwise, it won't be possible to have an externalID set while creating a user in the CSP. It uniquely identifies an identity within keycloak and must be unique within keycloak only.

The idea behind SCIM is to sync users and groups from one directory to multiple CSPs.

What's not covered by the current spec is, if you have one CSP with multiple clients.

There are examples in RFC 7642 3.2 and 3.3 covering this scenario.

Keycloak with your plugin is supposed to push changes to all configured CSPs, working as an SCIM client.

All I know about SCIM, I'm not able to find a reason, why it should be a 1:1 relation.

Just to be sure: from your plugin perspective, there's only one server per realm possible, which is totally expected. But for the client part, the 1:1 relation isn't expected. Making it possible to have multiple clients per realm, will make this plugin really useful. This would be the same behavior as others (authentik, okta,...) have implemented it.

Captain-P-Goldfish commented 2 months ago

On technical level it is not possible to synchronize a single user to several clients. Reason:

saz commented 2 months ago

This information isn't correct. Please see the description of id and externalId in the Common Attributes section of RFC7643.

saz commented 2 months ago

Even if you want to store the remote id, this would just require a table with service_provider_id, service_provider_uid and keycloak_uid to get a proper mapping, as this is only required within your plugin to overcome the current limitation.

Edit: it also might need a realm id to avoid duplicates between different realms. A unique together over those fields should make it easy to handle potential duplicates.

Captain-P-Goldfish commented 2 months ago

okay, I won't object anymore. But this will currently not be implemented. There is a lot of code that currently depends on the current mechanism making it difficult to rebuild. I will maybe do it in a later development iteration but this is nothing that I can do in the next time since this is a greater change.

saz commented 2 months ago

:+1: I'd be happy to see this in the future, if possible. :)

For anybody reading through all comments (and it might also help you), there's another plugin https://github.com/mitodl/keycloak-scim which is capable of acting as multiple SCIM clients, but, as far as I can see, there's no filtering implemented :(