Roles and groups
Ada joins the backend team. On her first day she should be able to review code, and because she is on a team inside engineering she should also get whatever every engineer gets. Nobody wants to tick those boxes person by person. Roles and groups are how you say it once.
In words: Groups form a tree. A role mapped to the engineering group reaches everyone in its backend group. Ada joins only backend, so her roles claim lists reviewer and engineering-lead, while her groups claim lists only the backend group, because it carries direct memberships and no parents.
Roles
A role is a name for something a person may do, such as reviewer or billing-admin. Odudu does not decide what the role allows. Your app does, when it reads the role from a token. A role can be:
- a tenant role, which any client in the tenant may read;
- a client role, named for one client and relevant only to it;
- a composite role, which bundles other roles so that holding it means holding them all.
A role can also be marked as a default for new people, so everyone created afterwards starts with it.
Groups
A group is a place people belong. Groups form a tree, and each has a path: /engineering is a group, and /engineering/backend is a group inside it. A person can belong to several groups.
A group can be given roles. Everyone in the group holds them.
How a person ends up with a role
There are three ways, and they add together:
- The role is given to the person directly.
- The role is given to a group the person belongs to.
- The role is given to a group above the person's own. A role mapped to
/engineeringreaches everyone in/engineeringand in every group beneath it.
The third is the one that saves work. Ada belongs to /engineering/backend and nothing else. She holds what backend gives her, and what engineering gives her too, though nobody ever added her to /engineering itself. Ask the admin API for her effective-roles and you see the full answer.
What reaches a token
Two claims carry this to your app, and they do not agree on purpose.
- The
rolesclaim lists every role the person holds, including those that came from groups above. Ada's lists bothreviewerandengineering-lead. A role that belongs to one client appears with the client's id in front, as inreports-api:reader. - The
groupsclaim lists only the groups the person belongs to directly. Ada's lists/engineering/backendand nothing else.
If your app checks groups for /engineering, it will not find Ada, even though she holds everything engineering grants. Check roles, and your app agrees with what Odudu allows. Use groups when you want the person's own memberships, for example to show where they sit.
A role also reaches a token only when a scope carries it. You map the role to a scope, such as roles, and the claim appears when the client was granted that scope. A client with Include all roles in tokens on skips the mapping, but still needs the roles scope to get the claim. Scopes explains the rule.
Working with roles and groups
- Decide which things your app needs to tell people apart by, and name one role for each.
- Create the roles, then the groups that match how people are organised.
- Give each group the roles its members should hold.
- Put people in groups. Prefer a group to a direct role: one change then covers everybody in it.
- Map the roles to a scope and give the client that scope, so they reach the token. Or turn on Include all roles in tokens and give the client the
rolesscope. - In your app, read
rolesfrom the access token. The access token carries it by default, and the ID token does not.
An administrator cannot put a person in a group whose roles reach further than the administrator's own, so the admin API cannot be used to grant more than its caller holds.
Where to go next
- Scopes shows how a role reaches a token.
- Tokens shows where the claim lives.
- The admin API has roles and groups pages, and the Keycloak guide lines Odudu's names up with Keycloak's.