This commit is contained in:
DrMelone
2026-02-13 22:27:30 +01:00
parent ada4cd0871
commit c3649b13c0
3 changed files with 69 additions and 3 deletions

View File

@@ -25,6 +25,7 @@ Configure SCIM by setting these environment variables:
- **`SCIM_ENABLED`**: Set to `true` to enable SCIM support (default: `false`)
- **`SCIM_TOKEN`**: The bearer token for SCIM authentication (required when SCIM is enabled)
- **`SCIM_AUTH_PROVIDER`**: The OAuth provider name to associate with SCIM `externalId` values (e.g., `microsoft`, `oidc`). Required for `externalId` storage and account linking.
:::warning
@@ -46,6 +47,9 @@ export SCIM_ENABLED=true
# Set a secure token (replace with your own generated token)
export SCIM_TOKEN="your-secure-token-here"
# Set the OAuth provider name for externalId linking
export SCIM_AUTH_PROVIDER="microsoft"
```
## SCIM API Configuration
@@ -88,9 +92,9 @@ Open WebUI's SCIM implementation supports the following operations:
- `userName`: The user's email address (required, unique)
- `name.givenName`: First name
- `name.familyName`: Last name
- `emails`: Email addresses
- `emails`: Email addresses (when multiple are provided, the entry marked `primary: true` is used)
- `active`: User status (active/inactive)
- `externalId`: External identifier from the identity provider
- `externalId`: External identifier from the identity provider (stored per-provider in the user's `scim` JSON field, see [externalId and Account Linking](#externalid-and-account-linking))
#### Group Attributes
- `displayName`: Group name (required)
@@ -103,6 +107,7 @@ The SCIM API supports filtering for both users and groups:
```
GET /api/v1/scim/v2/Users?filter=userName eq "user@example.com"
GET /api/v1/scim/v2/Users?filter=externalId eq "abc-123"
GET /api/v1/scim/v2/Groups?filter=displayName eq "Engineering"
```
@@ -118,6 +123,29 @@ Supported filter operators:
- `lt`: Less than
- `le`: Less than or equal
## externalId and Account Linking
When `SCIM_AUTH_PROVIDER` is configured, Open WebUI stores `externalId` values in a per-provider structure within the user's `scim` JSON field:
```json
{
"microsoft": { "external_id": "abc-123" },
"okta": { "external_id": "def-456" }
}
```
This enables several behaviors:
- **User lookup by externalId**: When an identity provider sends a `filter=externalId eq "..."` request, Open WebUI searches the `scim` field for a matching entry under the configured provider.
- **OAuth fallback**: If no user is found by `externalId`, Open WebUI falls back to matching against OAuth `sub` values, automatically linking SCIM-provisioned accounts with existing OAuth-authenticated users.
- **Create and update**: When creating or updating users via SCIM, the `externalId` is stored in the `scim` field and returned in subsequent responses.
:::warning
If `SCIM_AUTH_PROVIDER` is not set while SCIM is enabled, any operation that requires `externalId` (creation, lookup, or update) will return a `500` error. A warning is also logged on startup to alert you.
:::
## Troubleshooting
### Common Issues
@@ -133,7 +161,10 @@ Supported filter operators:
3. **User Creation Failures**
- Ensure the `userName` field contains a valid email address
- Check that the email is not already in use
- Check that the email or `externalId` is not already in use
4. **500 Error on externalId Operations**
- Verify that `SCIM_AUTH_PROVIDER` is set to the correct OAuth provider name
### Testing SCIM Endpoints
@@ -156,6 +187,7 @@ curl -X POST \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "test@example.com",
"externalId": "idp-user-id-123",
"displayName": "Test User",
"name": {
"givenName": "Test",

View File

@@ -5090,6 +5090,12 @@ This is useful when you need a JWT access token for downstream validation or whe
- Description: Sets the bearer token for SCIM authentication. This token must be provided by identity providers when making SCIM API requests. Generate a secure random token (e.g., using `openssl rand -base64 32`) and configure it in both Open WebUI and your identity provider.
- Persistence: This environment variable is a `PersistentConfig` variable.
#### `SCIM_AUTH_PROVIDER`
- Type: `str`
- Default: `""`
- Description: Specifies the OAuth provider name to associate with SCIM `externalId` values (e.g., `microsoft`, `oidc`). When set, SCIM operations store and look up `externalId` under this provider key in the user's `scim` JSON field, enabling account linking between SCIM-provisioned identities and OAuth logins. A warning is logged on startup if SCIM is enabled but this variable is not set.
## User Permissions
### Chat Permissions

View File

@@ -553,6 +553,33 @@ Things to know about the tag table:
| settings | JSON | nullable | User preferences |
| info | JSON | nullable | Additional user info |
| oauth_sub | Text | UNIQUE | OAuth subject identifier |
| scim | JSON | nullable | SCIM provisioning data |
Things to know about the user table:
- Uses UUID for primary key
- One-to-One relationship with `auth` table (shared id)
- One-to-One relationship with `oauth_session` table (via `user_id` foreign key)
The `scim` field's expected structure:
```python
{
"<provider>": {
"external_id": string, # externalId from the identity provider
},
# Multiple providers can be stored simultaneously
# Example:
# "microsoft": { "external_id": "abc-123" },
# "okta": { "external_id": "def-456" }
}
```
**Why this column was added:**
- **SCIM account linking**: Stores per-provider `externalId` values from SCIM provisioning, enabling identity providers (like Azure AD, Okta) to match users by their external identifiers rather than relying solely on email.
- **Multi-provider support**: The per-provider key structure allows a single user to be provisioned from multiple identity providers simultaneously, each storing their own `externalId`.
- **OAuth fallback**: When looking up a user by `externalId`, the system falls back to matching against `oauth_sub` if no `scim` entry is found, enabling seamless linking of SCIM-provisioned and OAuth-authenticated accounts.
## Entity Relationship Diagram
@@ -604,6 +631,7 @@ erDiagram
json settings
json info
text oauth_sub
json scim
}
auth {