Skip to content

Identity & Security ​

Agentfleet's core security position: an agent never holds standing credentials. Every step of every run executes under a short-lived token that records exactly who delegated, who acted, where the token is valid, and — optionally — which task and purpose the session serves. Separately, every API call is authorized by a policy decision point, permission by permission and tenant by tenant.

The delegated token ​

When a step first calls a resource, Agentfleet performs an RFC 8693 token exchange with the identity provider:

  • The subject token is the initiating user's access token — the delegating principal.
  • The acting party is the agent, authenticating with a secretless private_key_jwt assertion signed by its per-agent key (held in a key vault; the platform never sees private key material).
  • The request is narrowed to that resource (audience) and the scopes of the step's tools on it.

The issued token carries:

ClaimMeaning
subThe user the work is done for.
act.subThe agent that acted.
audThe one resource the token is valid at.
tenantThe owning tenant.
task_idThe task this session was composed for — when supplied as a run input.
purposeThe declared purpose of the session — when supplied as a run input.

Downstream resources can therefore audit "agent X, delegated by user Y, for task Z, under purpose P" on every call. Agentfleet records each exchange too (subject, actor, audience, scopes, purpose); the run's page shows them in its Purpose & delegation card.

A step that uses tools on several resources exchanges once per resource, lazily, so a resource the step never calls is never given a token. A child run (a sub-workflow step, or a workflow called as a tool) exchanges with the same subject and the parent's agent as actor, so it can never gain privileges.

Least privilege, by construction ​

  • Scope: only the step's tool scopes are requested. The identity provider intersects the request against what both the user and the agent are allowed — a step can narrow access, never widen it.
  • Audience: the token is valid only at one resource. It cannot be replayed elsewhere.
  • Lifetime: tokens are minted per step and are short-lived. Within a step, a token is re-exchanged shortly before it expires (or after the resource answers 401); a finished step never renews its tokens again.
  • Long runs: when a run is queued, Agentfleet also obtains a refresh-capable credential for the delegating user, so a run that outlives the user's interactive token (waiting for review, say) can still renew the subject. If the identity provider doesn't grant it, the run is bounded by the interactive token's lifetime.
  • Just-in-time access: the agent's client is granted access to the resource only for the duration of the step, then revoked — the agent never retains standing access to anything.
  • Proof of possession (optional): a resource that requires DPoP gets tokens bound to a per-step ephemeral key, so a stolen token is useless without that key.

Purpose-bound sessions (fail-closed) ​

Resources that enforce purpose-based policy require a purpose claim. If a run is queued without a purpose input, no purpose claim is requested — and a purposed resource rejects the session at the door. This is deliberate: forgetting to declare a purpose fails closed, while resources that don't require purpose run unchanged. A workflow (or an assistant profile) can also require a purpose on every launch; see Usage & Data Governance.

Authorization ​

Agentfleet does not decide access itself. Every request is decided by the Authlink policy decision point (PDP), and the API enforces the answer fail-closed: no decision means 403, never a fallback to token claims.

Permission keys ​

Each endpoint asks for one permission key of the form agentfleet:<permission> — for example agentfleet:create-workflow, agentfleet:run-workflow-instance, agentfleet:start-eval-run or agentfleet:confirm-tool-calls. A denied call answers 403 with the missing key. The full catalogue is provisioned into Authlink from the code; the REST API reference shows how endpoints use it.

Roles and personas ​

Permissions are bundled into roles, administered in Authlink. Assign one persona per job a person does; personas are additive.

RoleForGrants (summary)
agentfleet:viewerEveryone, day oneRead-only across every aggregate.
agentfleet:workflow-authorBuildersAuthor steps, workflows, tools, skills, assistant profiles and resources; queue and cancel runs; export packages; optimise models.
agentfleet:operatorOn-call / opsQueue and cancel runs; recover the run queue; fire schedules; confirm tool calls; answer clarifications.
agentfleet:automation-managerAutomation ownersSchedules, event triggers and webhook triggers.
agentfleet:evaluatorQA / release gatingEval suites and cases; start eval runs and experiments; grade; optimise models.
agentfleet:identity-adminPlatform (sensitive)Agents and model providers; bulk model swaps; usage limits. Never a default.
agentfleet:thread-userPeople who chatStart, read, continue, archive and delete their own chats. Granted deliberately.
agentfleet:adminBreak-glassEverything. Never a default.

Every persona except thread-user is the viewer bundle plus its own permissions. There are also per-domain agentfleet:<domain>-admin roles (for example workflow-admin, which alone with admin can override the promotion gate or import workflow packages). See the access-control roles runbook for each bundle.

Tenant isolation ​

Holding a permission is not enough: the PDP also checks which record you are touching.

  • Detail reads and changes carry the record's attributes (its tenant, status and creator) to the PDP. A permit for these keys applies only when the record's tenant equals yours. A record that cannot be found carries no attributes, and is denied.
  • Lists ask the PDP for the list permission, which comes back with a row filter to your tenant, so a list never shows another tenant's rows. A list that cannot reach the PDP answers 502 rather than unfiltered data.
  • Chats are further limited to their owner: another user's thread answers 404.

Model providers are the exception: they are platform-wide, so a tenant without its own provider uses the shared one. See the resource-scoped policies runbook.

Signing in to the console ​

The console uses a backend-for-frontend (BFF) session. You sign in at the identity provider; the API exchanges the authorization code for tokens and keeps them in HttpOnly cookies, so the browser's JavaScript never holds a bearer token. The API refreshes the session (POST /api/auth/refresh) and ends it on sign-out (POST /api/auth/logout). The console shows or hides actions from a permissions snapshot (GET /api/auth/permissions), refreshed every few minutes. The snapshot only shapes the UI; every request is still decided by the PDP.

Chats need a person ​

A conversation thread always acts for a signed-in human: starting a thread, sending a message and deciding a paused tool call refuse a request that carries a service or agent token (Thread.HumanSubjectRequired). A portal that embeds the chat widget exchanges its signed-in user's token, so the user remains the subject. See Conversations.

Secretless clients ​

Neither the platform nor its agents use client secrets:

  • Agents authenticate with private_key_jwt assertions (60-second lifetime), signed via the key vault's crypto API using managed identity.
  • The platform's own client (used for discovering tools, asking the PDP and minting machine tokens) authenticates the same way, with one signing key per environment held in that environment's key vault.
  • Per-agent keys support zero-downtime rotation with overlapping validity.

What this means in practice ​

  • A leaked token is short-lived, valid at one resource, under the step's scopes — and names its wielder.
  • A compromised agent cannot act without a fresh user delegation.
  • A user can do through Agentfleet only what the PDP permits, and only in their own tenant.
  • Every downstream audit line has a complete answer to "who, on whose behalf, for what."

Agentfleet — agent workflow orchestration.