Skip to content

Commit 583330e

Browse files
authored
docs: Add OIDC Group Synchronization documentation for Keycloak (#426)
* docs: Add OIDC Group Synchronization documentation for Keycloak Add comprehensive documentation for the new OIDC group sync feature: - Overview and prerequisites - Configuration examples for realm roles, client roles, and groups - Step-by-step setup instructions - Troubleshooting guide with common claim paths - Usage examples for permissions - Limitations and best practices Covers integration with LibreChat's granular permissions system for agents, prompts, files, and conversations. Related to LibreChat PR and issue #10006 * docs: Add group/role exclusion pattern documentation Document OPENID_GROUPS_EXCLUDE_PATTERN configuration option: - Explain exact match (case-insensitive) and regex pattern support - Provide common Keycloak exclusion examples - Show why to exclude system roles, default roles, and auth roles - Add practical scenario with admin/developers vs system roles - Include configuration examples for filtering out: - offline_access, uma_authorization (system roles) - default-roles-* (default realm roles) - manage-account, view-profile (account management) Complements the group sync feature by allowing fine-grained control over which roles become groups in LibreChat.
1 parent 4646ecc commit 583330e

File tree

1 file changed

+197
-0
lines changed
  • pages/docs/configuration/authentication/OAuth2-OIDC

1 file changed

+197
-0
lines changed

pages/docs/configuration/authentication/OAuth2-OIDC/keycloak.mdx

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,200 @@ If you want to restrict access to users with specific roles, you can define role
6969
# Optional: redirects the user to the end session endpoint after logging out
7070
OPENID_USE_END_SESSION_ENDPOINT=true
7171
```
72+
73+
---
74+
75+
## OIDC Group Synchronization
76+
77+
<Callout type="info" title="Automatic Group Sync">
78+
LibreChat can automatically synchronize Keycloak roles/groups to enable granular permissions for agents, prompts, files, and conversations. This feature requires **token reuse** to be enabled.
79+
</Callout>
80+
81+
### Overview
82+
83+
The OIDC Group Synchronization feature allows LibreChat to:
84+
- Automatically extract groups/roles from JWT token claims
85+
- Create groups in LibreChat's database
86+
- Sync user memberships on every login
87+
- Enable ACL-based permissions for shared resources
88+
- Support any OIDC provider (Keycloak, Auth0, Okta, etc.)
89+
90+
### Prerequisites
91+
92+
- `OPENID_REUSE_TOKENS=true` must be enabled (see [Token Reuse documentation](/docs/configuration/authentication/OAuth2-OIDC/token-reuse))
93+
- Keycloak realm roles or groups configured
94+
- Users assigned to roles/groups in Keycloak
95+
96+
### Configuration
97+
98+
Add the following variables to your `.env` file:
99+
100+
```bash filename=".env"
101+
# Required: Enable token reuse (prerequisite)
102+
OPENID_REUSE_TOKENS=true
103+
104+
# Enable OIDC group synchronization
105+
OPENID_SYNC_GROUPS_FROM_TOKEN=true
106+
107+
# Path to groups/roles in JWT token (dot notation)
108+
# For Keycloak realm roles:
109+
OPENID_GROUPS_CLAIM_PATH=realm_access.roles
110+
111+
# For Keycloak client roles:
112+
# OPENID_GROUPS_CLAIM_PATH=resource_access.librechat.roles
113+
114+
# For Keycloak groups (requires group mapper):
115+
# OPENID_GROUPS_CLAIM_PATH=groups
116+
117+
# Which token to extract groups from
118+
OPENID_GROUPS_TOKEN_KIND=access # or 'id'
119+
120+
# Source identifier for synced groups (optional)
121+
OPENID_GROUP_SOURCE=keycloak # default: 'oidc'
122+
123+
# Exclude specific roles/groups from sync (optional)
124+
# Comma-separated list: exact names or regex patterns (prefix with 'regex:')
125+
OPENID_GROUPS_EXCLUDE_PATTERN=default-roles-mediawan,manage-account,offline_access,regex:^view-.*
126+
```
127+
128+
### Filtering Roles/Groups (Exclusion Pattern)
129+
130+
<Callout type="tip" title="Filter System Roles">
131+
Use `OPENID_GROUPS_EXCLUDE_PATTERN` to prevent system roles, default roles, and authentication-only roles from being synced as groups.
132+
</Callout>
133+
134+
The exclusion pattern supports two types of matching:
135+
136+
**1. Exact Match (case-insensitive):**
137+
```bash
138+
OPENID_GROUPS_EXCLUDE_PATTERN=default-roles-mediawan,manage-account,view-profile
139+
```
140+
Excludes roles with exact names: `default-roles-mediawan`, `manage-account`, `view-profile`
141+
142+
**2. Regex Pattern (prefix with `regex:`):**
143+
```bash
144+
OPENID_GROUPS_EXCLUDE_PATTERN=regex:^default-.*,regex:^manage-.*
145+
```
146+
- `regex:^default-.*` - Excludes anything starting with "default-"
147+
- `regex:^manage-.*` - Excludes anything starting with "manage-"
148+
149+
**3. Mixed (recommended):**
150+
```bash
151+
OPENID_GROUPS_EXCLUDE_PATTERN=default-roles-mediawan,offline_access,uma_authorization,regex:^manage-.*,regex:^view-.*
152+
```
153+
154+
**Common Keycloak exclusions:**
155+
```bash
156+
# Exclude all system/default roles and account management
157+
OPENID_GROUPS_EXCLUDE_PATTERN=offline_access,uma_authorization,regex:^default-.*,regex:^manage-.*,regex:^view-.*
158+
```
159+
160+
**Why exclude roles?**
161+
- **System roles** (`offline_access`, `uma_authorization`) - Not relevant for resource permissions
162+
- **Default realm roles** (`default-roles-*`) - Assigned to everyone, not useful for group-based access
163+
- **Account management roles** (`manage-account`, `view-profile`) - Authentication-related, not business groups
164+
- **OPENID_REQUIRED_ROLE** - If you use a role for login authorization, you might not want it as a group
165+
166+
**Example scenario:**
167+
168+
Your Keycloak realm has roles:
169+
- `admin` ✅ (business role, sync as group)
170+
- `developers` ✅ (team role, sync as group)
171+
- `default-roles-mediawan` ❌ (everyone has this, exclude)
172+
- `manage-account` ❌ (system role, exclude)
173+
- `offline_access` ❌ (OAuth scope, exclude)
174+
175+
Configuration:
176+
```bash
177+
OPENID_GROUPS_EXCLUDE_PATTERN=default-roles-mediawan,manage-account,offline_access
178+
```
179+
180+
Result: Only `admin` and `developers` are synced as groups.
181+
182+
### How It Works
183+
184+
1. **User logs in** via Keycloak
185+
2. **Groups are extracted** from the JWT token based on `OPENID_GROUPS_CLAIM_PATH`
186+
3. **Groups are created** in LibreChat if they don't exist
187+
4. **User is added** to all extracted groups automatically
188+
5. **Removed from old groups** if roles were revoked in Keycloak
189+
6. **Groups are available** for sharing agents, prompts, conversations, and files
190+
191+
### Example: Using Realm Roles
192+
193+
If your Keycloak realm has roles like `admin`, `developers`, and `engineering`:
194+
195+
1. Users with these roles will automatically be added to corresponding groups in LibreChat
196+
2. You can share resources with these groups in the LibreChat UI
197+
3. Permissions are automatically synced on every login
198+
199+
### Example: Using Keycloak Groups
200+
201+
To use actual Keycloak groups instead of roles:
202+
203+
1. **Create a Group Membership mapper** in your Keycloak client:
204+
- Go to your client → Client Scopes → Select scope → Add Mapper
205+
- Choose "Group Membership"
206+
- Set Token Claim Name to `groups`
207+
- Enable "Full group path" if you want hierarchical groups
208+
209+
2. **Update configuration:**
210+
```bash filename=".env"
211+
OPENID_GROUPS_CLAIM_PATH=groups
212+
```
213+
214+
3. Groups like `/engineering/backend` will be synced as `engineering-backend` in LibreChat
215+
216+
### Viewing Synced Groups
217+
218+
After logging in, check your MongoDB database:
219+
220+
```bash
221+
mongosh librechat
222+
db.groups.find({ source: 'keycloak' })
223+
```
224+
225+
You should see groups with:
226+
- `name`: The role/group name
227+
- `source`: `keycloak` (or your configured `OPENID_GROUP_SOURCE`)
228+
- `memberIds`: Array of user IDs
229+
- `idOnTheSource`: The original role/group identifier
230+
231+
### Using Groups for Permissions
232+
233+
Once groups are synced, you can:
234+
235+
1. **Share Agents** - Assign specific groups to agents
236+
2. **Share Prompts** - Make prompts available to certain groups
237+
3. **Share Conversations** - Collaborate with team members in specific groups
238+
4. **Control File Access** - Restrict file visibility by group
239+
240+
All permissions are managed through the LibreChat UI's sharing interface.
241+
242+
### Troubleshooting
243+
244+
**Groups not syncing:**
245+
- Verify `OPENID_REUSE_TOKENS=true` is set
246+
- Check that users have roles/groups assigned in Keycloak
247+
- Verify `OPENID_GROUPS_CLAIM_PATH` matches your JWT token structure
248+
- Check backend logs for error messages
249+
250+
**To debug, decode your JWT token:**
251+
1. Login to LibreChat
252+
2. Get the access token from Keycloak
253+
3. Decode it at https://jwt.io
254+
4. Find where your roles/groups are located in the token structure
255+
5. Update `OPENID_GROUPS_CLAIM_PATH` accordingly
256+
257+
**Common claim paths:**
258+
- Keycloak realm roles: `realm_access.roles`
259+
- Keycloak client roles: `resource_access.{client-id}.roles`
260+
- Keycloak groups: `groups` (requires mapper)
261+
- Auth0 groups: `https://your-domain.auth0.com/groups`
262+
263+
### Limitations
264+
265+
- Groups are synchronized on login only (not real-time)
266+
- Group names are sanitized (special characters removed, slashes converted to hyphens)
267+
- Maximum 100 characters per group name
268+
- Requires OIDC provider to include groups/roles in JWT tokens

0 commit comments

Comments
 (0)