Skip to main content
Runtime callbacks are requests from an SDK server to Aion, such as model calls or MCP tool requests. The runtime authenticates with the Version access token obtained from its client ID and client secret. Do not reuse an incoming user’s, guest session’s, or invocation bearer for these callbacks. The Python SDK’s model, MCP, A2A, and File clients use the active request’s runtime context to select attribution. This page describes the headers they send and the checks Aion applies. Older clients that send Aion-Principal-Selector must be updated before using this contract.

Choose the attribution mode

For an inbound request, send one attribution header with the Version bearer. Aion rejects both headers together, duplicate values, empty values, and malformed caller IDs. An invalid or expired signed carrier does not select direct or deployment-self mode. Aion rejects the retired Aion-Principal-Selector header. User requests without callback headers retain user authority. Version callbacks without attribution or an explicit internal selector use the deployment’s current daemon identity. The former POST /auth/tokens/exchange endpoint and AgentIdentity bearer tokens are no longer supported. Keep the Version bearer for callbacks; Aion resolves and authorizes the acting identity from the attribution mode below.

Forward Aion usage attribution

Aion verifies the carrier’s signature, purpose, issuer, audience, time claims, and presenter. It checks whether that Version may currently act as the carrier’s execution principal. Each operation still requires its normal permissions. The original payer, originator, and outward agent are preserved; they do not select authorization. The carrier has a 24-hour lifetime for long-running work. It is not the invocation bearer used to authenticate an incoming request, and it must not be supplied as Authorization. Missing or stale executor bindings fail explicitly. Signed contextual callbacks are supported by model, MCP, A2A, and File mutation ingress.

Report a direct caller

Direct callbacks require an active deployment with an assigned daemon identity. Aion resolves the current assignment on each call: that daemon supplies authorization, agent, and execution identity. The deployment’s organization pays. Reassigning or clearing the daemon affects subsequent calls without changing earlier usage records. For a direct request with no identifiable caller, report ExternalAnonymous with principal ID external-anonymous:
Preserve a known anonymous session as AnonymousSession, rather than merging it into ExternalAnonymous. For a known Aion user, the following example encodes user ID 00000000-0000-0000-0000-000000000001:
The reported caller is attribution only, not proof that the person authenticated. Reporting a user does not grant their permissions, select their payer, or give the runtime access to that user’s tasks and conversations. Never put a user or session bearer in this header. Direct caller attribution supports model, MCP, A2A, and File create/replace requests. A2A task access uses the resolved sending daemon, not the reported caller; the receiving execution hop then updates the executor normally. File mutations require their ordinary permissions and reject a callback payer that differs from the File’s owning organization. File read/grant behavior and Version-only Fernet key retrieval are unchanged. In all callback modes, contexts/get and context/get use the resolved sending identity’s caller bindings. They do not grant access to every conversation owned by the receiving agent, or to the reported caller’s conversations.

Initiate work as the deployment

For work such as integration tests, use the Version bearer without an attribution header:
Aion resolves the deployment’s current daemon as originator, agent, executor, and authorization principal. The deployment’s organization pays. The SDK does not fetch or cache the daemon ID. Each operation still requires its normal permissions, including File owner and payer agreement. This default applies to model, MCP, A2A, and File create/replace calls. It does not change other Version endpoints, such as Fernet key retrieval. If the deployment has no daemon, Aion returns daemon_identity_required. Aion never executes these callbacks as a bare Version principal. The SDK permits this mode only when no inbound runtime context or explicit attribution exists. An active runtime context without attribution fails instead of silently selecting deployment-self mode. An unidentified inbound caller still uses the explicit ExternalAnonymous ID, not this default. Never remove invalid attribution to retry as the deployment.

Caller-ID format

Use the same canonical ID as the distribution extension’s callerId and the invocation JWT subject:
UUID-based types use the canonical lowercase UUID. External senders retain their provider, tenant, and sender namespace; do not substitute a raw network user ID. Encoding is reversible, not encryption or authentication. Use aion.core.principal.Principal.subject instead of maintaining a separate encoder.

Handle callback failures

  • daemon_identity_required: assign a daemon to the deployment before retrying. Do not select an arbitrary behavior’s daemon, create a new identity automatically, or fall back to the reported user’s credentials.
  • Invalid attribution: correct the header or obtain a new valid contextual invocation. Never drop an invalid carrier to retry in direct mode.
  • Permission denial: grant the deployment daemon the required operation permission. The Project Agent role permits model execution and File creation in its organization, but does not grant File update, read, or delete.
The stable configuration code is carried in the operation’s error envelope. No metered provider work is dispatched when resolution fails. Non-streaming model calls return HTTP 400 with type: "configuration_error" and code: "daemon_identity_required". Streaming model calls can return HTTP 200 and carry those same details in an SSE error event; clients must inspect the stream, not only the HTTP status. File and MCP configuration failures use HTTP 409. The Python SDK model helpers raise AionDaemonIdentityRequired from aion.core.exceptions, including during synchronous or asynchronous stream consumption. Its retryable property is False: assign the deployment daemon before retrying.