Docs restructuring: category grouping (Getting Started, Platform, Extension Development, Operations) with 14 ordered docs. Four new guides: Permissions & Groups, Workflows, Starlark Reference, Frontend JS Guide. Extension Guide updated with config_section docs. Content refresh across 10 existing docs: rebrand volume names, stale CSS vars, TLS_MODE env, self-hosted font notes, Architecture frontend section. Team Admin workflows.js (722 lines) split into 3 modules: workflows.js (router+CRUD), workflow-editor.js (editor+stages), workflow-monitor.js (assignments+monitor+signoff). Fix: docs outline scroll no longer pushes topbar off-screen. Fix: --bg-2 (undefined CSS var) replaced with --bg-secondary. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
122 lines
4.4 KiB
Markdown
122 lines
4.4 KiB
Markdown
# Permissions & Groups
|
|
|
|
Armature uses group-based RBAC. Permissions are granted to groups, and users
|
|
inherit the union of permissions from all groups they belong to. There are no
|
|
per-user permission grants — all access flows through group membership.
|
|
|
|
## Groups
|
|
|
|
### System groups
|
|
|
|
| Group | ID | Purpose |
|
|
|-------|----|---------|
|
|
| Everyone | `00000000-...0001` | Implicit membership for every authenticated user. Default permissions: `extension.use`, `workflow.submit`. |
|
|
| Admins | `00000000-...0002` | Full platform access. Members receive all seven permission slugs. Replaces the legacy `role = admin` check. |
|
|
|
|
Every new user is automatically added to **Everyone** on registration.
|
|
Admin status is granted by adding a user to the **Admins** group in
|
|
**Admin > People > Groups**.
|
|
|
|
### Custom groups
|
|
|
|
Administrators can create additional groups under **Admin > People > Groups**.
|
|
Each custom group has:
|
|
|
|
- **Name** — display label
|
|
- **Description** — purpose (shown in admin UI)
|
|
- **Scope** — always `global` (team-scoped groups reserved for future use)
|
|
- **Permissions** — zero or more permission slugs from the table below
|
|
|
|
## Permission slugs
|
|
|
|
Seven platform permissions control access to kernel features:
|
|
|
|
| Slug | Description |
|
|
|------|-------------|
|
|
| `surface.admin.access` | Full admin panel access (tabs, settings, package management) |
|
|
| `admin.view` | Read-only admin panel access (monitoring, health, audit log) |
|
|
| `extension.use` | Use installed extension surfaces and libraries |
|
|
| `extension.install` | Install, update, enable, and disable packages |
|
|
| `workflow.create` | Create and edit workflow definitions |
|
|
| `workflow.submit` | Submit instances to public-link workflows |
|
|
| `token.unlimited` | Bypass per-user token budgets (API rate limiting) |
|
|
|
|
Permissions follow a `domain.action` naming convention.
|
|
|
|
## Permission resolution
|
|
|
|
When a request arrives, the kernel resolves the effective permission set:
|
|
|
|
1. Fetch all groups the user belongs to (including Everyone).
|
|
2. Union all permission arrays across those groups.
|
|
3. Cache the result for the duration of the request.
|
|
|
|
A user has a permission if **any** of their groups grants it.
|
|
|
|
Frontend code checks permissions via `sw.can('slug')` — see the
|
|
[Frontend JS Guide](FRONTEND-JS-GUIDE) for details.
|
|
|
|
## Extension permissions
|
|
|
|
Separate from user permissions, each **package** can request sandbox
|
|
capabilities. These are granted per-package in **Admin > Packages**:
|
|
|
|
| Permission | Grants |
|
|
|------------|--------|
|
|
| `db.read` | Query `ext_data` tables (read-only) |
|
|
| `db.write` | Insert, update, and delete rows in `ext_data` tables |
|
|
| `api.http` | Make outbound HTTP requests from Starlark |
|
|
| `notifications.send` | Send in-app notifications to users |
|
|
| `secrets.read` | Read admin-configured extension secrets |
|
|
| `realtime.publish` | Publish WebSocket events to subscribed clients |
|
|
| `connections.read` | Read external connection configs (decrypted) |
|
|
| `workflow.access` | Read workflow definitions and instances |
|
|
|
|
See the [Starlark Reference](STARLARK-REFERENCE) for how these
|
|
map to sandbox modules.
|
|
|
|
## Settings cascade
|
|
|
|
Package settings use a three-tier resolution model:
|
|
|
|
```
|
|
user override → team override → global default
|
|
```
|
|
|
|
At each tier:
|
|
|
|
- **Global** — set by admins in **Admin > Packages > Settings**
|
|
- **Team** — set by team admins in **Team Admin > Settings**
|
|
- **User** — set by users in **Settings > Extensions**
|
|
|
|
### The `user_overridable` flag
|
|
|
|
Each setting key in a package manifest can declare `user_overridable`:
|
|
|
|
```json
|
|
{
|
|
"settings": [
|
|
{ "key": "theme", "user_overridable": true },
|
|
{ "key": "api_endpoint", "user_overridable": false }
|
|
]
|
|
}
|
|
```
|
|
|
|
- `true` (default) — team and user scopes can override the global value.
|
|
- `false` — only the global (admin) value is used. Team and user values
|
|
are silently ignored during resolution.
|
|
|
|
This gives administrators a lock mechanism: set `user_overridable: false`
|
|
on security-sensitive keys to prevent lower scopes from changing them,
|
|
while allowing cosmetic preferences to flow freely.
|
|
|
|
### Resolution algorithm
|
|
|
|
1. Start with the global value for each key.
|
|
2. For each key where `user_overridable` is true (or undeclared):
|
|
- If a team-scoped value exists, it overrides global.
|
|
- If a user-scoped value exists, it overrides team.
|
|
3. For keys where `user_overridable` is false:
|
|
- Team and user values are discarded.
|
|
4. Unknown keys (not in schema) default to overridable.
|