Skip to content

Keycloak

Keycloak as the OIDC provider: a confidential client dark-factory and its client role board-member in a top-level roles claim of the ID token. How the login works and every control plane setting: Authentication.

1. Create the client

In the realm of your instance, Clients > Create client:

SettingValue
Client typeOpenID Connect
Client IDdark-factory (auth.clientId)
Client authenticationOn (confidential client)
Authentication flowStandard flow only; turn off direct access grants and implicit flow
Valid redirect URIshttps://<public host>/auth/callback
Valid post logout redirect URIshttps://<public host>/
Web originsempty

Under Advanced > Advanced settings set Proof Key for Code Exchange Code Challenge Method to S256.

Copy the secret from Credentials into a Kubernetes Secret in the instance namespace:

kubectl -n dark-factory create secret generic dark-factory-oidc \
  --from-literal=client-secret='<secret from Keycloak>'

2. Create the role and map it into the token

  1. Clients > dark-factory > Roles > Create role: name board-member. Assign it to the users (or a group) who may operate the factory.

  2. Clients > dark-factory > Client scopes > dark-factory-dedicated > Configure a new mapper > User Client Role:

    SettingValue
    Nameroles
    Client IDdark-factory
    MultivaluedOn
    Token Claim Nameroles (auth.rolesClaim)
    Claim JSON TypeString
    Add to ID tokenOn
    Add to access tokenoptional

    The default resource_access.dark-factory.roles claim is nested and is not read. The claim must be a top-level list, for example "roles": ["board-member"].

A role removed in Keycloak takes effect when the access token expires (default 5 minutes) and is refreshed.

Revoke Refresh Token (refresh token rotation) is supported: the control plane refreshes each session once, even when several requests arrive with an expired token at the same time.

3. Configure the control plane

Helm values (all settings: Control plane settings):

oidc:
  issuerUrl: https://id.example.org/realms/dark-factory
  clientId: dark-factory
  existingSecret: dark-factory-oidc
  clientSecretKey: client-secret
  publicUrl: https://factory.example.org
  rolesClaim: roles

Then check the login as in Verify.

Troubleshooting

SymptomCause
Invalid parameter: redirect_uri at KeycloakThe redirect URI does not match auth.publicUrl + /auth/callback.
403 for a user who has the roleThe mapper does not add the claim to the ID token, or auth.rolesClaim differs from Token Claim Name.
Login unavailable (502)The control plane cannot reach auth.issuerUrl; check the NetworkPolicy and the issuer URL.
Login failed (400)The login state does not match, e.g. the login page was opened in another browser or the cookie was blocked.
Logged out every few minutesThe refresh was refused: the Keycloak SSO session or refresh token expired, or the client lost Standard flow.