Scopes
Every capability an app can use is gated by a scope. An app declares the scopes it needs in its block.manifest.json; a moderator reviews them; and at runtime the host mints a short-lived block token carrying only the approved-and-granted subset. The block never holds a long-lived credential.
The table below is generated from the civitai scope constants — the same source the manifest validator and the token minter read.
| Scope | What it authorizes | OAuth bit | Binding |
|---|---|---|---|
models:read:self | Read the model on the page where the block is mounted | ModelsRead | Bound to the model on the page where the block is mounted (a model-slot install supplies the modelId context). |
media:read:owned | Read the viewer's own uploaded media | MediaRead | Self-bound: only the viewer's own uploaded media. |
user:read:self | Read the viewer's username and account status | UserRead | Self-bound to the token subject; rejected for an anonymous subject. |
ai:write:budgeted | Submit generations with a per-call Buzz cap | AIServicesWrite | Host-enforced per-call Buzz cap; the token carries a buzzBudget claim the host clamps against. |
buzz:read:self | Read the viewer's Buzz balance | BuzzRead | Self-bound to the token subject (the signed-in viewer). |
block:settings:read | Read this block's per-install settings | — | No OAuth bit — gated by the issuance-time caller-is-installer check instead. |
block:settings:write | Update this block's per-install settings | — | No OAuth bit — gated by the issuance-time caller-is-installer check instead. |
social:tip:self | Post tips on behalf of the viewer | SocialTip | Self-bound: tips are posted as the token subject. |
apps:storage:read | Read this app's private per-install data store | — | Scoped to this app's private per-install store; asserted per read op. |
apps:storage:write | Write to this app's private per-install data store | — | Scoped to this app's private per-install store; asserted per write op. |
apps:storage:shared:read | Read this app's shared, community-wide data (e.g. everyone's posts + vote counts) | — | Scoped to this app's shared (cross-user) store; min-trust gate + fail-closed flag. Never minted for dev-tunnel / dev-token sessions. |
apps:storage:shared:write | Post + vote in this app's shared, community-wide data — visible to all users of the app | — | Scoped to this app's shared (cross-user) store; min-trust gate + fail-closed flag. Never minted for dev-tunnel / dev-token sessions. |
collections:read:self | Browse and read public Civitai collections, and your own public collections | — | Self-bound; public collections + the viewer's own public collections. Consent-exempt (server visibility/ownership is the gate). |
collections:write:self | Bookmark (follow) collections on your behalf | — | Self-bound: follow/bookmark on the viewer’s own behalf. Consent-exempt. |
collections:read:private | Read your private collections | — | Self-bound; CONSENT-GATED — the viewer must grant it via the host consent gate before a token carries it. |
How to read this table
- Scope — the exact string you put in
manifest.scopes. - What it authorizes — the capability it unlocks.
- OAuth bit — the underlying
OauthClient.allowedScopesbit this scope maps to. Your app's manifest scopes must be a strict subset of the OAuth client's allowed bits (a registration-time gate, re-checked at token issuance). A—means the scope has no OAuth bit and is gated by another mechanism (noted in Binding) rather than the bitmask. - Binding — how the scope is constrained at runtime.
:selfscopes are bound to the token subject (the signed-in viewer) and are rejected for an anonymous subject; model-slot scopes require the model context from the page the block is mounted on.
What this table can't show (the server enforces more)
- Consent gating. Most self-reads are consent-exempt (server visibility is the gate), but some scopes — notably
collections:read:private— are consent-gated: the viewer must grant them through the host consent gate before a token will carry them. - Dev-token / dev-tunnel restrictions. The shared-storage scopes (
apps:storage:shared:*) are deliberately never minted for pre-approval dev sessions; only an approved, mod-reviewed app that declares them gets them. - Per-op assertions. Storage scopes are asserted per operation (a read scope can't perform a write) on the server side, independent of what the token carries.
If a scope you declare isn't approved, granted, or in-context, the corresponding host call fails closed — design your app to degrade gracefully.