Access in Govern is granted with roles bound to nodes of the organisation's directory. This page is the reference for how roles, bindings and permissions fit together, and which permissions the governance areas use.
The model
| Term | Meaning |
|---|---|
| Node | A directory node: organisation, business unit, service, team, project or sub-project. |
| Permission | <resource>:<verb>, for example models:admin or iam.reviews:decide. A resource is one or more lowercase segments joined by dots. |
| Role | A named set of permission patterns, plus optional composite roles. Built-in roles are versioned in code; custom roles belong to one organisation. |
| Binding | A principal (user, group or service account), a role and a node, with an optional CEL condition, an optional expiry and a state (active or eligible). Bindings apply to the node and everything below it. |
A granted permission can be a wildcard: <resource>:*, *:<verb> or *:*. A required permission is always a concrete name from the catalog. GET /api/v1/permissions lists the catalog (filter by prefix, privileged and risk), and GET /api/v1/me/permissions answers the caller's effective permissions on a node.
Account roles
Account roles are bound on the organisation node. One person can hold several.
| Role | Holds | Cannot |
|---|---|---|
| Owner | Everything, including the Owner-reserved actions | |
| Admin | Users, groups, settings and every resource | The Owner-reserved actions |
| Security and compliance | Reads the audit trail, evidence, access configuration, policies and security posture; manages compliance, privacy requests and access reviews | Use or change code-facing resources; grant roles |
| Billing | Billing, usage and quotas | Anything else |
| Member | Only themselves (profile, own sessions, devices and keys) and the runtime entry points that deliver what is assigned to them (models:read, skills:use, harness:read) | Read or list any resource not shared with them |
| Read-only (all) | Reads everything, sensitive data included | Never a default; granted explicitly |
Owner-reserved actions are denied to everyone without a standing Owner grant: changing the payment method (billing.payment_method:manage), the spending cap, the support plan, closing the account (account:close), and granting or revoking Owner (iam.owner:grant, iam.owner:revoke). A just-in-time or break-glass activation of an Owner binding does not count. At least one Owner is always kept, and only an Owner can make another Owner.
The console shows account roles and custom roles on Access > Roles.
Resource roles
Resource roles are bound on a project node or on one object. Each level includes the one before.
| Role | use / read / write / secrets / manage |
|---|---|---|---|---|---|
| User | yes | | | | |
| Viewer | yes | yes | | | |
| Editor | yes | yes | yes | yes | |
| Manager | yes | yes | yes | yes | yes |
use: use the resource for one's work without seeing its configuration, for example call models through a connection or connect to an MCP server.read: read the configuration. Secret values are never returned after they are saved; model connection keys show only a hint and version.write: change the configuration.secrets: replace a secret, write-only.manage: grant and revoke resource roles, delete or disable the resource.
Approval is never part of a resource role. It is a separate permission in every area (mcp:approve, agentpolicy:approve, agents:approve and others), and nobody can approve their own request.
Shareable resource types include projects, model connections (models.connections), MCP servers (mcp.servers), skills, harness packs (harness.packs), Context spaces, vault paths, workspaces, sandboxes and agent policy rule sets. Membership of a project gives User on it.
What lists and direct reads show
Lists return only the objects the caller holds at least use or read on. A direct request for an object the caller can neither use nor read answers 404, also for writes, so a refusal never confirms that an object exists.
Sharing
People with Manager on an object share it from the object's page in the console, or with the API:
| Route | Who |
|---|---|
GET /api/v1/access/resources/{type}/{id}/effective-access | Anyone signed in: their own level on the object |
GET /api/v1/access/resources/{type}/{id}/sharing | Viewer: who has access and how |
POST /api/v1/access/resources/{type}/{id}/sharing / Manager: grant {principal_type, principal_id, level}; audited access.share.granted | |
DELETE /api/v1/access/resources/{type}/{id}/sharing/{binding_id} / Manager: revoke; audited access.share.revoked |
A share cannot exceed the granter's own level, cannot go to the granter or a group they belong to, and cannot come from authority that exists only through a just-in-time activation. Requests for access are on Just-in-time access.
Bindings
| Route | Permission |
|---|---|
GET /api/v1/access/bindings / iam.bindings:read (filters node_id, principal_type, principal_id, role_id, state) | |
POST /api/v1/access/bindings / iam.bindings:create on the node, plus the escalation guard | |
GET /api/v1/access/bindings/{id} / iam.bindings:read | |
PUT /api/v1/access/bindings/{id} / iam.bindings:update, plus the escalation guard | |
DELETE /api/v1/access/bindings/{id} / iam.bindings:delete; the last administrator cannot be removed |
Binding body: node_id, principal_type (user, group or service_account), principal_id, role_id, state (active or eligible), condition (CEL), condition_title, expires_at, requires_approval, max_activation_minutes (1 to 10080), break_glass, membership_bound and description. Mutable objects carry an etag; updates and deletes need If-Match and answer 409 on a mismatch. Every write returns a revision token (rv1.<n>); a client that sends it back in X-Keystone-Access-Revision gets answers computed at that revision or later.
Conditions
Conditions are CEL, compiled and type-checked when saved. They can read request.time, request.method, request.path, request.ip, request.mfa_age_seconds, resource.id, resource.kind, resource.path, resource.labels (only access/ labels), principal.type, principal.id, principal.email and principal.groups. An allow binding grants only when its condition is true; a deny applies when its condition is true or cannot be evaluated.
Custom roles
| Route | Permission |
|---|---|
GET /api/v1/access/roles, GET /api/v1/access/roles/{id} / iam.roles:read | |
POST /api/v1/access/roles / iam.roles:create | |
PUT /api/v1/access/roles/{id} / iam.roles:update | |
DELETE /api/v1/access/roles/{id} / iam.roles:delete | |
GET /api/v1/access/roles/{id}/versions / iam.roles:read |
Body: {"name", "description", "permissions": [...], "composites": [role ids]}. Permissions must be catalog names or wildcard patterns over the catalog. Built-in roles are read-only, every change records a version, and a role that is bound or used as a composite cannot be deleted. Creating or changing a role requires holding, with standing bindings on the organisation node, everything the role would grant.
The escalation guard
Creating or changing a binding requires, at the target node:
iam.bindings:create(orupdateordelete).- Holding every permission the role grants.
- The role being on the node's delegation allow-list; see Access guardrails.
- For roles that themselves grant roles: authority from a binding on the organisation node.
- A node keeps at least one administrator.
- Privileged roles bind only to users or to groups with assigned membership.
- No binding that breaks a separation-of-duties rule.
- No binding for yourself or a group you belong to.
- Authority that comes only from a just-in-time or break-glass activation can create only bindings that expire no later than the activation.
Invitations follow the same rule: an invitation can give an account role only if the inviter could grant it.
Permissions by area
These are the permissions the governance pages of these docs refer to. Owner and Admin hold all of them through *:*. In this table, iam.sod:read/manage is shorthand for the two permissions iam.sod:read and iam.sod:manage; the slash is not part of any name.
| Area | Permissions |
|---|---|
| Access | iam.roles:*, iam.bindings:*, iam.denypolicies:read/manage, iam.ceilings:read/manage, iam.delegation:read/manage, iam.sod:read/manage, iam.settings:read/update, iam.principals:read/manage, iam.activations:read/request/approve, iam.breakglass:read/review, iam.reviews:read/manage/decide/export, iam.access:analyze |
| Identity Center | sso.connections:*, sso.domains:*, sso.enforcement:*, sso.domainusers:*, sso.permissionsets:*, sso.assignments:*, sso.mappings:*, sso.sessions:*, scim:manage, scim:read, ldap:read/update/create |
| API keys and service accounts | apikeys:read/create/delete, directory.serviceaccounts:read/manage |
| Model access and the AI Gateway | models:read (use), models:view (read configuration), models:write (catalog, assignments, defaults, budgets, routes), models:admin (connections, policy, gateway settings, keys, guardrails, rate limits, logs), models:keys (provider keys) |
| Agent policy | agentpolicy:read, agentpolicy:write, agentpolicy:approve |
| Approvals | approvals:read, approvals:approve, approvals:admin |
| Third-party tool controls | controls:manage, security:read |
| Harness packs | harness:read, harness:publish, harness:assign, harness:experiment |
| Console assistant | assistant.conversations:*, assistant.proposals:*, assistant.settings:getsettings/updatesettings |
| Audit | audit:read, audit:create |
Legacy organisation roles API
The older routes under /api/v1/organizations/{id}/roles (and .../members/{membership_id}/roles) still work and need roles:read, roles:create, roles:update or roles:delete. Role assignments made through them pass the same escalation guard. Prefer /api/v1/access/* for new automation.