Docs

Roles & Permissions

Named permission sets with read and write scopes — the authority behind every admin action.

What a Role Is

Every account carries exactly one role, and the link can never dangle.

A role is a named bundle of permission scopes assigned to platform accounts. Every account points at exactly one role, and KeenAgents guarantees that link is always valid — an account can never reference a role that does not exist, and deleting a role never leaves accounts behind. A role carries a human-facing Title, a machine Slug derived automatically from the title, and two scope lists: what the role can read (view) and what it can write (modify). Both title and slug are unique across your organization.

Permission changes take effect across the whole platform right away — there is no propagation step for you to trigger and no per-surface re-sync. Assign a role, save its permissions, and every gated surface honors the new state.

Core Concepts

Slug
Generated from the title on create and on every rename: the title is lowercased, and spaces and punctuation become underscores — "Support Team" derives support_team. You never enter it directly. It is the role's stable identifier: what accounts reference and what integrations should store.
Write implies read
A writable scope is always readable too — after every save, KeenAgents ensures the read list contains everything in the write list, no matter what was sent. The permissions board makes the coupling visible: Write can only be switched on while Assigned is on, and switching Assigned off clears Write with it. Why: a role that can change something it cannot see would be an inconsistent grant.
Partial updates
A save that changes only one of the two lists never disturbs the other — KeenAgents combines what you sent with the stored value of the list you left out. A read-only change cannot strand stale write grants, and a write-only change cannot silently shrink read access.
Protected platform roles
Four roles ship with every organization and can never be deleted: admin ("Administrator"), owner ("Owner"), developer ("Developer") and default ("Default"). admin, owner and default cannot be edited at all; developer allows permission edits but keeps its title locked. default is additionally the landing role for accounts whose role is deleted.
Audit trail
Every role create, update and delete is recorded in the audit trail together with who performed it — the operator's email, user id and role. Why: permission changes are the highest-impact admin actions, and the record answers "who granted this" later.

Permission Scopes

A closed set of twelve values — unknown scopes are refused outright.

Scopes come from a fixed catalog; a value outside it can never be granted. The twelve values: roles, account, consumer, spaces, agents, api_keys, clients, certificates, contracts, webhooks, cache, logs. All twelve appear on the admin permissions board:

ScopeSurfaceRead grantsWrite grants
accountAccounts — platform user managementView accountsCreate/edit/delete accounts, assign roles
consumerConsumers — end-user managementView consumersCreate/edit/delete consumer accounts, assign their contracts
rolesRoles — permission managementView rolesCreate/edit/delete role definitions and their permissions
spacesAI Spaces — workspace managementView spaces and their deployment tokensCreate/edit/delete the spaces where agents are deployed
agentsAgents — AI agent managementView agents and their settingsCreate/edit/delete agents within spaces
api_keysAPI Keys — application secret managementView issued keys and their bindingsCreate/rotate/revoke keys
clientsClients — partner client credentialsView clientsCreate/rotate/delete client id and secret pairs
certificatesCertificates — signing certificatesView certificates and their public keysGenerate/rotate/delete certificate pairs
contractsContracts — consumer contractsView contracts, their spaces and policiesCreate/edit/delete contracts and their assignments
webhooksWebhooks — partner webhook recordsView webhook recordsCreate/edit/delete the name, origin and webhook bindings
cacheCache — platform cache administrationView cache statusCreate or invalidate platform caches
logsLogs — platform activity and flow execution logsView logsEnable/disable log channels

