3.8 KiB
Identity Provider Setup
This guide covers configuring your OIDC identity provider to work with the member console. The examples use Keycloak but the concepts apply to any OIDC-compliant provider.
Prerequisites
- An OIDC identity provider with a client configured for Authorization Code + PKCE flow
- The client ID and secret configured in
mc-config.yaml(or equivalent flags)
Standard OIDC Claims
The member console reads the following standard claims from the ID token:
| Claim | Used for |
|---|---|
sub |
Unique user identifier (OIDC subject) |
email |
User's primary email |
email_verified |
Whether the email is verified |
name |
Display name |
preferred_username |
Username (used for org slug derivation) |
On first login, the member console auto-provisions a person, organization, and workspace from these claims.
Role-Based Access: Operator Role
The member console uses a single application-level role to gate access to the operator panel:
- Role name:
operator-member - Where it's checked:
internal/server/operator.goandoperator_partials.go
How roles are extracted
The member console extracts roles from the access token by decoding the JWT payload and checking these claim locations in order:
roles(top-level array) — used if presentgroups(top-level array) — fallbackrealm_access.roles(Keycloak realm roles) — final fallback
The first non-empty source wins.
Known limitation: The code does not currently check
resource_access.<client-id>.roles, which is where Keycloak stores client-specific role assignments. This is tracked as a future improvement to maximize compatibility across identity providers. Seestatus/notes.md.
Keycloak setup
There are two ways to make the operator-member role visible in the access token:
Option A: Client role with a protocol mapper (recommended)
- Go to Clients > member-console > Roles
- Create a role named
operator-member - Assign it to the desired user(s) under Users > (user) > Role Mappings > member-console
- Ensure there is a protocol mapper that emits client roles into a top-level
rolesclaim in the access token:- Mapper type: User Client Role
- Client ID:
member-console - Token Claim Name:
roles - Claim JSON Type: String
- Multivalued: On
- Add to access token: On
This is the approach used in the test realm (test/data/keycloak/master-realm.json).
Option B: Realm role
- Go to Realm Roles
- Create a role named
operator-member - Assign it to the desired user(s)
- The role will appear in
realm_access.rolesin the access token by default
This is simpler but mixes application roles with realm-level roles.
Other identity providers
For providers other than Keycloak, ensure that the access token includes operator-member in one of the three checked claim locations (roles, groups, or realm_access.roles). Most providers support custom claims or group mappings that can achieve this.
Temporal Authorization
Temporal requires its own role setup for JWT-based authorization. See Keycloak-setup.md in the project root for the full Temporal permissions configuration.
Test Environment
The test Keycloak realm (test/data/keycloak/master-realm.json) comes pre-configured with:
- A
member-consoleclient with theoperator-memberclient role defined - The admin user mapped to the
operator-memberrole - Protocol mappers that emit roles into the access token
To use the test environment:
cd test
docker compose up -d
member-console start
Login with admin / admin at http://localhost:8081.
Note: The first
member-console startafter a freshdocker compose up -dmay fail with a Temporal auth error. Just run it again — seestatus/notes.mdfor details.