Permissions
This page shows how OpenBot decides if a caller may do something.
Every call to /v1 needs one or more permissions. OpenBot checks them before the call runs.
The model has four parts:
| Part | What it is |
|---|---|
| Permission group | A named set of actions on one kind of resource, such as sessions.read. |
| Resource key | The name of one resource, such as one Session. |
| Policy | Says allow or deny for some permission groups on some resources. |
| Role | A named set of policies, such as Member or Administrator. Organizations can add their own. |
A member gets the policies of their roles, plus their own extra policies. A user token gets the policies of its member, and also its own policies. The platform can add deny policies for every organization. See The order of checks.
Permission groups
List them with GET /v1/organization/permission_groups.
| ID | Resource | What it allows |
|---|---|---|
responses.run |
Session | Start, steer, queue and resume work in a Session. |
sessions.read |
Session | Read Sessions, their history, memory and delegations. |
sessions.write |
Session | Create, change, fork, restore, interrupt and delete Sessions. |
requests.resolve |
Request | Answer the requests of your Agents for new capabilities. |
agents.read |
Agent | Read Agents, their memory, Rules and Grants. |
agents.write |
Agent | Create and change Agents, their memory, Rules and Grants. |
agents.delegate |
Agent | Give work to an Agent, from a client or from another Agent. |
connections.read |
Connection | Read App connections and App accounts. |
connections.write |
Connection | Create, change and delete App connections, and sign in to App accounts. |
apps.use |
Apps | Find Apps, and use App operations and App views. |
apps.publish |
Apps | Use the developer tools for Apps that you publish. |
models.use |
Model | Choose a model for a Session. |
tokens.read |
User | List API tokens. |
tokens.write |
User | Create and revoke API tokens. |
organization.read |
Organization | Read the organization settings. |
organization.write |
Organization | Change the organization settings. |
members.read |
Organization | List members, their roles and their policies. |
members.write |
Organization | Change the roles, policies and status of members, and remove members. |
roles.write |
Organization | Create, change and delete the custom roles of the organization. |
model_providers.read |
Organization | Read the model providers of the organization. Keys are never shown. |
model_providers.write |
Organization | Add, change and remove the model providers and keys of the organization. |
sso.read |
Organization | Read the email domains and SSO connections. |
sso.write |
Organization | Add and verify email domains, and change SSO connections. |
audit_logs.read |
Organization | Read the audit log. |
platform.read |
Platform | Read the platform settings, organizations, admins and shared model providers. |
platform.write |
Platform | Change the platform settings, organizations, admins and shared model providers. |
organization.read and organization.write also cover the organization settings.
platform.read and platform.write only work on the resource openbot.platform, and only for platform admins. See Platform groups.
The API reference lists the routes. The contract in @openbot-build/api says which permission each route needs.
Resource keys
A resource key is a name with parts that dots separate:
| Resource | Key |
|---|---|
| The organization | openbot.org.<org> |
| One member | openbot.org.<org>.user.<user> |
| One Session | openbot.org.<org>.user.<user>.session.<session> |
| One Agent of a member | openbot.org.<org>.user.<user>.agent.<agent> |
| One shared Agent | openbot.org.<org>.agent.<agent> |
| The requests of a member | openbot.org.<org>.user.<user>.request |
| One connection | openbot.org.<org>.user.<user>.connection.<connection> |
| The Apps of a member | openbot.org.<org>.user.<user>.apps |
| One model provider | openbot.org.<org>.model.<provider> |
| The whole platform | openbot.platform |
A key covers itself and every key below it. So openbot.org.<org> covers everything in the organization, and openbot.org.<org>.user.<user> covers everything of one member.
In a policy, you can write two placeholders:
{org}is the ID of the organization.{self}is the user ID of the caller. For a token, it is the member of the token.
A dot inside an ID is written as %2E, so it never looks like a new part.
Policies
A policy looks like this:
{ "effect": "allow", "permissionGroups": ["sessions.read", "sessions.write"], "resources": ["openbot.org.{org}.user.{self}"]}OpenBot decides in this order:
- If a matching policy says
deny, the answer is no. - If a matching policy says
allow, the answer is yes. - If no policy matches, the answer is no.
A policy matches when it names the permission group, and one of its resources covers the key of the request.
A policy can only name resources in its own organization. Otherwise OpenBot returns 400. Only the policies of a token can also name openbot.platform.
Limit models
models.use on openbot.org.<org>.model.<provider> covers the models of one model provider. Use it to limit which providers a member may choose. This policy stops a member from using one provider:
{ "effect": "deny", "permissionGroups": ["models.use"], "resources": ["openbot.org.{org}.model.prov_4c1e..."]}The order of checks
OpenBot checks three sets of policies, in this order:
- The policy ceiling of the platform. It only has
denypolicies, and they apply in every organization. See Platform. - The member policies: the policies of the member’s roles, plus their extra policies.
- The token policies, when the caller uses a user token.
A deny anywhere means no. Each set after the ceiling must also allow the call.
Tokens never do more than their member
A user token has two sets of policies: the policies of its member and its own policies. Both sets must say yes. So a token can do less than its member, but never more. If an administrator takes a role away from the member, every token of that member loses it too.
A token made without policies gets this policy. It allows everything in the organization except managing tokens. It never includes platform.read or platform.write:
{ "effect": "allow", "permissionGroups": [ "responses.run", "sessions.read", "...", "audit_logs.read" ], "resources": ["openbot.org.{org}"]}This example makes a token that can only read your Sessions:
curl -b cookies.txt \ -H "Origin: https://api.example.com" \ -H "Content-Type: application/json" \ -d '{"name":"Dashboard","policies":[{"effect":"allow","permissionGroups":["sessions.read"],"resources":["openbot.org.{org}.user.{self}"]}]}' \ https://api.example.com/v1/user/tokensRoles
List them with GET /v1/organization/roles. The list has the built-in roles and the custom roles of the organization. Each role has builtin: true or builtin: false.
Built-in roles
Every organization has these roles. They cannot change. A change returns 409 with RoleReadOnly.
| Role | What it can do |
|---|---|
super_administrator |
Everything in the organization. Only a Super Administrator can give or take away this role. |
administrator |
Manage the organization, its members and its shared Agents, and read the audit log. Work only with your own Sessions and connections. |
administrator_read_only |
Read the organization, its members and the audit log, and use the shared Agents. Work only with your own Sessions and connections. |
member |
Work with your own Agents, Sessions, connections and tokens, use the shared Agents and the models of the organization, and read its settings. |
auditor |
Read the organization, its members and the audit log. Nothing else. |
Some built-in roles also hold the groups for roles, model providers and SSO:
| Role | Extra groups for organization features |
|---|---|
super_administrator |
Every permission group, except platform.read and platform.write. |
administrator |
roles.write, model_providers.read, model_providers.write, sso.read, sso.write. |
administrator_read_only |
model_providers.read, sso.read. |
To give a member less than a role, add a deny policy to the member. This example stops a member from running work, but lets them read their Sessions:
curl -X PATCH -b cookies.txt \ -H "Origin: https://api.example.com" \ -H "Content-Type: application/json" \ -d '{"policies":[{"effect":"deny","permissionGroups":["responses.run"],"resources":["openbot.org.{org}"]}]}' \ https://api.example.com/v1/organization/members/u_456Custom roles
An organization can add its own roles. A custom role has a name, a description and policies. Its ID starts with role_.
Creating, changing and deleting custom roles needs roles.write.
curl -H "Authorization: Bearer $OPENBOT_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Reviewer","description":"Reads Sessions and answers requests.","policies":[{"effect":"allow","permissionGroups":["sessions.read","requests.resolve"],"resources":["openbot.org.{org}.user.{self}"]}]}' \ https://api.example.com/v1/organization/roles| Route | What it does |
|---|---|
POST /v1/organization/roles |
Creates a custom role. |
GET /v1/organization/roles/:roleId |
Reads one role. |
PATCH /v1/organization/roles/:roleId |
Changes a custom role. |
DELETE /v1/organization/roles/:roleId |
Deletes a custom role. |
- The
allowpolicies of a role cannot give anything that you cannot do yourself. Otherwise OpenBot returns403withPermissionDenied. - A change applies to every member with the role at once.
- You cannot delete a role while a member or the
defaultRolesof the organization use it. OpenBot returns409withRoleInUse.
Give a custom role to a member with PATCH /v1/organization/members/:userId. See Organization.
Platform groups
platform.read and platform.write are for platform admins. They only work on the resource openbot.platform.
- No role in an organization gives them, not even
super_administrator. - A policy ceiling or a member policy cannot give them.
- A user token of a platform admin gets them only when its own policies name them on
openbot.platform.
See Platform for an example token.
Errors
| Status | Error | When |
|---|---|---|
403 |
PermissionDenied |
No policy allows the call, or a policy denies it. See the body below. |
404 |
RoleNotFound |
The organization has no role with this ID. |
409 |
RoleReadOnly |
You tried to change or delete a built-in role. |
409 |
RoleInUse |
A member or the default roles still use the role. |
503 |
AuthorizationUnavailable |
OpenBot cannot read the roles and policies of the caller right now. |
The body of PermissionDenied names the permission and the resource key:
{ "_tag": "PermissionDenied", "permission": "sessions.write", "resource": "openbot.org.org_8f3a.user.u_123.session"}You can only reach your own Sessions and connections. A Session of another member answers 404, as if it does not exist.