Tenants and grants
Tenants
A tenant is a customer's namespace: its agents, its members and approvers, its trust profile and the grants it issues. Every action belongs to exactly one tenant, and Axiom derives the tenant from the authenticated agent, never from the request body. A submit whose tenant field differs from the agent's tenant is refused with 403 forbidden, reason_code: tenant_mismatch.
Tenants appear in three ways:
- Customer tenants, created by a customer admin (
POST /v1/tenants, regionusoreu) or by an MSP organisation for its customers (POST /v1/orgs/{org_id}/tenants). - Developer workspaces: creating your first project creates a workspace tenant that owns it.
- The sample tenant, "Acme Corp (sample customer)", seeded with the quickstart.
Tenant roles are tenant_admin, finance_approver, approver and auditor. Org roles reach the tenants their organisation owns. Someone without access to a tenant's records gets 404, not 403: a caller cannot learn that a resource exists.
Services admit tenants
A provider's protected service lists the customer tenants allowed to request grants on it (admitted_tenants: tenant IDs or "any"). The project's own tenant is always admitted. A tenant admin creating a grant on a service that has not admitted their tenant gets 403 "this service has not admitted your tenant; ask the provider to add it".
Grants
A grant is the customer's standing authority for one agent on one service. Grants authorise; policy rules can only restrict what a grant allows.
POST /v1/tenants/{tenant_id}/grants
{
"agent_id": "agt_…",
"service_id": "svc_…",
"operations": ["billing.refund.create", "billing.invoice.read"],
"resources": [{ "type": "invoice", "id": "*" }],
"rules": [ /* optional grant-layer policy rules, see Policy layers */ ],
"delegable": false,
"expires_at": "2026-12-14T00:00:00Z"
}| Field | Meaning |
|---|---|
operations | Operation names or glob patterns. * matches within one dotted segment; ** matches anything. At least one is required. |
resources | Resource patterns { type, id } (globs). An empty list means any resource of the operation's type. |
rules | Grant-layer policy rules, validated like any policy document. The sample's USD 500 threshold and USD 100,000 ceiling live here. |
delegable | Whether the agent may hand a narrower child grant to another agent (Explicit delegation). |
expires_at | Hard end of the grant. It also caps every resume deadline: an approved action can never be resumed after its grant expires. |
issued_by records who created it (a user ID, or agent:{id} for a delegated child grant).
How a request is checked against a grant
For each of the agent's grants on the target service, in order:
| Check | Failure reason code |
|---|---|
| Grant revoked or suspended | grant_revoked |
| Grant expired | grant_expired |
| Not yet valid | grant_scope_mismatch |
| Grant tenant is not the agent's tenant | tenant_mismatch |
| Issued to another agent | grant_scope_mismatch |
| Grant is for another service | audience_mismatch |
| Operation not covered | operation_not_permitted |
| Resource not covered | resource_not_permitted |
| Child grant bound to a different root action | grant_scope_mismatch |
| An ancestor grant is no longer active | grant_revoked |
The first grant that passes is used. If none passes, the action is recorded as denied with the last failure reason (no_grant when the agent has no grant on the service at all). Denials are recorded as actions, so they appear in the project's evidence and the simulator.
Revoking a grant
POST /v1/grants/{grant_id}/revoke with a reason revokes the grant and every descendant (delegated child grants). New submits fail immediately; an approved action whose grant is revoked moves to revoked on resume. Work already dispatched is not recalled: it is reconciled and recorded separately. See Revocation.
Quotas do not take away authority
When a project reaches its plan's monthly action quota, new submits are refused with 402 quota_exceeded. Status reads, resumes of existing actions, approvals already requested and receipts keep working. See Plans and limits.