Every protected request must pass two independent authorization layers:
- the service account has the exact API scope required by the operation;
- its active run-as member is authorized for the organization, workspace, and object.
A broad run-as role cannot compensate for a missing API scope, and a broad scope cannot bypass the run-as member's product authorization.
Scope matrix
| Scope | Applies to | Examples |
|---|---|---|
api_read |
Safe JSON:API methods and GraphQL factQuery |
List workflows, retrieve runs, query facts |
api_write |
Unsafe JSON:API operations | Create a dashboard, update a data model, activate a workflow |
webhooks |
Inbound webhook delivery | POST /api/v1/webhooks/:token for the trigger selecting this account |
The public health GraphQL field requires no credential. No public GraphQL
mutations or subscriptions are exposed. Each endpoint page in the
API reference displays the exact required scope next to its method
and path.
Run-as behavior
Choose a real, active organization member whose access represents the integration's intended owner. Requests execute inside the service account's stored workspace. Object policies can further restrict a read or write, such as self-only profile access or owner-only organization changes.
If that membership becomes inactive, the account's requests stop succeeding even when its bearer token has not expired. Changing a member's role can also change visible objects and allowed writes immediately.
Use a dedicated integration member where operational ownership needs a stable, auditable boundary. Do not select the most privileged person merely because it avoids permission design.
How failures appear
401 unauthorizedmeans authentication failed: the token is absent, invalid, expired, or the underlying account is no longer valid.403 forbiddenorinsufficient_scopemeans the identity is known but the required scope or policy is not satisfied.404 not_foundcan protect object existence when the run-as member cannot see a resource. Do not treat it as proof that the object does not exist elsewhere.
Keep the x-request-id from any failed response. Never include the bearer token
when sharing diagnostics.
Least-privilege patterns
- Separate reporting (
api_read) from automation that writes (api_write). - Grant
webhooksonly to the account selected by the webhook trigger. - Use separate service accounts for separate workspaces and vendors.
- Remove a scope before deleting an integration so runtime revalidation cuts access immediately.
- Review reference pages before adding
api_write; not every internal action is publicly exposed.
Continue with Perform an idempotent write or Sender authentication and signatures.