Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespaced Roles #318

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

dgozalo
Copy link

@dgozalo dgozalo commented Oct 1, 2021

Creating a separate PR as this proposal is too large for having the whole text in Github discussions as defined in https://github.com/keycloak/keycloak/pull/8503/files#diff-eca12c0a30e25b4b46522ebf89465a03ba72a03f540796c979137931d8f92055R48

Coming from: keycloak/keycloak#8516

design/namespaced-roles.md Outdated Show resolved Hide resolved
design/namespaced-roles.md Outdated Show resolved Hide resolved
design/namespaced-roles.md Outdated Show resolved Hide resolved
design/namespaced-roles.md Outdated Show resolved Hide resolved
design/namespaced-roles.md Outdated Show resolved Hide resolved
design/namespaced-roles.md Outdated Show resolved Hide resolved

If the role name is another reference to a free form role, starting with `frole_v1:/`, this role will also be represented in a hierarchical way, making it possible for protocol mappers to show them as such in tokens.

## Use Cases
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to explicitly mention how role namespaces can clean-up the roles used "internally" by Keycloak's admin APIs. Getting rid of the strange clients, and having a separate/dedicated namespace for the roles so they don't conflict with "custom roles". I had something like the following in mind:

kc/admin/{realm-name}/{role-name}

design/namespaced-roles.md Outdated Show resolved Hide resolved

- `Group:devops` has the `role_v1:/realm1/tenant1//devops/devops_role` role.

#### Representation in the tokens
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would like to see some alternatives on how roles can be represented in a token. For example options to flatten them if that makes sense. For example a client may not understand the concept of role namespaces, but would only want the roles for a specific namespace flattened.

Also, would be good to touch on how the roles can be represented in the current way they are being done in tokens with regards to realm and client roles.

## Specification

A Namespaced Role would contain a version, a path that start with a known particle to identify the nature of the role, and finally the role name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is particle a common term in this context?


User defined roles, but still used to interact with Keycloak entities would start with `/ud`.

Totally custom namespaces created with a specific business meaning for users wouldn't contain any of the previous particles.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean we've reserved /kc and /ud, but folks can define anything else if they want like /myorg/ or do you think there's always a "short" special start to the path?


A few examples would be:

`role_v1:/kc/groups/{group-name}/roleName`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be role_v1:/ud/groups/{group-name}/roleName?

Comment on lines 45 to 46
**Tenant**: There's a proposal to make Keycloak multitenant aware, so even if it's not currently supported, for future compatibility, it should be considered when defining a unique identifier.
- Example: `role_v1:/kc/tenants/tenantA/roleName`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a little bit concerned with making the role namespace proposal mix-up with multi-tenant proposal. Also, a little bit unsure if "tenant" is an optional part in your head. Will need to discuss this with you to get some more clarification.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thought is to leave the multi-tenant part a bit out of this design, perhaps just including it at the end as a separate section on how we could leverage role namespaces for multi-tenancy.

**Client**: Roles can be defined and assigned for a certain client in Keycloak, so a unique identifier has to support this possibility.
- Example: `role_v1:/kc/clients/clientId/roleName`.

Alternatively, if a namespace wants to be created for roles that can be shared among clients, it could be defined such as: `role_v1:/clients/*/roleName`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand why there's a * here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wonder if in this case you'd just use a free-form role namespace instead.


- `role_v1:/groups/{group-name}/role-path/business-units/myBusinessUnit/const-centers/myCostCenter/roleName`

But not convinced on the way to let Keycloak know that that's not a role name but rather a new namespace.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that clients, groups, tenants, etc, would instead of having a fixed path to their namespace would allow configuring the namespace that is associated with them.

So, a client could have it's default namespace be /kc/clients/{client-id}, but could be configured to use a different namespace like /my-roles/my-group-of-apps


## Management Roles

These roles would only exist in the Master realm and would have a meaning for Keycloak, hence the `kc` fragment.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have roles in the master realm that is used to control both the master realm and other realms when authenticating to the master console, but there are also the roles within each realm that can be used to grant users within a given realm access to only that realms admin endpoints.


- `role_v1:/kc/admin/{role-name}` -> Roles to manage the Keycloak instance.

When a new Realm is created in Keycloak, a new client is created in the Master realm to represent a namespace for this new Realm's admin roles. With the exception of the previous one, they will be used to deprecate the Clients that Keycloak creates to group certain management roles together.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's also a client created within the new realm


The rest of these roles would always be scoped to a specific realm that would replace the current client-per-realm.

- `role_v1:/kc/realms/{realm-name}/clients/{client-name}/{role-name}` -> Roles to manage a certain client.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more fine-grained than what we have today. Right now, we have just manage-clients, not ability to manage an individual client. Wonder if this level is too fine-grained for roles, and rather we should look at fine-grained admin permission to manage individual clients (and also could look at integrating with external authz services in the future).


or with a regexp, they could be namespaced to a specific subset of clients:

- `role_v1:/ud/clients/{regexp-containing-wildcard}/{role-name}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this be incredibly complex to resolve? Also, we'd want to use client-id to specify a client rather than client-name, and often these are just generated (and really should be), so is there a meaningful regex here?

```
Or even scope this custom namespace to a specific client or client sets:

- `role_v1:/ud/clients/{client-name-or-regexp}/frole:/mycompany/resources/department-a-roles/developer`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm... I'm struggling to understand this one ;)

- On resource deletion: The system should query all roles with the resource in its namespace and delete them.
- Example: Role `role_v1:/ud/groups/groupA/developer` exists. User deletes `groupA`. The system will query `getRoles("v1", "ud, "/groups/groupA")` and delete any returned entries.

### Extensibility
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Versioning is important, but may be complicated to incorporate at least in a first pass of role namespaces. Versioning has implications on versioning of other entity types, Rest APIs, UI, Java APIs, etc. and should probably be done as an overall concept rather than something "bespoke" for role namespace.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants