Enforce group-based access controls
What you’ll accomplish
Section titled “What you’ll accomplish”You’ll restrict access to a UDS application so that only users in specific Keycloak groups can authenticate. Users who are not in the required group will be denied, even if they have a valid Keycloak account.
Prerequisites
Section titled “Prerequisites”- UDS Core deployed
- Application deployed as a UDS Package with a Keycloak SSO client configured (see Register and customize SSO clients for native SSO or Protect applications with Authservice for mesh-boundary protection)
- Relevant Keycloak groups exist (either the built-in platform groups or custom groups you have created)
Before you begin
Section titled “Before you begin”UDS Core pre-configures two Keycloak groups:
| Group | Purpose |
|---|---|
/UDS Core/Admin | Platform administrators with full access to Grafana, Keycloak admin console, Alertmanager |
/UDS Core/Auditor | Read-only access to Grafana, log browsing |
Application teams can define their own group paths. Group paths follow Keycloak’s hierarchy notation:
/ParentGroup/ChildGroup: nested groups use/as separator- If a group name itself contains a
/, escape it with~(e.g., a group nameda/bbecomesa~/b)
-
Identify the group path
In the Keycloak admin UI (uds realm), go to Groups and locate the group you want to require. Note the full hierarchical path including any parent groups.
For the built-in platform groups, the paths are:
/UDS Core/Admin/UDS Core/Auditor
-
Add
groups.anyOfto yourPackageCRIn your application’s
PackageCR, add agroups.anyOflist under the relevant SSO client. Users must be a member of at least one of the listed groups to be granted access. For Authservice protection, also addenableAuthserviceSelectoras described in Protect applications with Authservice.package.yaml apiVersion: uds.dev/v1alpha1kind: Packagemetadata:name: httpbinnamespace: httpbinspec:sso:- name: Demo SSOclientId: uds-core-httpbinredirectUris:- "https://protected.uds.dev/auth/callback"groups:anyOf:- "/UDS Core/Admin"To allow multiple groups (users in any one of the listed groups are granted access):
groups:anyOf:- "/UDS Core/Admin"- "/MyApp/Operators" -
Apply the
PackageCRTerminal window uds zarf tools kubectl apply -f package.yamlThe UDS Operator reconciles the
PackageCR and passes the group requirement to the Keycloak SSO client. UDS Core uses that client configuration to enforce group membership during authentication.
Verification
Section titled “Verification”Confirm group-based access is enforced:
Test with an authorized user:
- Log in with a user who is a member of the required group
- Access should be granted to the application
Test with an unauthorized user:
- Log in with a user who is NOT a member of the required group
- For these browser-based SSO flows, access should be denied during Keycloak authentication before the user reaches the application.
Verify the Keycloak client configuration for both integrations:
- In the Keycloak admin UI, open the client identified by
clientId. - Confirm that its
uds.core.groupsattribute contains the expectedanyOfgroup paths. - Test the login flow with an authorized and unauthorized user.
For Authservice-protected applications, you can additionally check the generated policy:
uds zarf tools kubectl get authorizationpolicy -n <app-namespace>This policy confirms JWT and Authservice enforcement, but the uds.core.groups client attribute controls group membership. Native SSO does not create an Authservice chain.
Troubleshooting
Section titled “Troubleshooting”Problem: All users are denied access
Section titled “Problem: All users are denied access”Symptoms: Even users who should have access receive a 403.
Solution: Verify the group path in groups.anyOf is exactly correct:
- Log in to the Keycloak admin UI (uds realm)
- Go to Groups and navigate to the intended group
- Copy the full path including parent groups and leading
/ - Compare it character-for-character with the value in your
PackageCR (paths are case-sensitive)
Problem: Group membership does not match what’s in Keycloak
Section titled “Problem: Group membership does not match what’s in Keycloak”Symptoms: A user is in the group in Keycloak but is still denied access.
Solution: UDS Core checks the user’s server-side Keycloak group membership during authentication. Confirm that:
- The group exists at the exact path listed in
groups.anyOf. - The user belongs to that group in Keycloak.
- The user logs out and back in after a group membership change so Keycloak evaluates the updated membership.
The groups token claim does not control groups.anyOf enforcement, but application code can use it for fine-grained authorization after the platform grants access. To include the claim in tokens, see Register and customize SSO clients for the group membership mapper. To inspect token claims, use the Keycloak Account console at sso.<domain> or a tool like jwt.io.
Problem: Group name contains a slash
Section titled “Problem: Group name contains a slash”Symptoms: Group path is not matching even though the group exists.
Solution: If the group name itself contains a / character (not a hierarchy separator), escape it with ~. For example, a group named a/b nested under ParentGroup would be written as /ParentGroup/a~/b.
Related documentation
Section titled “Related documentation”- Identity & Authorization concepts - background on platform groups and the SSO model
PackageCR reference - fullgroupsfield specification- Register and customize SSO clients - configure a native OIDC or SAML client before adding group restrictions
- Protect applications with Authservice - add mesh-boundary protection when UDS Core should own browser authentication