Security & Authentication¶
Overview¶
Traylinx uses a dual-token authentication model designed for secure agent-to-agent (A2A) communication while maintaining backward compatibility with user authentication.
The Dual-Token Model¶
| Token | Purpose | Used For | Header |
|---|---|---|---|
access_token |
Authenticate with Sentinel | Auth service calls only | Authorization: Bearer |
agent_secret_token |
Prove identity to other agents | A2A communication | X-Agent-Secret-Token |
Why Two Tokens?¶
PROBLEM: If stolen, a single token could impersonate an agent anywhere.
SOLUTION: Agent Secret Token is cryptographically bound to the agent's client_secret.
Only the legitimate owner can generate valid tokens.
Agent Secret Token Cryptography¶
Generation Flow¶
1. Agent authenticates → POST /oauth/token
├─ Input: client_id, client_secret
└─ Output: access_token + agent_secret_token
2. Agent Secret Token Structure:
┌──────────────────────────────────────────────────┐
│ AgentSecretToken_<nonce>_<encrypted_payload> │
└──────────────────────────────────────────────────┘
│
▼
Encrypted with: PBKDF2(client_secret) → AES-256-GCM
Security Guarantees¶
| Attack | Protection |
|---|---|
| Token Interception | AES-256-GCM encryption |
| Token Forgery | 128-bit authentication tags |
| Replay Attack | Timestamp + nonce + 1hr expiry |
| Brute Force | PBKDF2 with 10,000+ iterations |
| Man-in-the-Middle | TLS 1.3 required |
Authentication Flows¶
Flow 1: Agent-to-Agent (A2A)¶
Agent A Agent B
│ │
│ Headers: │
│ X-Agent-Secret-Token: xxx │
│ X-Agent-User-Id: agent-a │
│ Content-Type: application/ │
│ vnd.traylinx.a2a+json │
│─────────────────────────────────▶
│ │
│ │ 1. Extract token
│ │ 2. Validate via Sentinel
│ │ 3. Process request
│◀─────────────────────────────────
Flow 2: User-to-Service¶
User App Service
│ │
│ Headers: │
│ Authorization: Bearer xxx │
│─────────────────────────────────▶
│ │
│ │ 1. Extract token
│ │ 2. Validate via Auth Service
│ │ 3. Get user from DB
│◀─────────────────────────────────
Flow 3: Unified (Dual-Auth)¶
Services can accept both authentication types using our unified middleware:
from middleware.unified_auth import UnifiedAuthMiddleware, AuthMode
# Detection logic:
# - If X-Agent-Secret-Token present → AGENT mode
# - If Authorization: Bearer present → USER mode
@app.post("/api/task")
async def task_endpoint(auth: CallerIdentity = Depends(get_caller_identity)):
if auth.mode == AuthMode.AGENT:
print(f"Called by agent: {auth.agent_id}")
else:
print(f"Called by user: {auth.user_id}")
Service Authentication Status¶
Production Status (as of 2025-12-07)¶
| Service | User Auth | Agent Auth | Implementation |
|---|---|---|---|
| Agent Registry | N/A | ✅ | @require_a2a_auth |
| Router Agent | N/A | ✅ | @require_a2a_auth |
| Subscription Service | N/A | ✅ | @require_a2a_auth |
| Cortex | ✅ DB | ✅ Sentinel | get_caller_identity() |
| Agent Template | ✅ API Key | ✅ Sentinel | verify_unified_auth() |
| Agentic Search | ✅ Bearer | ✅ Sentinel | UnifiedAuthMiddleware |
| Agentic Translation | ✅ Bearer | ✅ Sentinel | UnifiedAuthMiddleware |
| Agentic Upload | ✅ Bearer | ✅ Sentinel | UnifiedAuthMiddleware |
Quick Reference: Adding Auth to Your Service¶
Option 1: Agent-Only (Simplest)¶
from traylinx_auth_client import require_a2a_auth
@router.post("/a2a/task")
@require_a2a_auth
async def agent_only_endpoint(request: Request):
agent_id = request.headers.get("x-agent-user-id")
return {"called_by": agent_id}
Option 2: Dual-Auth (Recommended)¶
from traylinx_auth_client import require_dual_auth, detect_auth_mode
@router.post("/api/task")
@require_dual_auth
async def unified_endpoint(request: Request):
mode = detect_auth_mode(request.headers)
# mode is "agent" or "user"
return {"auth_mode": mode}
Option 3: Full Middleware (Maximum Control)¶
See unified_auth.py for the complete implementation.
Environment Variables¶
All services using Sentinel auth require:
TRAYLINX_CLIENT_ID=your-agent-id
TRAYLINX_CLIENT_SECRET=your-secret
TRAYLINX_API_BASE_URL=https://api.makakoo.com/ma-authentication-ms/v1/api
TRAYLINX_AGENT_USER_ID=your-agent-id
Security Best Practices¶
- Never log tokens — Use masked versions:
token[:8]... - Always use HTTPS — TLS 1.3 is required
- Rotate secrets regularly — Implement key rotation
- Rate limit endpoints — Prevent brute-force attacks
- Monitor activity — Use Sentinel's activity logging