Rules & Limits

  • Title is required and non-empty; it is trimmed and capped at 60 characters.
  • Forbidden titles: a title that is or merely contains a protected name — admin, owner, developer or default, matched case-insensitively — is refused at create and update with "title cannot be or include "admin", "owner", "developer" or "default"". "Default Support" fails; "Support" passes. Why: custom roles must never masquerade as the built-in ones.
  • Title and slug are both unique. Because the slug is normalized, two visually different titles can collide — "Support Team" and "Support-Team" both derive support_team, and the second create is refused as a duplicate.
  • Every granted scope must belong to the twelve-value catalog; anything else is refused with "each permission must be one of: roles, account, consumer, spaces, agents, api_keys, clients, certificates, contracts, webhooks, cache, logs".
  • After every save the read list contains everything in the write list. The form additionally refuses submission when a write scope is not readable ("A writable scope must be readable too").
  • Protected roles: none of the four can be deleted; admin/owner/default refuse any update; developer ignores title changes but accepts permission edits.
  • Renaming a role regenerates its slug, and every assigned account follows in the same atomic step — accounts are never split between the old and the new name.
  • Refusals are deliberately general: a duplicate title, a protected role or an unknown role all answer with the same terse refusal, and only input-validation errors explain what to fix. Why: error responses should help you correct input, not map out the platform's internal state.

In the Admin UI

Where roles live, and what happens on delete.

  • /rolesRole Management landing page with a create card and a list card.
  • /roles/listRole List: a table with Title, Slug, ID and a Visit link per row, plus a filter panel with repeatable rows of type + operator + value — free text for title, slug and id (equals / not / like / not like / in / not in) and a date picker for created date (on / not on / after / before). Filters live in the URL — refresh, share and back/forward all preserve them — and Clear All resets the list.
  • /roles/createCreate Role: a single Title field (helper text: "Up to 60 characters. The slug is derived from the title."). Success toasts and redirects straight to the new role's detail page, where permissions can be assigned.
  • /roles/<id>Role Details: Title field + Permissions board + Save + Delete. Save is dirty-gated (enabled only when values actually deviate from the loaded role); Delete is two-step (Delete → Confirm delete / Cancel).
  • The Permissions board shows one row per catalog scope with an Assigned (read) and a Write switch. Caption: "Assigned grants read access; Write needs Assigned first. Turning Assigned off clears Write too."
  • Protected roles render a badge — protected — read only for admin/owner/default (entire form locked) and protected — title locked for developer (permissions still editable). All four hide the Delete button entirely.

Deleting a role is one atomic operation — there is no path that leaves an account pointing at a role that no longer exists:

  1. On confirm, KeenAgents refuses the delete if the role is protected or unknown.
  2. Otherwise, in a single atomic step, every account holding the role is moved to default and the role is removed — either both happen or neither does.
  3. Anyone signed in under the deleted role is signed out, and permission checks across the platform reflect the change immediately.
  4. The action is written to the audit trail with the requester's email, id and role.
  5. The UI toasts 'Role "X" deleted — its accounts moved to "default"' and returns to the roles list.
Delete moves accounts silently
The move to default happens in the same step with no per-account confirmation of which accounts moved — and users working under the deleted role are signed out. Review who holds a role before deleting it.

Good to Know

  • Renaming a role regenerates its slug and every assigned account follows automatically — but anything external that stored the old slug string no longer matches. A rename is atomic, not a soft alias.
  • The four built-in platform roles start with empty permission lists — Administrator/Owner privileges are not expressed through the scope lists, which only drive the scope-gated surfaces.
  • Granting a write scope never fails for a missing read scope — the read grant is added automatically, so you never have to grant read separately.
  • The developer role fails "softly" on rename: a new title is ignored rather than rejected — the save succeeds, the permission changes apply, the title just stays "Developer".
  • Slug collisions are refusals even when titles differ — pick titles that normalize to distinct slugs, since the slug is the role's stable identifier.
  • The cache scope's write level separately gates the per-record Rebuild Resource Cache button on the Spaces, Agents and API Keys detail pages: someone can hold a resource's own write scope and still not see Rebuild without cache:w — and, conversely, a cache manager can see Rebuild without holding that resource's write scope.

Previous

Accounts

Next

Spaces

Keen Agents 2026

Documentation

Release 15