Your own Keycloak¶
Use this when your company already runs Keycloak for its people. Your Keycloak stays in front: it checks who the person is. MEHO's built-in Keycloak sends people to yours, gets back their groups, and puts each person into the matching MEHO group.
MEHO always ships its own Keycloak. You do not replace it with yours.
What stays where:
| On your side (your Keycloak) | On MEHO's side (realm meho) |
|---|---|
| Your people and your user directory | The five MEHO groups |
| Passwords, MFA, login checks | Tenant and role, from the MEHO group |
| Which of your groups may use MEHO | The tokens that MEHO accepts |
MEHO accepts only tokens from its own Keycloak. A token from your Keycloak does not work at MEHO directly.
On MEHO's side you set this up with Helm values
(coreKeycloak.companyLogin), not by hand in the Keycloak admin
console. The install sets it up again at every helm upgrade. The
page Company login with authentik
explains the same values in more detail.
Before you start:
- The realm is set up and the five MEHO groups exist. See Company login.
- You are an admin in your Keycloak.
- You know the address of your MEHO, for example
https://meho.example.com. MEHO's Keycloak is athttps://<meho-host>/auth.
The Helm values use the alias company by default. The alias is part
of the redirect URI:
https://<meho-host>/auth/realms/meho/broker/company/endpoint
1. Make the client in your Keycloak¶
In your Keycloak admin console, in the realm of your people: Clients → Create client.
| Setting | Value |
|---|---|
| Client type | OpenID Connect |
| Client ID | meho-broker |
| Client authentication | On |
| Authentication flow | Standard flow only. Turn off Direct access grants. |
| Valid redirect URIs | https://<meho-host>/auth/realms/meho/broker/company/endpoint |
Click Save. Then, on the client:
- Advanced → Proof Key for Code Exchange Code Challenge Method:
S256. - Credentials: copy the Client Secret.
-
Client scopes →
meho-broker-dedicated→ Configure a new mapper → Group Membership:Setting Value Name groupsToken Claim Name groupsFull group path Off Add to ID token On Add to access token On Add to userinfo On
The token now carries groups: a list of the person's group names,
without a leading /.
2. Make the groups in your Keycloak¶
Make one group per MEHO role you need. The names are yours to choose, for example:
| Your group | MEHO group |
|---|---|
meho-readers |
MEHO-Readers |
meho-operators |
MEHO-Operators |
meho-sa-operators |
MEHO-SA-Operators |
meho-admins |
MEHO-Admins |
meho-approvers |
MEHO-Approvers |
Put each person who may use MEHO in one of them. People in none of them cannot use MEHO.
3. Store the client secret¶
Put the secret from step 1 into a Kubernetes Secret in MEHO's namespace. The chart reads it by name and never prints it.
read -rs CLIENT_SECRET # paste the client secret; it is not shown
kubectl create secret generic meho-company-login -n meho \
--from-literal=client_secret="$CLIENT_SECRET"
unset CLIENT_SECRET
If a private CA signs your Keycloak's certificate, also store the CA
in a ConfigMap and set caBundle (see
Company login with authentik).
4. Add the Helm values¶
Add this to your values file, next to your other coreKeycloak
values:
coreKeycloak:
companyLogin:
enabled: true
alias: company
displayName: Company account
discoveryUrl: https://<your-keycloak>/realms/<your-realm>/.well-known/openid-configuration
clientId: meho-broker
clientSecret:
secretName: meho-company-login
secretKey: client_secret
scopes: openid profile email
groupsClaim: groups
groupMap: # your group -> MEHO group
meho-readers: MEHO-Readers
meho-operators: MEHO-Operators
meho-sa-operators: MEHO-SA-Operators
meho-admins: MEHO-Admins
meho-approvers: MEHO-Approvers
autoRedirect: false # true later: go straight to your Keycloak
groupMap: the left side is your group's name, the right side is the MEHO group. Only the groups you list here give access.autoRedirect: withtrue, MEHO's Keycloak sends everyone straight to yours and never shows its own password form. Start withfalse, so the first admin can still log in with a password. Switch totrueonce a person from your Keycloak is inMEHO-Admins.
Then run helm upgrade as in
Install or upgrade.
The install notes print the redirect URI. Check that it is the same as
the one in your client. If you turn the company login on for an
install that already exists, read the note in that section first.
The install sets up the login with PKCE (S256). It makes one group
rule per groupMap line. MEHO's Keycloak checks the groups at every
login: remove a person from your group, and MEHO's Keycloak removes
them from the MEHO group at their next login.
Your Keycloak needs one fixed address
MEHO's Keycloak checks that every token from your Keycloak names the
Issuer from the discovery endpoint. Your Keycloak must therefore
use one fixed public address (KC_HOSTNAME), the same one MEHO's
Keycloak reaches it on. If the address in the token changes with the
caller, the login fails with "Unexpected error when authenticating
with identity provider", and MEHO's Keycloak log says
Wrong issuer from token.
No extra form at the first login. At a person's first login,
Keycloak runs the First login flow (default first broker login).
With the default settings it shows no form, as long as your token
carries the person's email, first name and last name. Keep the scopes
openid profile email and fill those fields in your Keycloak. The
person keeps the username from your Keycloak.
Your Keycloak's own checks stay in place: its password policy, MFA and blocked accounts. They run when MEHO's Keycloak sends the person to yours.
The rules¶
- One MEHO group per person. Put each person in one of your MEHO
groups only. In two, MEHO refuses the login with
401 multiple_role_groups. - Never map your claims to
tenant_id,tenant_role,approverorplatform_admin. Only the MEHO group gives those. - Removal applies at the next login. Remove a person on your side, and their next login through your Keycloak is refused. MEHO's Keycloak reads your groups only at that login: a session the person already has with MEHO's Keycloak keeps its group until it ends. To cut access at once, also end their sessions in MEHO's Keycloak (Users → the person → Sessions → Sign out).
- MEHO accepts only tokens from its own Keycloak. A token issued by your Keycloak is refused.
Lab test¶
Use a test person from your Keycloak who is not an admin.
- [ ]
meho login https://<meho-host>works with the account from your Keycloak.meho statusshows the right tenant and role. - [ ] The web UI (
https://<meho-host>/ui/) logs in with the same account and shows the same role. - [ ] Claude (MCP) logs in through the browser and can call a MEHO tool that fits the role.
- [ ] Your Keycloak's MFA ran during the login.
- [ ] No profile form showed at the first login.
- [ ] Remove the person from your group. The next login is refused
with
401 missing_tenant_claim. - [ ] A token from your Keycloak itself, sent to MEHO, is refused with
401 invalid_token.
An automated test covers the Keycloak part of this recipe:
backend/tests/integration/test_keycloak_customer_idp_e2e.py. It does
not replace the lab test.
Followed by a colleague who did not write this recipe: name, date, result.