Troubleshooting IdP Logins
Goal
A user signs in through your external IdP successfully, but the application then behaves as though they have no access — the Policies tab is missing, creating an AI System fails, or the UI reports an authentication error even though the login itself worked.
None of the symptoms below indicate a misconfigured Identity Provider. If sign-in completes and the user reaches the application at all, the IdP integration is working. Each one is a distinct, later step in onboarding that a federated user does not receive automatically.
The first three sections exist because a required onboarding step was skipped, not because something broke. If you are setting up an IdP now, follow Activate Each IdP User on the Platform and Add the Email Claim and you should never reach this page. It is here for deployments already past that point, and to map symptoms back to causes that are not obvious from the error text.
Use this guide after completing Entra ID as IdP or Keycloak as IdP and Adding Mappers.
The Policies Tab Is Missing for an IdP User
The user signs in, sees Projects and AI Systems, and no Policies tab. Roles and group membership look correct in Keycloak.
The tab is gated on a single per-user flag, not on a role:
hasDynamoGuardAccess = config.MODERATION.dynamoGuardAccess === 'ACTIVATED'
That flag is set per user by the platform's user-setup routine, which also creates the demo policies. It runs for users created by the platform bootstrap, and when called explicitly — but there is no first-login hook, so a user who arrives through an IdP never has it run. Checking their Keycloak roles is a dead end: the roles are correct and irrelevant to this flag.
Confirm before changing anything — the flag is user-scoped, so query it as the affected user, not as an admin:
curl -s -H "Authorization: Bearer $USER_TOKEN" \
https://api.<domain>/v1/config | jq '.response.MODERATION'
ACTIVATED means this is not your problem. Anything else means setup has not run.
Fix
Run the activation step from the setup guide: Activate Each IdP User on the Platform. Note the ordering constraint documented there — the user must load the application once before setup is run, or the POLICIES step fails (see the next section).
Every user who arrives through the IdP needs this. Plan for it during onboarding rather than treating it as a one-off fix, and re-check after adding a new cohort.
Policy user:<email> not found When Creating an AI System
Creating an AI System (or another shared resource) fails with:
Policy user:someone@example.com not found
Creating a resource attaches a permission bound to a Keycloak authorization policy named after the creator. That policy is created lazily, from the email on an authenticated request. If it is absent, resource creation fails while everything else about the session works — which is why this looks like a permissions bug rather than a missing object.
List the policies that exist on the API client's resource server:
curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://<keycloak-domain>/admin/realms/<realm>/clients/<api-client-uuid>/authz/resource-server/policy?max=100" \
| jq -r '.[] | select(.name | startswith("user:")) | .name'
Expect one user:<email> entry per active user. A federated user missing from that list is the failure.
Create the missing policy
Have the user load the application once and retry first — the lazy creation is driven by their request, so an admin acting on their behalf does not trigger it. If it still does not appear, create it explicitly:
curl -s -X POST \
"https://<keycloak-domain>/admin/realms/<realm>/clients/<api-client-uuid>/authz/resource-server/policy/user" \
-H "Authorization: Bearer $ADMIN_TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"user:someone@example.com","users":["<keycloak-user-uuid>"]}'
The POLICIES step of user setup fails with this same message when the policy is absent. Create the policy first, then re-run setup — otherwise setup reports a partial success that is easy to misread as complete.
The IdP Returns No Email Claim
A first-time IdP user is shown Keycloak's Review Profile page and asked to type their email, or a request fails because the platform cannot resolve the user.
The email is not cosmetic. The platform resolves the signed-in user by email on every request, and the lazy creation of the authorization policy above is keyed on it — so a token without an email produces failures that look unrelated to the IdP.
Two things to check, in order:
-
Does the IdP actually send it? Microsoft Entra ID only emits an
emailclaim when the user'smailattribute is populated. For many directories the address lives in the UPN instead. Addemail(andupn) as optional ID-token claims on the application registration — the same Token configuration screen used to add the groups claim in Adding Mappers. -
Is it mapped onto the user? Add an Attribute Importer mapper on the Identity Provider so the claim lands on the account:
Attribute Value Mapper Type Attribute Importer Claim emailUser Attribute Name emailSync Mode Override Inherit Add a second one from
preferred_usernametoemailas a fallback for directories that only populate the UPN. Identity-provider mappers run before the profile-review step, so a populated email suppresses the prompt.
The Review Profile page is governed by the first broker login flow's Review Profile execution, whose config is update.profile.on.first.login. The default missing prompts only when a required field is absent — which is the correct setting, and means a prompt is evidence that a claim is genuinely missing rather than something to switch off. The Identity Provider's own updateProfileFirstLoginMode field is legacy and is not honoured by current Keycloak versions; setting it has no effect.
Unable to authenticate user During Normal Use
The UI intermittently reports Unable to authenticate user, or an action such as saving a policy fails with Please try later, and retrying a minute later succeeds.
Check whether Keycloak restarted rather than looking for a permissions problem:
kubectl -n <namespace> get pods -l app.kubernetes.io/name=keycloak
kubectl -n <namespace> get pods -l app.kubernetes.io/name=dynamoai-api
A Keycloak pod that is only a minute or two old, alongside API pods with recent restarts, is the signature. The API treats Keycloak as a hard startup dependency — it logs Keycloak is not available, then Failed to authenticate with Keycloak after multiple attempts, and exits. So a brief Keycloak outage becomes a longer API outage, and the user-visible error names authentication rather than the restart.
kubectl -n <namespace> logs deploy/dynamoai-api --previous | grep -i keycloak
On clusters with node autoscaling this is usually node consolidation evicting the pod:
kubectl -n <namespace> get events --sort-by=.lastTimestamp | grep -iE 'Evicted|Underutilized'
A PDB written as maxUnavailable: 1 against a one-replica workload permits disrupting 100% of it — it looks like protection and provides none. kubectl get pdb shows ALLOWED DISRUPTIONS 0 only while the pod is already down, which makes the gap easy to miss.
For a stateful singleton such as Keycloak or MinIO, either use minAvailable: 1, or exclude it from consolidation entirely. With Karpenter or AKS Node Auto Provisioning:
podAnnotations:
karpenter.sh/do-not-disrupt: "true"
Apply the same treatment to any single-replica component whose loss breaks others — MinIO is the other common one, because guard model servers stream their weights from it and crashloop while it is gone.
Claim-Mapped Roles Missing After Entra ID Sign-In
The user signs in through Entra ID without error, is in the all-users group, but is missing org-level roles that their Entra security group membership should grant. Other users with fewer Entra groups receive the expected roles.
This is not a Keycloak permissions bug. Entra ID omits the groups claim from the ID token when the user belongs to too many groups (more than 200 for JWT tokens). Keycloak Advanced Claim to Role mappers read only what is in the token — they do not call Microsoft Graph via the _claim_sources overage endpoint.
Fix
Follow Entra ID Groups Claim Overage: switch the groups claim to Groups assigned to the application, assign only your DynamoAI authorization groups to the dynamoai-idp enterprise application, and have the user sign in again.
Related
- Entra ID Groups Claim Overage — missing
groupsclaim and failed claim-based role mappers - Entra ID as IdP — registering the provider
- Adding Mappers — group and role mappers, and the Token configuration screen
- User Management — roles and the Organizational Management Dashboard
- Storing OIDC Client Secrets via Vault — keeping the client secret out of the Keycloak database