Scopes
Every API key carries a fixed set of scopes chosen at creation time. The access token derived from the key inherits those scopes, and every protected endpoint is guarded by an x-required-scopes declaration. If the calling token's scopes don't cover the operation's required scopes, the request returns 403 Forbidden.
Scopes are immutable on a key — to change permissions, mint a new key with the desired scopes and revoke the old one. There's no in-place edit.
How Scopes Compose
Most families follow the pattern <family>:<verb>, where verbs are usually read / create / update / delete. Several families also expose a * wildcard that grants every verb in that family:
workflow:read ← grants only that verb
workflow:* ← grants read, create, update, execute (everything in the family)
Scopes are additive — listing both workflow:read and workflow:create grants both. Wildcards subsume the family they belong to, so workflow:* makes the per-verb workflow scopes redundant.
Scope Catalog
| Family | Scope | Grants |
|---|---|---|
| Organization | organization:read |
Read the calling user's organization |
organization:update |
Update organization settings | |
| User | user:read |
Read user records |
user:create |
Create users | |
user:update |
Update user records | |
| Billing | billing:read |
View invoices, plan, usage |
billing:manage |
Manage billing subscription | |
| Namespace | namespace:read |
List and inspect namespaces |
namespace:create |
Provision new namespaces | |
namespace:update |
Update namespace settings, branding | |
namespace:* |
All namespace verbs | |
| API Key | api-key:read |
List API keys (no secret material) |
api-key:create |
Mint new API keys | |
api-key:delete |
Revoke API keys | |
api-key:* |
All API-key verbs | |
| Embed Token | embed-token:create |
Mint embed tokens for the four <ss-*> web components |
| Resource (covers all primitives: blueprints, templates, schemas, assets, functions) | resource:read |
Read primitives |
resource:create |
Create primitives (drafts) | |
resource:update |
Update drafts; publish new versions | |
resource:delete |
Delete drafts | |
resource:* |
All resource verbs | |
| Workflow | workflow:read |
Read workflows + their state |
workflow:create |
Create workflows from blueprints | |
workflow:update |
Update workflow data, add documents, void | |
workflow:execute |
Process steps, send for signatures, advance state | |
workflow:* |
All workflow verbs | |
| Signing | signing:sign |
Submit a participant signature (used by signing-session embed tokens) |
| Scenario | scenario:read |
Read scenarios |
scenario:create |
Create scenarios | |
scenario:update |
Update scenarios; link/unlink scenarios to resources | |
scenario:delete |
Delete scenarios | |
scenario:* |
All scenario verbs | |
| Webhook | webhook:read |
Read webhook configs and delivery logs |
webhook:create |
Configure new webhook endpoints | |
webhook:update |
Update webhook configs | |
webhook:delete |
Delete webhook configs | |
webhook:* |
All webhook verbs | |
| File | file:read |
Download files (assets, rendered docs) |
file:upload |
Upload files for use in templates / workflows | |
| AI Chat | ai-chat:use |
Invoke SignStack's AI helpers — used by Studio's in-app AI assistant, CLI generation/modify commands, and the embedded resource-editor's AI features |
| Library | library:publish |
Publish primitives to the Library |
Common Scope Sets
Pre-canned recipes for typical integration patterns. Add or remove individual scopes as needed.
Backend that authors and runs workflows
The most common server-to-server case — your backend creates blueprints/templates and launches workflows.
{
"scopes": [
"resource:read",
"resource:create",
"resource:update",
"workflow:read",
"workflow:create",
"workflow:execute",
"file:read",
"file:upload",
"webhook:read"
]
}
Backend that mints embed tokens for a customer-facing UI
If your backend serves a customer-facing surface that mounts SignStack web components, you need to read the resources you're embedding plus mint embed tokens.
{
"scopes": [
"resource:read",
"workflow:read",
"workflow:create",
"embed-token:create",
"file:read"
]
}
CI/CD pipeline (push primitives only)
A pipeline key that pushes blueprint/template changes from your repo on merge.
{
"scopes": [
"resource:read",
"resource:create",
"resource:update"
]
}
Multi-tenant provisioning
A back-office key that provisions per-tenant namespaces and mints their starter API keys.
{
"scopes": [
"namespace:*",
"api-key:create",
"api-key:read"
]
}
Full-access (use sparingly)
For internal admin tooling only. Avoid for any externally-touchable system.
{
"scopes": [
"resource:*",
"workflow:*",
"scenario:*",
"webhook:*",
"namespace:*",
"api-key:*",
"file:read",
"file:upload",
"embed-token:create"
]
}
When a Request Returns 403
If you get a 403 Forbidden, the response body's errorInfo.message names the missing scope:
{
"statusCode": 403,
"errorInfo": {
"message": "Token lacks required scope: workflow:create"
}
}
The fix is always the same: mint a new API key with the required scope added. Existing keys cannot have scopes added or removed after creation.
To check what an endpoint requires, look at the operation's x-required-scopes field in the API reference.
Related
- A Full Guide to API Keys and JWTs — credential lifecycle
- Error Handling — full error model and retry patterns
- Namespaces — how namespace + mode interact with scopes
