Authorize

#Provisioning

Once your tenant has its first admin, everything else is self-service under the /access/* surface: add users, mint API tokens, assign roles, author policies, and bind a least-privilege policy to a token for cross-tenant access. (Provisioning a brand-new tenant and its first admin is a one-time platform-operator step done during onboarding.)

Authenticate as a tenant admin with a Personal Access Token (HTTP Basic auth) — enter it once in the Authorize bar at the top of this page and every Try it below uses it. Each example body is pre-filled; the console targets staging by default. Full request/response schemas are in the linked API reference.

#Roles, policies, grants — the vocabulary

  • A role is a per-tenant system policy (tenant_admin, entity_editor, workflow_admin, viewer, app_user, …). Every new tenant is auto-seeded with the full catalogue. List them at GET /access/roles; the ids are what you pass as role_ids / role_id.
  • A policy is a named bundle of grants you author for least-privilege scoping (e.g. read-only access to a few shared resources).
  • A grant authorizes a principal (user, team, or policy) to act on a resource. Grants and cross-tenant shares are covered in Shares & Grants.

#Add a user

Create a user in your tenant and assign their initial roles in one call.

An address that already exists in another tenant reuses that account and just adds a profile in yours — one person, one login, many tenants. An address that already has a profile in your own tenant is a 409 CONFLICT, not a no-op, so treat 409 as "already provisioned" if you are writing an ensure-this-user-exists loop. Its details carry the existing auth_user_id.

POST/access/usersAdd a user to your tenantAPI docs ↗Try it

role_ids takes role ids from GET /access/roles. A DELETE on /access/users/{authUserId} soft-deactivates the profile in your tenant; the underlying account stays intact. PATCH /access/users/{authUserId} edits first_name, last_name and foreign_key, and "is_active_in_tenant": true reactivates the profile.

#Mint an API token

Tokens belong to a (user, tenant) pair. A fresh token runs in standard mode — it acts with the target user's full effective permissions in the tenant.

POST/access/api-tokensMint an API token for a userAPI docs ↗Try it

The response carries client_id and client_secret (helm_tk_…) — the secret is returned once. Use the pair as HTTP Basic credentials (base64(client_id:client_secret)). Pass policy_id here to mint a scoped token in one step, or attach one later (below). GET /access/api-tokens lists your tenant's tokens, and DELETE /access/api-tokens/{tokenId} revokes one.

#Assign a role to an existing user

Roles can be assigned after the fact too:

POST/access/role-assignmentsAssign a role to a userAPI docs ↗Try it

#Scope a token with a policy (least privilege)

For a least-privilege token — especially one a partner tenant uses to read only the resources you shared — author a policy, give it grants, then bind it to the token. First the policy shell:

POST/access/policiesCreate a least-privilege policyAPI docs ↗Try it

Add its grants: inline as grants when you create it, with POST /access/policies/{id}/grants, or with POST /access/grants and "grantee_kind": "policy" (see Shares & Grants for the grant shape and the cross-tenant read-only rule). Then bind the policy to a token — this flips the token into policy-mode, acting as exactly that policy:

PUT/access/api-tokens/{tokenId}/policyBind a policy to a token (policy-mode)API docs ↗Try it

The bound policy must belong to your tenant: one you authored, or a role from GET /access/roles. Another tenant's policy is refused with 422 (POLICY_NOT_FOUND), and so is a policy derived from an app spec or workflow (POLICY_SOURCE_INELIGIBLE). DELETE on the same path clears the binding (back to standard mode).

Standard mode vs policy mode. A standard-mode token is the union of the user's role/policy assignments. A policy-mode token acts as one policy — narrower, predictable, and the right choice for cross-tenant or integration tokens. The same user yields different access under different bound policies.

#Cross-tenant access

To let another tenant read your data, you need both a tier-1 share (you → them) and tier-2 permission inside their tenant. You create the share by listing the resources in a manifest and offering it to their tenant. It takes effect when they accept, and they decide which of their principals read it. A policy-mode token there always needs a grant on the shared resource. The model is in Shares & Grants; the two sides are walked through in Share with Another Tenant and Accept & Activate.

#Provider organisations (for apps)

If you run a Bridge app for an external provider, register that provider organisation yourself with POST /access/external-companies (provider + external_id, plus optional name/metadata). The pair is unique per tenant, so registering a company another tenant already has is fine. List them with GET /access/external-companies; update name/metadata/is_active with PUT /access/external-companies/{id}. See Apps (Bridge).

The people who use an app through that provider are external users. They are created on their first app session when the provider sets autoCreateUsers, or ahead of time with POST /access/external-users (external_company_id + external_id). A repeat of the same pair answers 200 with the existing user. List them with GET /access/external-users (filter by external_company_id), change external_data or is_active with PUT /access/external-users/{id}, and deactivate one with DELETE. See Auto-provisioning.

#Secrets

Tenant secrets (and the scoped references apps/workflows wire into their config) are managed at /access/secrets. See Secrets.

#API reference

Every user, token, role, policy, grant, manifest, share, and secret operation — with full schemas and an interactive console — is in the API reference.