How it works
- Owner is the only organization role. It manages members, security and who may reach each product, and grants no Gateway access by itself.
- Product roles are
member<editor<admin. A product role applies in every workspace of the product, including ones created later. - Workspace roles use the same three names and are effective only while the holder also has Gateway access.
Gateway permissions
Roles are defined in code; each role holds everything the role below it holds.| Permission | Member | Editor | Admin |
|---|---|---|---|
gateway.requests.execute — call models through /v1 | ✓ | ✓ | ✓ |
gateway.workspaces.read, gateway.members.read | ✓ | ✓ | ✓ |
gateway.providers.read, gateway.models.read | ✓ | ✓ | ✓ |
gateway.routing.read, gateway.policies.read, gateway.guardrails.read | ✓ | ✓ | ✓ |
gateway.ratelimits.read, gateway.budgets.read | ✓ | ✓ | ✓ |
gateway.apikeys.read, gateway.serviceaccounts.read | ✓ | ✓ | ✓ |
gateway.analytics.read, gateway.observability.read | ✓ | ✓ | ✓ |
gateway.apikeys.manage | ✓ | ✓ | |
gateway.serviceaccounts.manage — virtual accounts and their tokens | ✓ | ✓ | |
gateway.models.manage — models and model restriction policies | ✓ | ✓ | |
gateway.routing.manage — virtual models and routing configs | ✓ | ✓ | |
gateway.workspaces.manage, gateway.members.manage | ✓ | ||
gateway.providers.manage | ✓ | ||
gateway.policies.manage, gateway.guardrails.manage | ✓ | ||
gateway.ratelimits.manage — rate limits, token limits, access policies | ✓ | ||
gateway.budgets.manage | ✓ | ||
gateway.audit.read | ✓ | ||
gateway.traces.sensitive.read — reveal PII removed from a trace | ✓ | ||
gateway.observability.manage — trace export destinations | ✓ |
Permissions are namespaced by product. A
gateway.* permission is never satisfied by a Studio or Deployer role, and no product role grants any org.* permission.Workspace roles and custom roles
Inside a workspace, a member holds exactly one system role plus any number of the workspace’s custom roles and individual extra permissions. Custom roles and extras only add; they are built from thegateway.* permissions above. In the console this lives under Gateway → Access → Roles.
| Method | Path | Body |
|---|---|---|
GET | /api/v1/gateway/workspaces/{id}/roles | — lists every permission, the three system roles and custom roles |
POST | /api/v1/gateway/workspaces/{id}/roles | {name, description, permissions} |
GET/PATCH/DELETE | /api/v1/gateway/workspaces/{id}/roles/{roleID} | PATCH: {name?, description?, permissions?} |
PUT/DELETE | /api/v1/gateway/workspaces/{id}/roles/system/{role} | {permissions} — change (PUT) or reset (DELETE) what member or editor grants in this workspace |
GET/PUT | /api/v1/gateway/workspaces/{id}/members/{userID}/access | {role, custom_role_ids, extra_permissions} |
., _ or -, starting with a letter or digit.
Credentials and service identities
| Credential | Prefix | Acts as |
|---|---|---|
| Admin-created API key | ml- | A key filed under one team, optionally bound to one workspace, with a member, editor or admin role |
| Personal access token | ml_pat_ | Its owner, within one workspace; always expires |
| Virtual account token | ml_vat_ | A virtual (service) account: the member role plus explicit allowlists, never its creator’s authority |
allowed_models and allowed_providers; an account that names none reaches none. Tokens are issued only from a console session, never from another token, and their plaintext appears only in the response that issued them. In the console, find these under Gateway → Access → Personal Access Tokens and Virtual Accounts. See Credentials for the full API.
Restricting model access
Several independent checks run on every/v1 request; a model must pass all of them.
Virtual account allowlists
Virtual account allowlists
An
ml_vat_ token can reach only the models and providers its account lists. Anything else returns 403 model_not_allowed.Team model allow-list
Team model allow-list
A team’s
models list (logical names, or *). A team with no list configured is unrestricted. Otherwise a request for an unlisted model returns 403 model_not_allowed. To call a virtual model, the list must include its name. Set it with POST /admin/teams (organization Owner only).Provider account bindings
Provider account bindings
A provider account can be restricted to named users, teams or everyone in the workspace, as Subject
user (may call its models) or manager (may also edit it). everyone can only be granted user. An account with no bindings is open to its workspace. A refused caller gets 403 provider_access_denied.type is user, team or everyone (no id). List bindings with GET, remove one with DELETE /admin/gateway/providers/{id}/access/{bindingID}. Needs gateway.providers.manage.Provider key scope
Provider key scope
PUT /admin/gateway/providers/{id}/scope with {models_scope, model_ids, api_keys_scope, api_key_ids}, each scope all or specific, limits an account to particular models or to traffic from particular API keys. GET returns the current scope.Model restriction policies
Model restriction policies
Allow- and deny-lists at organization, workspace, team, service-account, user or API-key scope; deny wins. Managed in Gateway → Policies → Model restrictions or at
/admin/gateway/policies/model-restrictions with gateway.models.manage. See Policies.Routing configs are checked target by target: a target the caller may not use is skipped, never served. Auto Routing and virtual models cannot route around a deny; if every target is refused the caller gets
403 model_not_allowed.Next steps
Teams & permissions
Organization, product and workspace rungs.
Credentials
PATs, virtual accounts and rotation.
Policies
Access policies and model restrictions.
Rate limiting
Per-identity request and token ceilings.