Files
papercrate/docs/capability_sets.md
nils 3c9a9fc060
ci / docker (backend, backend/Dockerfile, backend) (push) Failing after 13s
ci / docker (frontend, frontend/Dockerfile, frontend) (push) Failing after 12s
Initial commit
2025-12-17 13:37:31 +01:00

101 lines
3.9 KiB
Markdown

# Capability Sets
Capability sets are the tenant-scoped bundles of REST and WebDAV permissions. Every user membership and API token now references one of these sets, and the capability guard middleware enforces the scopes on every route.
## Enumerated Capabilities
All capabilities live in the `ApiCapability` enum. The current list is:
- `documents:read`
- `documents:edit`
- `documents:write`
- `documents:upload`
- `folders:read`
- `folders:edit`
- `folders:write`
- `tags:read`
- `tags:edit`
- `tags:write`
- `correspondents:read`
- `correspondents:edit`
- `correspondents:write`
- `profile:read`
- `profile:write`
- `webdav:read`
- `webdav:write`
- `capability_sets:read`
- `capability_sets:write`
## Default Sets
Provisioning (and the test harness) seed four system capability sets per tenant:
- `owner` — contains the full set above. Tenant owners, admin users, and freshly minted API tokens effectively get unrestricted access.
- `user` — the default interactive role: full document/tag/correspondent/profile access, but no capability-set or WebDAV write privileges.
- `readonly` — interactive but read-only: document/folder/tag/correspondent reads plus WebDAV downloads, but no modifying routes.
- `webdav` — contains only `webdav:read`. WebDAV backup scripts can bind to this set for read-only access.
System sets are flagged with `is_system = true` and cannot be modified or deleted via the API.
## REST API
The capability-set endpoints live at `/api/capability-sets` and require the new admin capabilities:
| Method & Path | Capability | Description |
|----------------------------------------|-------------------------|-----------------------------------------|
| `GET /api/capability-sets` | `capability_sets:read` | List all sets for the tenant |
| `POST /api/capability-sets` | `capability_sets:write` | Create a new set |
| `GET /api/capability-sets/{id}` | `capability_sets:read` | Fetch details of a specific set |
| `PATCH /api/capability-sets/{id}` | `capability_sets:write` | Replace capabilities / rename the set |
| `DELETE /api/capability-sets/{id}` | `capability_sets:write` | Remove a custom set (must be unused) |
### Examples
Create a read-only set:
```bash
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://app.papercrate.org/api/capability-sets \
-d '{
"slug": "api_readonly",
"capabilities": [
"documents:read",
"folders:read",
"tags:read"
]
}'
```
Update an existing set:
```bash
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
https://app.papercrate.org/api/capability-sets/$SET_ID \
-d '{
"capabilities": ["documents:read", "documents:edit"]
}'
```
Delete (fails if still referenced by memberships or tokens):
```bash
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
https://app.papercrate.org/api/capability-sets/$SET_ID
```
## Assigning Sets
- **User memberships**: change the `capability_set_id` column (via future admin APIs or direct SQL) to reassign a user. The authentication pipeline will enforce the new capabilities automatically.
- **API tokens**: `POST /api/profile/api-tokens` requires a `capability_set_id`. Tokens are bound to the selected set; raw capability arrays are no longer accepted.
## Guard Coverage
The `RequireCapabilitiesLayer` middleware wraps all protected routers (documents, folders, tags, correspondents, profile, capability sets, assets). Requests missing the necessary capability now terminate with a 403 containing `missing_capability` details.
Integration tests in `backend/tests/capability_guards_flow.rs` ensure read-only users cannot upload or manage capability sets, and WebDAV tokens without `webdav:read` are rejected (`backend/tests/api_tokens_flow.rs`).