Authentication

The engine accepts four kinds of caller identity: a JWT bearer token, an API key, HTTP Basic credentials and no credentials at all (anonymous). All of them work on every surface — REST, Socket.IO, plain WebSocket and the HTTP pipeline channel.

Authentication only establishes who the caller is. What that caller may see and run in a project is decided by the authorization model documented in Consumer Security.

JWT Bearer Token

The engine is an OAuth2 resource server. Tokens are issued by the platform’s identity provider (Keycloak) and validated against its configured issuer.

Pass the token as a standard header:

Authorization: Bearer <token>

Because browsers and native socket libraries cannot always set headers on a WebSocket handshake, the token may also be passed as a query parameter on any endpoint:

/socket/pipeline/agent:acme-support?authorization=<token>
/api/v2/project/acme?authorization=<token>

Roles are read from the token’s realm_access.roles claim and mapped to engine authorities. The role vocabulary is:

Role Meaning

consumer

End user of an agent. Required by the user-facing endpoints (sessions, memory, navigation, evaluation).

manager

May read session data and turn logs across users.

designer

Designs agents and projects.

viewer

Read-only access.

owner

Owns a tenant or project.

admin

Full administrative access, including operational endpoints.

Two further claims are consumed by the project authorization model: idpRef (which identity provider authenticated the user) and extRoles (external roles used for optional role-based project access). See Consumer Security.

Changing the Token During a Session

A conversation can outlive an access token. Send an in-band control token on an open connection to replace the identity used for the remainder of the session:

#authorization:<jwt>

API Key

Server-to-server integrations can authenticate with a pre-shared API key, supplied either as a header or as a query parameter:

X-Api-Key: <key>
/api/session?apiKey=<key>

Each key is configured on the engine side with a fixed set of roles, and can be disabled without being removed. A request carrying an unknown or disabled key is rejected with 401 Unauthorized — note that this differs from sending no key at all, which is treated as an anonymous request.

HTTP Basic

Authorization: Basic <base64(user:password)> is accepted on REST endpoints and on the Socket.IO handshake. A Basic identity may carry an associated idpRef, which participates in identity provider matching exactly like the JWT claim.

Anonymous Access

Requests without credentials are permitted. The engine does not reject them at the transport level; individual endpoints and projects decide what an anonymous caller may do:

  • GET /api/v2/project/{idOrRef} returns project metadata to anonymous callers, and the full agent list only when the project does not require identity.

  • A conversation can be opened anonymously when the project allows it. The user identity is then derived from the device (deviceRef) rather than from an account, which means memory and history do not carry over to another device.

  • Passing anonymousMode=true on a conversation makes the session anonymous even when the caller is authenticated — the session is bound to an anonymous user derived from the session ID.

Which Endpoints Require What

Endpoint group Minimum identity

Project and agent discovery

None (response content depends on identity)

Session and turn history

consumer for own sessions, manager for session detail and LLM logs

User, memory and navigation

consumer (the user and memory endpoints resolve the current user from the token)

Evaluation status

None for \/evaluation/status, consumer for insights and aggregations

Feedback specification and submission

consumer or deviceRef for GET /feedback/specification, consumer for submission

Visual API

None for visual assets

OAuth, MCP, telephony, reports

consumer or admin depending on the endpoint

Conversation transports

None; project rules decide (see Consumer Security)