# Permissions

What each role can do, who can reach which files and folders in your knowledge base, and what happens when access is denied.

Senso decides what a request can do in two steps. A **role** decides what a person can do across your organization. **Knowledge base access** decides which files and folders a person or an API key can reach.

| Who | Across the organization | In the knowledge base |
|-----|-------------------------|-----------------------|
| **Admin** | Everything | Every file and folder |
| **Collaborator** | Everything except credits, and managing members, groups, API keys and organization settings | Every file and folder |
| **Viewer** | Read only: members, prompts and their analytics, and organization settings | Only what is shared with them, with a group they belong to, or made public |
| **API key** | Everything except what needs a signed-in person, like managing API keys and groups | Every file and folder, unless you restrict the key |

## Roles

Every person in your organization has one of three built-in roles: `admin`, `collaborator` or `viewer`. Every organization has the same three.

An admin chooses a person's role when they invite them, and can change it later on the **User Management** page in the Senso app or with `senso users update`.

**Pass the `role_id`, not the role name.** Each organization has its own IDs for the three roles. Look them up with `senso roles list` or:

```bash
curl "https://apiv2.senso.ai/api/v1/org/roles" \
  -H "X-API-Key: $SENSO_API_KEY"
```

### What each role can do

| Area | Admin | Collaborator | Viewer |
|------|-------|--------------|--------|
| Organization settings: profile, competitors, tracked sources, AI models and run schedule | Read and change | Read | Read |
| Publishing destinations | Add and remove | Read | None |
| Members | Invite, change roles, remove | Read | Read |
| Roles | Read | Read | Read |
| Groups | Create, change, delete | None | None |
| API keys | Create, change, revoke | None | None |
| Credits | Read | None | None |
| Generated content and generation runs | Read and change | Read and change | None |
| Prompts | Read and change | Read and change | Read |
| Prompt analytics: mentions and citations | Read | Read | Read |
| Tags | Read and change | Read and change | None |
| Brand kit, content types and product lines | Read and change | Read and change | None |
| Search analytics | Read | Read | None |
| Knowledge base | Every file and folder | Every file and folder | What is shared with them |

Generated content means the drafts and published content Senso writes for you, not the files in your knowledge base. Knowledge base access works differently, and is covered below.

Roles apply to people. An API key has no role, so it is never refused for one.

### Permission keys

Each role is a set of permission keys, written `action:resource`. Admins hold every key below.

| Area | Keys | Collaborator | Viewer |
|------|------|--------------|--------|
| Organization | `read:org`, `update:org`, `delete:org` | `read:org` | `read:org` |
| Members | `list:org_users`, `read:org_user`, `add:org_user`, `update:org_user`, `remove:org_user` | `list:org_users`, `read:org_user` | `list:org_users`, `read:org_user` |
| Users | `read:user` | All | All |
| Roles | `list:org_roles` | All | All |
| Groups | `list:groups`, `create:group`, `update:group`, `delete:group` | None | None |
| API keys | `list:api_keys`, `read:api_key`, `create:api_key`, `update:api_key`, `delete:api_key`, `revoke:api_key` | None | None |
| Credits | `read:credits` | None | None |
| Generated content | `list:content`, `read:content`, `search:content`, `create:content`, `update:content`, `delete:content` | All | None |
| Prompts | `list:prompts`, `read:prompt`, `create:prompt`, `update:prompt`, `delete:prompt` | All | `list:prompts`, `read:prompt` |
| Categories | `list:categories`, `read:category`, `create:category`, `update:category`, `delete:category` | All | `list:categories`, `read:category` |
| Topics | `list:topics`, `read:topic`, `create:topic`, `update:topic`, `delete:topic` | All | `list:topics`, `read:topic` |
| Templates | `list:templates`, `read:template`, `create:template`, `update:template`, `delete:template` | All | `list:templates`, `read:template` |
| Tags | `read:tag`, `create:tag`, `update:tag`, `delete:tag` | All | None |
| Brand kit | `read:brand_kit`, `update:brand_kit` | All | None |
| Content types | `read:content_type`, `update:content_type` | All | None |
| Product lines | `read:product_line`, `update:product_line` | All | None |
| Search analytics | `read:search_analytics` | All | None |
| Knowledge base | `bypass:kb_acl`, `kb:create_at_root` | All | None |

A few keys cover more than their names say. `update:org` covers competitors, tracked sources, publishing destinations, AI models and the run schedule. `update:prompt` covers adding, changing and deleting prompts. `update:content` covers generation settings and runs.

`bypass:kb_acl` is what gives admins and collaborators every file and folder in the knowledge base. `kb:create_at_root` lets them add files and folders at the top level.

`senso permissions list` and `GET /org/permissions` return the keys with a name and description for each.

## Knowledge base access

Every file and folder in your knowledge base has its own access, separate from roles.

- **Admins and collaborators** reach every file and folder.
- **Viewers** reach only the files and folders shared with them, shared with a group they belong to, or made public.
- **API keys** reach every file and folder, unless you restrict the key. See API key access, below.

Search follows the same rules. A search only returns passages from files the person or key can reach.

**Without at least `viewer` access, a file or folder answers `404`**, exactly as if it did not exist. This applies to people and API keys, and to reads and changes alike, so Senso never reveals what you cannot see. A `403` means you can see the file or folder but your role on it does not allow the change.

### Knowledge base roles

Each grant of access gives one of these roles on a file or folder:

| Role | What it allows | How it is given |
|------|----------------|-----------------|
| `viewer` | View and download, and find it in search | Shared with a person or group, or given to a restricted API key |
| `editor` | Everything a viewer can do, plus add, change, delete and share | Shared with a person or group, or given to a restricted API key |
| `owner` | The same as `editor` | Given to a viewer or restricted API key that creates the file or folder |

