Hi
AtoM 2.10 is definitely doable, but there are a few gotchas worth flagging that the official docs don't always make obvious.
1. Setup complexity of arOidcPlugin
The arOidcPlugin requires editing multiple configuration files manually rather than just flipping a switch in the UI. (accesstomemory) The key steps are:
Create an empty file named activate-oidc-plugin in the root of your AtoM installation (accesstomemory) (permissions must match the other AtoM folders).
Change the login module to oidc in apps/qubit/config/settings.yml.
Change the user class to oidcUser in apps/qubit/config/factories.yml.
Configure the provider settings in plugins/arOidcPlugin/config/app.yml.
Hidden dependency: The OIDC plugin requires an external cache to function correctly — you need to change the storage class in factories.yml from QubitSessionStorage to QubitCacheSessionStorage. (accesstomemory) Miss this step and you'll get cryptic authentication failures. You'll need something like Memcached or Redis configured.
Also important: an administrator user must exist before activating the OIDC plugin if group membership mapping is deactivated (accesstomemory) — so create your admin account first with local auth, then switch over.
2. Redirect URI for Azure App Registration
The redirect_url in the arOidcPlugin's app.yml is the URL that Azure should redirect back to after authentication. For AtoM, this is typically:
This is the route the arOidcPlugin registers internally — it's not the standard /login or /user/login path. In your Azure App Registration under Authentication > Redirect URIs, enter this exact URL. Make sure the protocol matches (HTTPS in production). A mismatch here is the single most common cause of "invalid redirect" errors.
For the provider url setting in app.yml, with Azure/Entra the value will be:
And set client_id and client_secret from your Azure App Registration.
Azure-specific settings to note:
Set send_oidc_logout to false — Keycloak supports OIDC logout natively, but for other providers like Dex this should be set to false. (accesstomemory) Azure's logout behaviour differs from Keycloak, so test carefully. If you want SSO logout to work with Azure, you'll need to configure the front-channel logout URL separately in Entra.
Set server_cert to false if your Azure endpoints use publicly trusted certificates (which they do by default), or point it to the Microsoft root CA bundle.
For scopes, use at minimum: openid email profile. If you want to match users by email, the email scope is essential.
3. Mapping Azure claims to AtoM groups
This is where it gets interesting with Azure specifically. You enable this by setting set_groups_from_attributes to true, then configuring roles_source and roles_path to tell AtoM where to find role information in the OIDC tokens. (accesstomemory)
AtoM can look for roles in: access-token, id-token, verified-claims, or user-info. (accesstomemory)
For Azure/Entra, the approach is:
In your Azure App Registration, go to Token configuration > Add groups claim and select "Security groups" (or application groups if you want finer control).
Azure emits groups as object IDs by default, not friendly names. You can configure Azure to emit group display names or use App Roles instead.
If using App Roles (recommended — cleaner approach): Define roles in Azure (e.g. atom-admin, atom-editor, atom-contributor), then set roles_source: id-token and roles_path to the path where Azure puts the roles array (typically just roles).
If using Security Groups: Set roles_source: id-token and roles_path to groups. Be aware that the number of groups in the ID token cannot exceed 200 due to Azure's HTTP header size limits (Spacelift) — for large organisations this can be a real problem.
Then in user_groups, map each role value to the corresponding AtoM group_id:
user_groups:
administrator:
attribute_value: "atom-admin" # Must match the Azure App Role value
group_id: 100 # AtoM administrator group
editor:
attribute_value: "atom-editor"
group_id: 101
contributor:
attribute_value: "atom-contributor"
group_id: 102
The group_id values reference your AtoM database — check your aclGroup table for the correct IDs.
When group mapping is enabled, any manual group changes an admin makes in AtoM will be overwritten on the user's next OIDC login (accesstomemory) — so manage everything from Azure once you've turned this on.
User matching: Set user_matching_source to either oidc-email or oidc-username. A mismatch will result in a new user record being created. (accesstomemory) With Azure, oidc-email is usually the right choice, but make sure every Azure user has an email set — it's optional in Entra by default.
Quick tips:
Test with enable_refresh_token_use: false first to simplify debugging, then enable it once login works.
Once OIDC is activated, existing local password hashes are no longer used for authentication but become valid again if the plugin is deactivated. (accesstomemory)
Always clear the Symfony cache (php symfony cc) and restart php-fpm after any config changes.
Check AtoM's Symfony logs (log/qubit.log) for detailed OIDC error messages during troubleshooting.
Hope this helps
Johan Pieterse
082 337-1406