Permissions
HappyView uses a granular permission system to control access to the admin API. Each user has a set of permissions that determine which endpoints they can access. Permissions can be assigned individually, via templates, or both.
Permission list
Section titled “Permission list”HappyView defines 51 permissions organized by category:
Lexicons
Section titled “Lexicons”| Permission | Description |
|---|---|
lexicons:create | Upload and register new lexicon schemas |
lexicons:read | View registered lexicon schemas |
lexicons:delete | Remove lexicon schemas |
lexicons:publish | Publish lexicons to the network and manage publishing rules |
Records
Section titled “Records”| Permission | Description |
|---|---|
records:read | Browse indexed atproto records |
records:delete | Delete individual records from the index |
records:delete-collection | Bulk-delete all records in a collection |
Scripts
Section titled “Scripts”| Permission | Description |
|---|---|
scripts:read | View trigger-keyed scripts |
scripts:manage | Create, update, and delete trigger-keyed scripts |
Script Variables
Section titled “Script Variables”| Permission | Description |
|---|---|
script-variables:create | Add or update environment variables for Lua scripts |
script-variables:read | View script environment variable keys and values |
script-variables:delete | Remove script environment variables |
| Permission | Description |
|---|---|
users:create | Add new dashboard users |
users:read | View the user list and their permissions |
users:update | Modify user permissions |
users:delete | Remove dashboard users |
API Keys
Section titled “API Keys”| Permission | Description |
|---|---|
api-keys:create | Generate new API keys for admin access |
api-keys:read | View existing API keys |
api-keys:delete | Revoke existing API keys |
Backfill
Section titled “Backfill”| Permission | Description |
|---|---|
backfill:create | Trigger historical record backfill jobs |
backfill:read | View backfill job status and progress |
Labelers
Section titled “Labelers”| Permission | Description |
|---|---|
labelers:create | Subscribe to external labeler services |
labelers:read | View subscribed labeler services |
labelers:delete | Unsubscribe from labeler services |
Settings
Section titled “Settings”| Permission | Description |
|---|---|
settings:manage | Modify instance settings, logo, and configuration |
Plugins
Section titled “Plugins”| Permission | Description |
|---|---|
plugins:read | View installed plugins and their configuration |
plugins:create | Install and configure new plugins |
plugins:delete | Uninstall plugins |
API Clients
Section titled “API Clients”| Permission | Description |
|---|---|
api-clients:view | View registered OAuth API clients |
api-clients:create | Register new OAuth API clients |
api-clients:edit | Modify API client settings and credentials |
api-clients:delete | Remove registered API clients |
Dead Letters
Section titled “Dead Letters”| Permission | Description |
|---|---|
dead-letters:read | View failed hook executions |
dead-letters:manage | Retry, re-index, or dismiss dead letters |
Spaces
Section titled “Spaces”| Permission | Description |
|---|---|
spaces:create | Create new permissioned data spaces |
spaces:read | View space details, metadata, and members |
spaces:update | Modify space settings |
spaces:delete | Remove spaces and their data |
spaces:manage-members | Add or remove space members and roles |
spaces:manage-invites | Create and revoke space invitations |
spaces:manage-records | Read and write records within spaces |
spaces:manage-credentials | Issue and revoke space access credentials |
| Permission | Description |
|---|---|
jobs:read | View background job status and progress |
jobs:create | Queue new background jobs |
jobs:manage | Cancel, pause, and resume background jobs |
Linked Repos
Section titled “Linked Repos”| Permission | Description |
|---|---|
linked-repos:read | View linked repos, their status, and their outstanding invites |
linked-repos:create | Add linked repos, start authorizations, mint and revoke invites |
linked-repos:delete | Revoke linked repos and delete their stored sessions |
Revoking an invite uses linked-repos:create rather than linked-repos:delete, because minting and revoking are one lifecycle. linked-repos:delete is reserved for destroying a grant and the OAuth session behind it. See Linked Repos.
Project
Section titled “Project”| Permission | Description |
|---|---|
project:deploy | Replace the instance’s project with a deployed bundle and start the backfills it declares |
It also covers reading what is deployed. A deploy can add, change and remove every lexicon and script the project owns, so it is as strong as lexicons:create, lexicons:delete and scripts:manage together, plus backfill:create for the backfills a project declares. See Project.
System
Section titled “System”| Permission | Description |
|---|---|
stats:read | View collection statistics and record counts |
events:read | View the event log |
events:purge | Bulk-delete event log entries matching a filter |
Permission templates
Section titled “Permission templates”Templates are predefined sets of permissions that simplify adding an operator. Pass a template value when creating one via POST /admin/users. A template is named after a level of access, not a kind of person: every one of them is given to an operator, including the Operator template.
Viewer template
Section titled “Viewer template”Read-only access. Can browse lexicons, records, scripts, stats, events, dead letters, and user lists but cannot modify anything.
Includes: lexicons:read, records:read, scripts:read, script-variables:read, users:read, api-keys:read, backfill:read, stats:read, events:read, dead-letters:read
Operator template
Section titled “Operator template”Everything in the Viewer template, plus the ability to run backfill jobs, manage API keys, and manage dead letters.
Adds: backfill:create, api-keys:create, api-keys:delete, dead-letters:manage
Manager template
Section titled “Manager template”Everything in the Operator template, plus the ability to manage and publish lexicons, records, scripts, labelers, settings, plugins, API clients, and spaces, and to deploy the project.
Adds: lexicons:create, lexicons:delete, lexicons:publish, scripts:manage, project:deploy, script-variables:create, script-variables:delete, records:delete, labelers:create, labelers:read, labelers:delete, settings:manage, plugins:read, plugins:create, plugins:delete, api-clients:view, api-clients:create, api-clients:edit, api-clients:delete, spaces:create, spaces:read, spaces:update, spaces:delete, spaces:manage-members, spaces:manage-invites, spaces:manage-records, spaces:manage-credentials
Full Access template
Section titled “Full Access template”All 52 permissions. Equivalent to granting every permission individually (but still not superadmin).
Superadmin
Section titled “Superadmin”Superadmin is a privilege one operator holds. On a fresh instance, the first person to sign in becomes an operator with it, unless SUPERADMIN_DID names someone else. The dashboard marks that operator Owner. The operator with superadmin:
- Has unrestricted access to all endpoints, regardless of which permissions are assigned
- Is the only operator who can call
POST /admin/users/transfer-super - Cannot be deleted
- Cannot have their permissions modified by other operators
Usually one operator holds superadmin. A transfer, from the dashboard or the transfer endpoint in the Admin API, moves it to another operator and takes it from the previous holder. SUPERADMIN_DID only adds: the configured account gets superadmin at every boot, and anyone else who holds it keeps it.
Escalation guards
Section titled “Escalation guards”HappyView prevents privilege escalation:
- When creating a user or API key, you can only grant permissions that you yourself have. Attempting to grant a permission you lack returns
403 Forbidden. - When updating a user’s permissions, the same rule applies — you cannot grant permissions beyond your own.
Self-modification guards
Section titled “Self-modification guards”Users cannot modify their own account in destructive ways:
- You cannot delete yourself
- You cannot revoke your own permissions
These guards prevent accidental lockout.
API key permissions
Section titled “API key permissions”API keys have their own set of permissions, specified at creation time. The effective permissions of an API key are the intersection of:
- The permissions assigned to the key
- The permissions of the user who owns the key
This means if a user’s permissions are later reduced, any API keys they created are also effectively reduced — even though the key’s own permission list doesn’t change.
For example, if a user with lexicons:create and lexicons:read creates a key with both permissions, and the user later loses lexicons:create, the key can only use lexicons:read.
Managing permissions
Section titled “Managing permissions”Via the dashboard
Section titled “Via the dashboard”Go to Access > Users to view and manage user permissions. Click on a user to see their current permissions and modify them. You can also assign templates when creating new users.
Via the API
Section titled “Via the API”POST /admin/users— create a user with a template or explicit permissionsPATCH /admin/users/{id}/permissions— grant or revoke individual permissionsPOST /admin/users/transfer-super— pass superadmin to another operator (superadmin only)
See the Admin API — Users for full details.
Next steps
Section titled “Next steps”- Admin API reference — endpoint documentation with required permissions
- API Keys — creating scoped API keys
- Event Logs — permission-denied events are logged for auditing