### Inheritance

**Access flows down.** Access to a folder covers everything inside it, however deep.

```
Root
├── Public Docs/          ← shared with Sam as "viewer"
│   ├── faq.pdf           ← "viewer"
│   └── Guides/           ← "viewer"
│       └── setup.md      ← "viewer"
├── Internal/             ← not shared with Sam, so no access
│   └── roadmap.docx      ← no access
```

Where two grants reach the same file, for example one shared with you and one shared with your group, **the more permissive role wins**.

## Share a file or folder

To share, you need `editor` or `owner` on the file or folder. Admins and collaborators can share anything.

In the Senso app:

1. In the knowledge base, open the **…** menu on a file or folder and click **Share**.
2. Choose **Group** or **User**, then pick who to share with.
3. Choose **Viewer** or **Editor**.

The same panel has a **Public access** switch. Turning it on gives everyone in your organization `viewer` access to the file or folder and everything inside it.

With the CLI:

```bash
senso kb permissions list <id>
senso kb permissions add <id> --grantee-type user --grantee-id <userId> --role viewer
senso kb permissions update <id> <permissionId> --role editor
senso kb permissions remove <id> <permissionId>
```

The `user_id` is in the response when you invite someone, and `senso users list` shows each member's `user_id` and role. With the API, send the same fields to the file or folder:

```bash
curl -X POST "https://apiv2.senso.ai/api/v1/org/kb/nodes/{id}/permissions" \
  -H "X-API-Key: $SENSO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"grantee_type": "user", "grantee_id": "<userId>", "role": "viewer"}'
```

A few rules apply wherever you share from:

- Only `viewer` and `editor` can be given. `owner` is only ever given automatically.
- A person or group has one grant per file or folder. Sharing again returns `409`, so use update to change the role.
- A signed-in person cannot change or remove their own grant.

### Groups

A group lets you share with several people at once. Admins create groups and add members in the Senso app, under **Org Settings → Group Management**. Deleting a group removes the access its members had through it.

**Share with a group in the Senso app.** An API key cannot see your groups, so the CLI and API keys can only share with people. For the same reason, `senso kb permissions list` shows only the grants to people.

Every organization also has a built-in **Public** group that everyone belongs to. Making a file or folder public gives that group `viewer` access.

## API key access

**A new key reaches your whole knowledge base**, and can add and change anything in it. Restrict a key when an integration should only see part of it, for example "Public Docs" but not "Internal".

A restricted key:

- only reaches the files and folders you chose, and everything inside them
- only gets search results and folder listings from what it can reach
- needs `editor` on a folder to add or change anything in it

An admin restricts a key on the [API Keys](https://docs.senso.ai/api-keys) page by clicking the gear icon (**Configure KB scope**) on the key, giving it `viewer` or `editor` on each file or folder. A key cannot change any key's access, including its own. [API Keys](https://docs.senso.ai/docs/api-keys) has the steps.

Any key can read a key's restrictions, including its own. Get the key's ID from `senso api-keys list`. An empty list means the key has full access:

```bash
curl "https://apiv2.senso.ai/api/v1/org/api-keys/{keyId}/kb-permissions" \
  -H "X-API-Key: $SENSO_API_KEY"
```

Or `senso api-keys kb-permissions-get <keyId>`.

> One key per integration, restricted to what it needs. Then revoking one breaks nothing else.

## Examples

| Who | Set up as | Result |
|-----|-----------|--------|
| Content lead | `collaborator` | Reaches every file, writes and edits content and prompts. Cannot manage members or API keys. |
| Contractor | `viewer`, with "Public Docs" shared as `viewer` | Reads and searches Public Docs only, and cannot change anything. |
| Contractor who writes docs | `viewer`, with "Drafts" shared as `editor` | Adds and edits files in Drafts only. Can read prompts but not change them. |
| Internal agent | API key, unrestricted | Reaches everything, and can add, search and generate. |
| Customer-facing chatbot | API key, `viewer` on "Public Docs" | Searches Public Docs only. |
| Ingestion pipeline | API key, `editor` on "Uploads" | Adds files to Uploads, and cannot see anything else. |

## When access is denied

Every error response has a `message` that says what went wrong.

| Status | Message | What it means |
|--------|---------|---------------|
| `401` | "Organization API key or valid JWT token required" | The API key is missing, wrong, expired or revoked. |
| `403` | "You don't have permission to perform this action" | Your role does not allow this. Only people signed in to the Senso app see this, since an API key has no role. |
| `403` | "You do not have permission to modify this resource" | You can see this file or folder, but as a `viewer` you cannot change it. Other actions have similar messages. |
| `403` | "This action requires user authentication" | Only a signed-in person can do this, for example managing API keys. Do it on the [API Keys](https://docs.senso.ai/api-keys) page. |
| `404` | "Node not found", "Folder not found" or "Parent folder not found" | You do not have at least `viewer` access to this file or folder, or it does not exist. Senso answers the same way for both. |

More on every status in [Errors](https://docs.senso.ai/docs/errors).

## Next steps

- [API Keys](https://docs.senso.ai/docs/api-keys) — How keys work, and how to create, restrict and revoke one
- [Errors](https://docs.senso.ai/docs/errors) — Every status the API returns
- [CLI Reference](https://docs.senso.ai/docs/cli-reference) — Every `senso users`, `roles` and `kb permissions` command
- [API Reference](https://docs.senso.ai/api-reference) — Every endpoint, including roles, permissions and sharing
