Files
member-console/docs/identity-provider-setup.md
T

5.0 KiB

title, audience, summary
title audience summary
Identity Provider Setup
admin
developer
Configure an OIDC identity provider (Keycloak-focused) so the console can authenticate users and assign the operator role.

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.go and operator_partials.go

How roles are extracted

The member console extracts roles from the access token by decoding the JWT payload and reading every claim location an identity provider might use to carry roles, rather than trusting only one:

  1. roles (top-level array)
  2. groups (top-level array)
  3. realm_access.roles (Keycloak realm roles)
  4. resource_access.<client-id>.roles (Keycloak client-scoped roles, read only for this app's configured client ID; roles belonging to other clients are never included)

The member console reads all four locations and merges their roles into one deduplicated list: a role that appears in more than one location is kept once, at the position where it first appears (the locations are read in the order listed above, and within a location, in the order the claim lists them). Because every location is read, a deployment can put operator-member in whichever claim its identity provider produces and the member console still recognizes it.

Keycloak setup

There are two ways to make the operator-member role visible in the access token:

  1. Go to Clients > member-console > Roles
  2. Create a role named operator-member
  3. Assign it to the desired user(s) under Users > (user) > Role Mappings > member-console
  4. Ensure there is a protocol mapper that emits client roles into a top-level roles claim 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 by the test stack's Keycloak seed (test/seed/keycloak/seed-keycloak.sh).

Option B: Realm role

  1. Go to Realm Roles
  2. Create a role named operator-member
  3. Assign it to the desired user(s)
  4. The role will appear in realm_access.roles in 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 four checked claim locations (roles, groups, realm_access.roles, or resource_access.<client-id>.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 Temporal Authorization Setup for the full Temporal permissions configuration.

Test Environment

The test stack's Keycloak seed (test/seed/keycloak/seed-keycloak.sh) pre-configures:

  • A member-console client with the operator-member client role defined
  • The admin user mapped to the operator-member role
  • 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.

Run app OIDC on a dedicated realm, not Keycloak's master admin realm. The member-facing "Identity and Access" link opens Keycloak's account console; on the master admin realm that console errors ("Something went wrong") because the minted token carries no aud: account claim. The test stack therefore creates and runs on a dedicated test realm, where the account console works out of the box — do the same in production. See status/issues.md.

Note: The first member-console start after a fresh docker compose up -d used to fail with a Temporal auth error. This is fixed — compose now gates Temporal on its database and Keycloak being healthy, and member-console retries the initial Temporal connection. See status/issues.md.