OAuth

OAuth Scopes

The supported OAuth/OIDC scopes and what each one grants your app permission to do on the user's workspace.

OAuth Scopes

Scopes are the permissions your app asks for at the consent screen. Request the minimum: users are more likely to authorize, and the consent screen renders cleaner when you don't ask for everything.

The user can grant a subset of the scopes you request (by unchecking individual ones on the consent screen). Your app must handle that gracefully — check what's actually in the access token's scope claim, not what you originally requested.


Identity scopes

ScopeWhat it adds
openidRequired for sign-in. Enables the id_token in the token-endpoint response and gives you the user's stable sub identifier.
emailAdds email and email_verified claims to the ID token and to the /userinfo response.
profileAdds name to the ID token and /userinfo.
offline_accessIssues a refresh_token alongside the access token, so your app can mint new access tokens without re-prompting the user.

These four scopes give your app identity only — they don't unlock any workspace data.


Workspace scopes

Workspace scopes give your app the ability to act on the single workspace the user selects at consent time. The access token carries a workspace_id claim and your app's calls are restricted to that workspace.

ScopeGrants
workspace:readRead operational data in the selected workspace: workflows, components, executions, members, environment-variable names (not values), workspace API key labels, MCP settings. Does NOT include financial data — request workspace:read.billing for that.
workspace:read.billingRead financial data: credit balance (paid + usage + total), billing transactions, payments, billing information, subscription status. Independent of workspace:read so apps that only need workflow data do not also see your billing history.
workspace:writeRead everything in workspace:read, plus create / edit / delete workflows, trigger executions, cancel and retry runs, manage environment variables.
workspace:api_keysNarrow grant for creating named workspace API keys (the same key + secret you would receive from the workspace settings UI). Independent from workspace:write — apps that only need to mint API keys don't have to ask for full admin.
workspace:adminImplies all four scopes above. Adds: invite + remove members, revoke API keys, change workspace settings, manage billing (top up, change plan, cancel subscription).

Tier hierarchy

workspace:admin  ⊃  workspace:write  ⊃  workspace:read
                ⊃  workspace:read.billing
                ⊃  workspace:api_keys

workspace:read.billing and workspace:api_keys are sibling slices to the write tier — they sit beside workspace:write rather than under it. An app holding workspace:write can create workflows but cannot mint API keys or read billing; an app holding workspace:read.billing can see the credit balance but cannot list workflows. Request each slice independently.


Picking the right scopes

Some common integration shapes and the scopes they need:

IntegrationScopes to request
"Sign in to my app with Zafeguard" — identity only, no workspace dataopenid email profile
Identity + stay-signed-inopenid email profile offline_access
Read-only dashboard that mirrors workflow runsopenid offline_access workspace:read
Accounting tool reading credit balance + billing transactionsopenid offline_access workspace:read.billing
Workflow builder / automation clientopenid offline_access workspace:write
Provisioning agent that needs to mint a workspace API key on first runopenid offline_access workspace:api_keys
Full admin surface (rare; only for ops tooling)openid offline_access workspace:admin

A user can only grant a workspace scope they themselves hold on that workspace. Examples:

  • A regular workspace member (no admin permissions) tries to consent to workspace:admin → the consent endpoint rejects the request, and the consent UI greys out workspaces they can't grant the requested scope on.
  • A user who is a member of two workspaces — admin on one, read-only on the other — can grant workspace:admin for the first workspace but only workspace:read for the second.

This means a third-party app cannot escalate privileges by asking for a wider scope than the consenting user holds.

In addition, every consent requires the workspace-level permission authorize_workspace_connected_apps regardless of which scopes are being granted. Workspace owners hold this implicitly; members need it granted explicitly to be able to authorize any third-party app on the workspace.


Access token claim shape

Once your app receives an access token, the claims it carries:

{
  "iss": "https://api.zafeguard.com",
  "sub": "9c3f4b2a-7e8d-4d1a-a3b0-f6e2a4b8c1d9",
  "aud": "zfg_abc123…",
  "client_id": "zfg_abc123…",
  "workspace_id": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
  "scope": "openid email profile workspace:read",
  "iat": 1748145600,
  "exp": 1748149200
}
  • sub is stable per (user, app) — the same user signing in to the same app always sees the same sub. Use it as your local user identifier.
  • workspace_id is the workspace the user selected for this authorization. Pass it to any workspace-scoped Zafeguard endpoint you call; mismatched values are rejected with 403.
  • scope is the actual granted set (could be narrower than what you requested if the user unchecked items).

ID token claim shape

The ID token carries identity-only claims:

{
  "iss": "https://api.zafeguard.com",
  "sub": "9c3f4b2a-7e8d-4d1a-a3b0-f6e2a4b8c1d9",
  "aud": "zfg_abc123…",
  "nonce": "<the nonce you sent on /authorize>",
  "auth_time": 1748145600,
  "email": "alice@example.com",
  "email_verified": true,
  "name": "Alice Example",
  "iat": 1748145600,
  "exp": 1748149200
}

Fields are present only when the matching scope is granted (email / email_verified need email; name needs profile).

On this page