Documentation
- Getting Started Configuration Operations
Single Sign-On
CDM has no user accounts of its own. It signs everyone in through your existing OpenID Connect identity provider, which is why three OIDC_* settings are required before it starts.
You need three values from your provider (the discovery URL, a client ID and its client secret), and one redirect URI registered on their side:
<CDM_PUBLIC_URL>/oidc
It has to match exactly, including http versus https and the port. For a first local test that is http://localhost:8234/oidc.
Worked example: authentik
1. Create the provider. Applications, Providers, Create, OAuth2/OpenID Provider.
| Field | Value |
|---|---|
| Name | CDM |
| Authorization flow | your usual one, for example default-provider-authorization-explicit-consent |
| Client type | Confidential |
| Client ID / Client Secret | authentik generates both; copy them |
| Redirect URIs | https://cdm.example.com/oidc, match set to Strict |
| Signing Key | pick your certificate, so the ID token is signed with RS256 |
| Scopes | leave authentik's defaults for openid, email and profile |
2. Create the application. Applications, Applications, Create. Name it croit Datacenter Manager, set the slug to cdm, and select the provider from step 1. The slug is what appears in the discovery URL.
3. Fill in CDM. The discovery URL follows the application slug:
OIDC_DISCOVERY_URL=https://authentik.example.com/application/o/cdm/.well-known/openid-configuration
OIDC_CLIENT_ID=<Client ID from step 1>
OIDC_CLIENT_SECRET=<Client Secret from step 1>
4. Map your groups to roles. Create a group in authentik, for example storage-admins, and map it:
OIDC_ROLE_MAPPING={"storage-admins":"admin","noc":"viewer"}
CDM reads the group names out of the groups claim. Recent authentik versions include that claim in the default profile scope, so this usually works with no further setup.
If your login lands on viewer although your group matches
The claim is not being sent. Add a scope mapping in Customisation, Property Mappings, Create, Scope Mapping:
| Field | Value |
|---|---|
| Name | CDM groups |
| Scope name | groups |
| Expression | return [group.name for group in user.ak_groups.all()] |
Add that mapping to the provider's selected scopes, and request it in CDM:
OIDC_SCOPES=openid email profile groups
This step depends on your authentik version, which is why it is written as a fallback rather than a required step.
Checking what CDM received
Log in and read the container log. It reports every sign-in, and the four cases look different on purpose (timestamps left out here):
INFO mapped the provider's groups to CDM roles user=martin claim=groups groups=[storage-admins] roles=[admin] defaulted=false
INFO mapped the provider's groups to CDM roles user=jo claim=groups groups=absent roles=[viewer] defaulted=true
INFO mapped the provider's groups to CDM roles user=ana claim=groups groups="present but empty" roles=[viewer] defaulted=true
INFO mapped the provider's groups to CDM roles user=kim claim=groups groups=[devs] roles=[viewer] defaulted=true
groups=absent means your provider is not sending the claim, so fix it there. present but empty means the claim arrives but is empty or is not a list; make your provider send it as a list of group names. A claim that arrives but matches nothing (defaulted=true, so OIDC_DEFAULT_ROLES applied) means OIDC_ROLE_MAPPING needs that group name.
Other providers
The same three things apply everywhere: a confidential client, the redirect URI above, and a claim carrying group names. CDM reads the claim from your provider's userinfo response, so the provider must release it there, not only in the ID token. If your provider calls that claim something else, point CDM at it with OIDC_GROUPS_CLAIM.
