Security
The agent's security model: bearer auth, HMAC webhooks, secret handling and rotation, callback allowlists, and network posture.
Context — Everything security-relevant about running an agent, in one place: who can call what, how each credential flows, and what to lock down. Assumes the network surface overview.
Authentication surfaces
Inbound: bearer token (everything except health, webhooks & login)
All API routes except the health probes, /webhooks/*, and the /auth/login flow require:
Authorization: Bearer <agent api key>The token is the manifest's runtime.api_key (resolved from ${AGENT_API_KEY} or your chosen variable). Comparison is constant-time.
For the built-in chat UI only, the same key can be presented as an HttpOnly agent_auth cookie, set by typing the key into POST /auth/login (browsers can't attach bearer headers to the UI's own requests) and cleared by POST /auth/logout. The cookie carries the same secret with the same powers — everything below applies to it equally.
Properties to design around:
One shared token per agent. There is no per-client identity, no scopes, no expiry. Anyone holding the token has the full API: read any session, post messages, trigger autonomous routines.
Therefore: the token belongs to your integration tier only. Browsers and end-user devices must never see it — your integration authenticates end users its own way and holds the agent token server-side (the SDK guide's architecture).
Treat it like a database password: secret store, rotation procedure, never in URLs or logs.
Inbound: HMAC signatures (/webhooks/*)
/webhooks/*)Third-party webhook entry points bypass bearer auth — the provider's signature over the raw body is the authentication:
Signature =
prefix + hex(HMAC(secret, raw_body)), algorithmsha256(orsha1/sha512where a provider requires it), carried in the configured header. Verified constant-time; any failure → 401 with no detail.Unknown webhook names and routines without webhook config return an identical 404 — the public surface doesn't reveal what exists.
Rotation without restart: the secret env var is re-read on every request. Update the secret in the platform's secret store and both old and new traffic windows behave predictably (one secret is valid at a time — coordinate the provider-side switch).
Replay safety: identical deliveries dedupe to the same run via a body-hash idempotency key — a replayed webhook cannot double-fire a routine.
Outbound credentials
LLM router
llms.api_key
Bearer
InteractiveAI platform (boot fetch)
interactive_platform.{public_key,secret_key}
platform auth
MCP servers
per-server mcps[].api_key
Bearer
Knowledge base (pgvector)
search.password
Postgres auth
External search
search.api_key
Bearer
Traces backend
traces.backend.api_key
Bearer or Basic (api_key_scheme)
Autonomous callbacks & event webhooks to your integration
the agent api key
Bearer
Your callback/webhook receivers must verify that bearer header — otherwise anyone who can reach them can forge "agent results".
Secret handling rules
The manifest cannot contain a secret value — credential fields only accept ${VAR_NAME} references, enforced by schema validation:
Resolution at boot, fail-fast: missing variables abort startup with the variable name. No fallback path, no partial boots.
Exception — webhook secrets are read per request (rotation support, above).
You declare a secret bundle in the manifest's
secrets:list (by its name in Interactive Secrets); the platform injects that bundle's key/value pairs as environment variables before boot. The value exists only in the agent's environment, never in the manifest.Rotation procedure (all except webhook secrets): update the secret in the platform's secret store; the platform rolls the agent to pick it up. The old credential must stay valid until the rollout completes.
Logs and config dumps redact credential fields; Postgres URIs are logged with credentials masked.
Autonomous-surface hardening
callback_url_allowliston every autonomous routine in production. Without it, any caller holding the bearer token can point results at any URL. With it, only listed hostnames (a leading.allows the apex and subdomains) receive callbacks.Operator timeout bounds are a backstop against runaway runs: a routine's
timeout_secondsis capped byAUTONOMOUS_MAX_TIMEOUT_SECONDS(default 600s) regardless of what the YAML asks for.Input schemas are a security control — strict
input_schemas reject malformed payloads at the door (HTTP 400), before any model sees them.
Prompt-level exposure
What reaches the model is what's in the session: messages, tool results, variables, retrieved snippets. Practical consequences:
Anything a tool returns can end up in a reply. Don't return fields the customer must never see; filter server-side in the MCP tool, not in instructions.
Injected tool events (
/sessions/{id}/tool_events) render verbatim into prompts (control characters are stripped). The endpoint is bearer-gated, but treat injected payloads with the same trust you'd give tool results.Variables are agent-visible by definition — never put secrets in variables. Integration-private data goes in metadata, which never reaches a prompt.
Traces capture conversations, tool results, and variables and the trace metadata snapshot is not redacted. Apply access control on the traces backend accordingly, and point
traces.backendat your own collector if platform-default storage doesn't meet your data policy.
Network posture checklist
Last updated
Was this helpful?

