Skip to main content

Agent Identity Model

This page focuses on the conceptual identity model for agents -- the three identifiers and how they relate. For details on the HTTP headers agents send when calling the platform API, see Agent API Headers.

Every running agent has three distinct identifiers. Confusing them is a common source of bugs -- especially around authentication.

The Three Identifiers

Env VarExampleWhat It Is
XPRESSAI_NAMESPACExpressaiKubernetes namespace the agent pod runs in
XPRESSAI_PROJECT_IDpersonal-egonzalezDatabase project ID (used for API auth and data isolation)
AGENT_NAMEtobyAgent's service name (used for participant lookup and display)
Common mistake

Do not use XPRESSAI_NAMESPACE for token validation. The authentication hash is computed from XPRESSAI_PROJECT_ID, not the namespace. Using the wrong value means the hash will never match.

Token Validation

Agent API tokens are computed as:

SHA-1(projectId + tokenSecret)

The result is a hex-encoded SHA-1 hash string (40 hex characters). For example:

# Concatenate projectId and tokenSecret, then SHA-1 hash:
echo -n "personal-egonzalezyour-token-secret" | sha1sum
# Output: 5a3f8c1d... (40 hex characters)

The platform validates this token against XPRESSAI_PROJECT_ID. The namespace is irrelevant to authentication.

# Correct -- uses projectId
import hashlib
token = hashlib.sha1((project_id + token_secret).encode()).hexdigest()

# Wrong -- uses namespace, hash will never match
token = hashlib.sha1((namespace + token_secret).encode()).hexdigest()

Request Headers

Agents send these headers on every platform API call (via platform_client.py):

X-Task-Authorization: <SHA-1 token>
X-Task-Namespace: <XPRESSAI_NAMESPACE>
X-Agent-Name: <AGENT_NAME>
Content-Type: application/json
HeaderSourceUsed For
X-Task-AuthorizationSHA-1(projectId + tokenSecret)Authentication -- validated against project's token secret
X-Task-NamespaceXPRESSAI_NAMESPACE env varRouting -- identifies which K8s namespace the agent runs in
X-Agent-NameAGENT_NAME env varIdentity -- used to look up the agent via agentRepository.findByNameAndProjectId()

How Endpoints Get the Project ID

Platform endpoints need the project ID to validate the token and scope data access. There are two patterns:

URL Path (Preferred)

GET /api/projects/{projectId}/conversations/...

The agent passes XPRESSAI_PROJECT_ID in the URL. The endpoint extracts it from the path parameter.

Request Body

{
"project_id": "personal-egonzalez",
"subject": "Follow-up"
}

Used when the URL structure does not include a project ID segment (e.g., AgentEmailResource).

Personal vs Team Projects

The project ID format determines data isolation:

Project TypeID FormatExampleFile Path
Personalpersonal-{userId}personal-egonzalez/data/home/{userId}/
Team{teamSlug}marketing-team-42/data/home/projects/{projectId}/

Personal projects are identified by the personal- prefix. See the platform's directory resolution pattern for details on how file paths are derived from project IDs.

warning

The legacy constant "personal" (without a user ID suffix) is deprecated. Always use "personal-{userId}" format. Using the bare "personal" string causes the platform to treat it as a team project, resolving to the wrong directory.