Seafile creates a new user every time via Keycloak

Hello, I have Seafile installed in Docker.
I also have Keycloak installed in Docker.
Authentication is configured via Seafile > Keycloak > Seafile.
Everything works, the redirect works, Keycloak authenticates, and redirects back to the application, but:
Seafile creates a new user every time. Has anyone encountered this? I’ve tried everything, including different scopes, manually changing UID → email in MySQL, etc., but nothing helps.
The correct scopes are coming through curl:
{“sub":“1d9cc62f-81ea-484d-af26-6839051066b9”,“email_verified”:true,“preferred_username”:"example@inbox.ru”,“given_name”:“”,“family_name”:“”,“email”:“exemple@inbox.ru”}

Meanwhile, Seafile continues to create users of this format:
1d9cc69f94ea583daf776839051066b9@auth.local

The current settings look like this:

#Keycloak
ENABLE_OAUTH = True
OAUTH_ACTIVATE_USER_AFTER_CREATION = True
OAUTH_CREATE_UNKNOWN_USER = True
OAUTH_ENABLE_INSECURE_TRANSPORT = True

OAUTH_CLIENT_ID = “seafile”
OAUTH_CLIENT_SECRET = “TOKEN”
OAUTH_REDIRECT_URL = https:// url seafile

OAUTH_PROVIDER_DOMAIN = https:// url keycloak
OAUTH_PROVIDER = https:// url keycloak

OAUTH_AUTHORIZATION_URL =https:// url keycloak/realms/“realm”/protocol/openid-connect/auth’
OAUTH_TOKEN_URL = https:// url keycloak/realms/“realm”/protocol/openid-connect/token’
OAUTH_USER_INFO_URL = ‘https:// url keycloak/realms/“realm”/protocol/openid-connect/userinfo’

OAUTH_SCOPE = [“openid”, “profile”, “email”]
OAUTH_ATTRIBUTE_MAP = {
“sub”: (False, “not used”),
“name”: (False, “full name”),
“email”: (True, “email”),
}

etc., only the display of, for example, the uid on the email changes, but users are created anew each time.

The first user is the local admin, the rest are created via Keycloak.

Any ideas?

It appears the issue is related to how Seafile 11.0+ handles user identification via OAuth. Since version 11.0, Seafile uses Virtual User IDs (the [unique_id]@auth.local format you are seeing) and requires a specific mapping for the unique identifier to recognize existing users.

In your current configuration, you have mapped the Keycloak sub claim to "not used". This prevents Seafile from finding the existing entry in the social_auth_usersocialauth database table, leading it to treat every login as a new user.

Recommended Fix

You need to update your OAUTH_ATTRIBUTE_MAP in seahub_settings.py to map Keycloak’s unique ID (sub) to Seafile’s uid field.

Please update your settings to the following:

OAUTH_ATTRIBUTE_MAP = {   
   "sub": (True, "uid"),           # Map Keycloak unique ID to Seafile UID    
   "email": (False, "contact_email"),    
   "name": (False, "name"),
}

Why this happens:

  • UID Mapping: Setting sub to (True, "uid") ensures Seafile uses the stable Keycloak ID to look up your account.
  • Virtual IDs: Seafile generates internal IDs for social users. Once the uid mapping is correct, Seafile will consistently map that specific Keycloak sub to the same internal virtual ID instead of generating a new one each time.

Note on Existing Users:

If you have already manually modified the MySQL tables or have many duplicate accounts, you may need to clear the incorrect entries in the social_auth_usersocialauth table so that Seafile can create a fresh, correct association upon the next login.

I tried this too, and unfortunately, it didn’t help. I don’t rule out that I might have some incorrect settings on Keycloak, although all other services have no issues. Do you have any documentation on setting up Keycloak, because I’m out of ideas?
I set the values ​​as you mentioned in your message, but it didn’t help; several different users were still created.

Today I barely found time to dig around. I created a “test” user from Keycloak for this user. It’s the same sub every time.
{“sub”:“6a8fc506-d433-45e7-ad54-8f51e79a965f”,“email_verified”:true,“name”:“test testov",“preferred_username”:"test@test.com”,“given_name”:“test”,“family_name”:“testov”,“email”:“test@test.com”}
But Seafile stubbornly keeps creating new UIDs.

It accepts email and usernames fine, but something weird is happening with the UID.

The settings are yours, so what else can I do?

OAUTH_SCOPE = [“openid”, “profile”, “email”]
OAUTH_ATTRIBUTE_MAP = {
“sub”: (True, “uid”), # Map Keycloak unique ID to Seafile UID
“email”: (False, “contact_email”),
“name”: (False, “name”),
}

Can you check the content of social_auth_usersocialauth table?