Roles & Permissions

Permissions in FerrisKey are bits in a 64-bit integer. A role is a named bundle of them, and an authorization check is a single bitwise AND.

How it works

Each permission maps to a unique power of two:

CreateClient        = 0b0000...0001  (bit 0)
ManageAuthorization = 0b0000...0010  (bit 1)
ManageClients       = 0b0000...0100  (bit 2)
...

A role stores its permissions as a single u64 bitmask, the OR of all included permission bits. Checking whether a user has a permission is a single AND operation:

fn has_permission(user_permissions: u64, required: u64) -> bool {
    user_permissions & required == required
}

Permissions reference

The API and the CLI both take permissions by their snake_case name, so manage_realm, not ManageRealm and not realm:manage. An unrecognized name is dropped silently when a role is saved, which is worth remembering when a role looks like it granted nothing.

Manage

PermissionDescription
create_clientCreate new OAuth2 clients
manage_authorizationManage authorization policies
manage_clientsUpdate and delete clients
manage_eventsManage audit event configuration
manage_identity_providersConfigure external identity providers
manage_realmUpdate realm settings
manage_usersCreate, update, and delete users
manage_rolesCreate, update, and delete roles
manage_webhooksConfigure webhook subscriptions
manage_client_scopesManage client scopes and protocol mappers
manage_email_templatesCreate, update, and delete email templates

Query

PermissionDescription
query_clientsList and search clients
query_groupsList and search groups
query_realmsList and search realms
query_usersList and search users
query_webhooksList and search webhooks
query_client_scopesList and search client scopes

View

PermissionDescription
view_authorizationView authorization details
view_clientsView client details
view_eventsView audit events
view_identity_providersView identity provider details
view_realmView realm details
view_usersView user details
view_rolesView role details
view_webhooksView webhook details
view_client_scopesView client scope details
view_email_templatesView email templates

Role mappings

Roles are attached to users, including service account users, through role mappings. A user’s effective permissions are the bitwise OR of every role bitmask assigned to them.

Take a user with two roles:

  • Viewer, holding view_users | view_clients = 0b...10100
  • User Manager, holding manage_users | query_users = 0b...01010

The effective mask is 0b...11110: they can view and manage users, view clients, and query users.

Realm and client roles

A realm role is defined on the realm and applies across all its clients. A client role is scoped to one client and only means something in that client’s context. Both are assigned to users the same way, and role ids are unique across the two scopes.

When a user authenticates, their roles are resolved and written into the access token as claims through protocol mappers, so a resource server can authorize a request without calling back to FerrisKey.