Create a root key with the permissions listed on this page under Root Keys in the dashboard sidebar. CLI commands can instead use a session from unkey login with the required permissions. See Permission reference for every permission.
permissions.createPermission needs unkey:v1:<workspace_id>:projects/<project_id>/rbac/permissions/*#write. Use your workspace ID and its default project ID. A wildcard project grant also authorizes this operation.
permissions.createRole doesn’t accept rbac.* permissions. It needs unkey:v1:<workspace_id>:projects/<project_id>/rbac/roles/*#write, covering your workspace and its default project.
For permissions.setRolePermissions, use the URN permissions listed under Change a role’s permissions.
The other endpoints need the matching rbac.* permission: read_permission, read_role, and delete_role. The update and delete permission requirements are listed below.
Permissions
1 to 128 characters matching
^[a-zA-Z0-9_:\-\.\*]+$, unique within the workspace. This is the string keys hold and queries check. documents.read and billing:write are both fine. An asterisk is allowed but is a literal character, not a wildcard. See Permission queries.permissionId (perm_...). A duplicate slug fails with HTTP 409 err:unkey:data:permission_already_exists.
permissions.getPermissiontakes the ID or slug.permissions.listPermissionstakeslimit(1 to 100, default 100),cursor(up to 1024 characters), andsearch(up to 256 characters, matched against ID, name, slug, or description, ignoring case).permissions.updatePermissiontakes the ID or slug inpermission, plus any ofname,slug, anddescription. Omitted fields stay unchanged, anddescription: nullremoves the description. It needsunkey:v1:<workspace_id>:projects/<project_id>/rbac/permissions/<permission_id>#write. A slug that another permission already uses fails with HTTP 409. Keys and roles keep the permission after a slug change. Key verification can return the old slug for a short time while caches refresh.permissions.deletePermissiondeletes the permission and removes it from every role and key. It needsunkey:v1:<workspace_id>:projects/<project_id>/rbac/permissions/<permission_id>#delete.
Roles
1 to 128 characters, unique within the workspace. Keys refer to roles by name. Spaces are allowed.
Permission slugs to attach. Existing slugs need no extra permission. Slugs that don’t exist yet are created if the root key also has
unkey:v1:<workspace_id>:projects/<project_id>/rbac/permissions/*#write for your workspace and its default project. Without it, an unknown slug fails with HTTP 403 err:unkey:authorization:insufficient_permissions. Leave it out or send [] for an empty role.roleId (role_...). A duplicate name fails with HTTP 409 err:unkey:data:role_already_exists. permissions.getRole and permissions.listRoles return roles with their permissions. permissions.deleteRole deletes the role, and keys lose its permissions unless they get them another way.
permissions.updateRole takes the ID or name in role, plus any of name and description. Omitted fields stay unchanged, and description: null removes the description. It needs unkey:v1:<workspace_id>:projects/<project_id>/rbac/roles/<role_id>#write. A name that another role already uses fails with HTTP 409. Keys keep the role after a rename, but requests that name the role, such as keys.addRoles, must use the new name. Key verification can return the old name for a short time while caches refresh.
Change a role’s permissions
permissions.setRolePermissions takes role (ID or name) and the full list of slugs. Anything not in the list is removed, and [] empties the role. (The older roleId field still works but is deprecated. Send one or the other.) Your root key must have unkey:v1:<workspace_id>:projects/<project_id>/rbac/roles/<role_id>#write. Creating missing slugs also requires unkey:v1:<workspace_id>:projects/<project_id>/rbac/permissions/*#write. Use the role’s workspace, project, and role IDs.
Every key with the role picks up the change within about 10 seconds, and a few verifications just after that can still see the old permissions. Verifying keys describes the timing.
Designing the set
- Name permissions after actions, not customers:
invoices.read,invoices.write,invoices.void. - Name roles the way you talk to customers:
viewer,editor,admin, or plan names. - Attach roles to keys, and save direct permissions for one-off grants. Then changing what “editor” means is one
setRolePermissionscall, not an update to every key. - Use a role for “everything under documents”. An asterisk isn’t a wildcard, so list each
documents.*permission in the role.
From the dashboard
Open Authorization in the sidebar. On the Permissions tab, create and edit permissions. On the Roles tab, create and edit roles, pick their permissions (or create new ones), and assign the role to keys.