Generated from source at build time — this page cannot drift from the running service.
Scopes
Inbox has 6 scopes. They are granted in Axis Accounts under the inbox:
prefix and mapped onto a shorter local vocabulary inside the service — the prefix exists because an
Accounts key is not app-exclusive, so inbox:threads must not collide with another app's scopes.
| Accounts scope | Local scope | Routes | What it grants |
|---|---|---|---|
inbox:connections |
connections |
22 | Connect, list, disconnect and reconnect social accounts |
inbox:threads |
inbox |
139 | Read inbox threads and entries; reply and moderate |
inbox:publish |
publish |
7 | Create, schedule and cancel posts |
inbox:admin |
admin |
25 | Webhook endpoints, webhook inbox and break-glass operations |
inbox:stats |
stats |
8 | Read-only CROSS-TENANT operator/admin figures (dashboard operator view). No tenant scope; grants no access to any tenant-scoped resource. |
inbox:connections:write |
operator:connections:write |
— | CROSS-TENANT operator WRITE: action connection requests from the dashboard — approve/reject, enter provider credentials, run a test. Requires inbox:stats for reachability; not implied by inbox:admin. |
Scopes Accounts grants that Inbox does not recognise are ignored, not rejected. A key that also
carries intelligence:* works fine here; those scopes simply grant nothing.
The two rules that surprise people
admin is a superset — but only on tenant-scoped routes. ScopeGuard treats admin as
satisfying every @RequireScopes check. OperatorGuard does not: a cross-tenant route needs
stats explicitly, because an admin key confined to one workspace must never be able to read
the whole estate's figures.
operator:connections:write is meaningless on its own. It is checked on top of the stats
reachability check, so a key needs both. Grant them together or not at all.
Registering the catalogue
A scope must exist in Accounts before a key can be issued with it. The service publishes its own catalogue:
cd apps/service && yarn register-scopes --app <appId|slug>
This is a full replace of the app's catalogue, so it always sends the whole list. It needs
INBOX_ACCOUNTS_SERVICE_KEY to hold the native app-scopes:write scope, plus stats:read if
you pass a slug rather than a UUID.