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 Var | Example | What It Is |
|---|---|---|
XPRESSAI_NAMESPACE | xpressai | Kubernetes namespace the agent pod runs in |
XPRESSAI_PROJECT_ID | personal-egonzalez | Database project ID (used for API auth and data isolation) |
AGENT_NAME | toby | Agent's service name (used for participant lookup and display) |
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
| Header | Source | Used For |
|---|---|---|
X-Task-Authorization | SHA-1(projectId + tokenSecret) | Authentication -- validated against project's token secret |
X-Task-Namespace | XPRESSAI_NAMESPACE env var | Routing -- identifies which K8s namespace the agent runs in |
X-Agent-Name | AGENT_NAME env var | Identity -- 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 Type | ID Format | Example | File Path |
|---|---|---|---|
| Personal | personal-{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.
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.