Govern
Documentation

Version Latest

Roles and permissions

Reference for Neural Inverse Govern's permission grammar, account roles, resource roles, bindings, custom roles, sharing and the escalation guard, with the permissions each governance area uses.

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

TermMeaning
NodeA 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.
RoleA named set of permission patterns, plus optional composite roles. Built-in roles are versioned in code; custom roles belong to one organisation.
BindingA 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.

RoleHoldsCannot
OwnerEverything, including the Owner-reserved actions
AdminUsers, groups, settings and every resourceThe Owner-reserved actions
Security and complianceReads the audit trail, evidence, access configuration, policies and security posture; manages compliance, privacy requests and access reviewsUse or change code-facing resources; grant roles
BillingBilling, usage and quotasAnything else
MemberOnly 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 includedNever 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:

RouteWho
GET /api/v1/access/resources/{type}/{id}/effective-accessAnyone signed in: their own level on the object
GET /api/v1/access/resources/{type}/{id}/sharingViewer: 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

RoutePermission
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

RoutePermission
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:

  1. iam.bindings:create (or update or delete).
  2. Holding every permission the role grants.
  3. The role being on the node's delegation allow-list; see Access guardrails.
  4. For roles that themselves grant roles: authority from a binding on the organisation node.
  5. A node keeps at least one administrator.
  6. Privileged roles bind only to users or to groups with assigned membership.
  7. No binding that breaks a separation-of-duties rule.
  8. No binding for yourself or a group you belong to.
  9. 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.

AreaPermissions
Accessiam.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 Centersso.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 accountsapikeys:read/create/delete, directory.serviceaccounts:read/manage
Model access and the AI Gatewaymodels: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 policyagentpolicy:read, agentpolicy:write, agentpolicy:approve
Approvalsapprovals:read, approvals:approve, approvals:admin
Third-party tool controlscontrols:manage, security:read
Harness packsharness:read, harness:publish, harness:assign, harness:experiment
Console assistantassistant.conversations:*, assistant.proposals:*, assistant.settings:getsettings/updatesettings
Auditaudit: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.

Last reviewed 17 October 2026View as Markdown

Roles and permissions · Docs · Neural Inverse