Security context
Deployment configuration and runtime authorization facts are evaluated separately from message content.
Hosted profile
| Field | Meaning |
|---|---|
| tenant_mode | Whether tenant relationships are fixed or derived per request. |
| roles | Stable actor IDs and security labels. |
| actions | Operations and their read, write, egress, or administrative consequence. |
| tools | Allowed tool IDs and security classes. |
| data_classes | Public, internal, confidential, or restricted resource classes. |
| destinations | Internal, approved external, or untrusted destinations. |
| authorization_rules | Allow and deny relationships across the catalogs. Deny rules take precedence. |
Runtime facts
| Field | Source |
|---|---|
| actor_role_id | Profile role ID for the authenticated actor. |
| actor_tenant_id | Tenant ID from your identity/session layer. |
| resource_tenant_id | Tenant that owns the resource being accessed. |
| action_id | Profile action ID for the operation being attempted. |
| tool_id | Profile tool ID for the runtime or proposed tool. |
| authorization_decision | Optional result from your authorization service. |
| data_class_id | Profile data-class ID for the resource. |
| destination_id | Profile destination ID for the result or transfer. |
Trust boundary
A deployment-scoped API key selects the hosted profile. The gateway resolves catalog IDs, derives tenant relationships, applies profile rules, and marks the result as gateway-derived. Message text can influence the threat score, but it cannot rewrite the profile or claim gateway provenance. Missing or contradictory facts increase Tier-3 routing instead of becoming an automatic allow.
TypeScript
Context-aware conversation
const conversation = axiom.conversation();
const facts = {
actorRoleId: "support_agent",
actorTenantId: signedInUser.tenantId,
resourceTenantId: account.tenantId,
actionId: "read_account",
toolId: "support_assistant",
dataClassId: "customer_confidential",
destinationId: "current_session",
};
const input = await conversation.scanInput(userPrompt, {
runtimeFacts: facts,
});
if (input.action === "block") throw new Error("Blocked by Axiom");
const modelOutput = await callYourModel(userPrompt);
const output = await conversation.scanOutput(modelOutput, {
runtimeFacts: facts,
});
if (output.action === "block") throw new Error("Blocked by Axiom");