What this is about
Not every request comes from a human. Sometimes one server calls another: CIAS creates accounts in Keycloak, or CDMS asks CIAS whether a tenant may be served. For this, the server needs its own token, without anyone typing a password.
The standard way to do this is called Client Credentials. The server signs in at Keycloak with the ID and the secret of its client and gets an access token. In Keycloak, a client is the entry for a program.
The flow
sequenceDiagram
participant D as Service
participant K as Keycloak
participant A as API
D->>K: POST /token<br/>grant_type=client_credentials<br/>client_id, client_secret
K-->>D: access token of the service account
D->>A: request with Authorization: Bearer …
A-->>D: response
Note over D: keeps the token<br/>until shortly before it expires
There is no refresh token and no login screen. When the token expires, the service simply gets a new one.
The three cases at CodamAI
When: A server of your own project needs to call a CodamAI API.
-
1Client→Keycloakgets a token for its client with
client_credentials -
2Client→CDMScalls the API with
Authorization: Bearer <token> -
3CIASchecks the token like any other, see token check
-
4CDMSchecks the roles the service account has
Result: The API treats the service like a person with the name service-account-<client>.
When: CIAS creates accounts, grants roles, and manages groups and organizations.
-
1CIAS→Keycloaksigns in with the client
cias-adminviaclient_credentials -
2CIASkeeps the token and renews it 30 seconds before it expires
-
3CIAS→Keycloakcalls the admin API
Result: The client cias-admin can sign in only this way. Browser login is turned off for it. Settings are under codamai.cias.keycloak.* (client-id, client-secret).
When: CDMS runs separately from CIAS and must ask whether a tenant is served, or which attribute values a person has in the tenant.
-
1CDMS→CIAS
GET /cias/lookup/tenants/{key}orGET /cias/lookup/users/{id}/attributes?tenantKey=…, with a bearer token -
2CIASDoes the token have one of the roles that are allowed for the lookup?
-
3CIAS→CDMSresponds
Result: The service fetches the token from Keycloak itself, with the client ID and secret of its client (codamai.cias.tenancy.client.credentials), and renews it before it expires. Without a client it uses a fixed token from codamai.cias.tenancy.client.token, which does not refresh. lookup-roles sets which roles may ask. If the list is empty, the endpoint answers no one.
In embedded mode, when CDMS and CIAS run in one program, the lookup does not go over HTTP. CDMS then asks CIAS directly with a method call. See Embedded.
What a service token may do
For the APIs, a service account is a user like any other, just without a human behind it:
| Question | Answer |
|---|---|
| Who is the caller? | the service account, name service-account-<client> |
| Which roles does it have? | the roles assigned to its service account. No others |
| Which tenant does it work in? | same as for a person: from the token. If the tenant is missing in MULTI, the filter chain responds with 403 |
| What does it see in user models? | only rows that belong to it |