Authentication
AutoMem uses a two-tier token-based authentication system to control access to different classes of operations. All endpoints except /health require a valid API token.
For deployment-specific token generation on Railway, see Railway Deployment. For complete endpoint documentation with authentication requirements, see Memory Operations.
Token Types
Section titled “Token Types”| Token Type | Environment Variable | Required For | Purpose |
|---|---|---|---|
| API Token | AUTOMEM_API_TOKEN | All endpoints except /health | Standard memory operations (store, recall, update, delete) |
| Admin Token | ADMIN_API_TOKEN | Admin and enrichment endpoints | Privileged operations (reprocessing, re-embedding, bulk operations) |
Authentication Methods
Section titled “Authentication Methods”AutoMem accepts authentication credentials via three methods, checked in the following priority order:
graph TD
Request["Incoming Request"]
CheckBearer{"Authorization header<br/>starts with 'Bearer'?"}
ExtractBearer["Extract token<br/>from Bearer string"]
CheckCustomHeader{"X-API-Key or<br/>X-API-Token header?"}
ExtractHeader["Extract token<br/>from header"]
CheckQuery{"Query param<br/>api_key/apiKey/api_token?"}
ExtractQuery["Extract token<br/>from query string"]
NoToken["Return None<br/>→ 401 Unauthorized"]
ValidateToken["Validate against<br/>AUTOMEM_API_TOKEN or<br/>ADMIN_API_TOKEN"]
Request --> CheckBearer
CheckBearer -->|Yes| ExtractBearer
CheckBearer -->|No| CheckCustomHeader
CheckCustomHeader -->|Yes| ExtractHeader
CheckCustomHeader -->|No| CheckQuery
CheckQuery -->|Yes| ExtractQuery
CheckQuery -->|No| NoToken
ExtractBearer --> ValidateToken
ExtractHeader --> ValidateToken
ExtractQuery --> ValidateToken
1. Bearer Token (Recommended)
Section titled “1. Bearer Token (Recommended)”Standard OAuth 2.0-style authentication using the Authorization header:
curl -H "Authorization: Bearer YOUR_API_TOKEN" \ https://your-service.railway.app/recall?q=queryAdvantages:
- Industry standard
- Automatically handled by most HTTP libraries
- Cannot be logged in server access logs (more secure than query params)
2. Custom Header
Section titled “2. Custom Header”Alternative header-based authentication using X-API-Key:
curl -H "X-API-Key: YOUR_API_TOKEN" \ https://your-service.railway.app/recall?q=queryUse this when client libraries do not support Bearer tokens easily.
3. Query Parameter
Section titled “3. Query Parameter”Fallback authentication via URL query string:
curl "https://your-service.railway.app/recall?q=query&api_key=YOUR_API_TOKEN"Full Token Validation Flow
Section titled “Full Token Validation Flow”This diagram shows how requests flow through both the MCP SSE server and the Flask API:
graph LR
subgraph "Token Sources"
BearerHeader["Authorization: Bearer TOKEN"]
APIKeyHeader["X-API-Key: TOKEN"]
QueryParam["?api_key=TOKEN"]
end
subgraph "mcp-sse-server :8080"
GetAuthToken["getAuthToken(req)"]
ValidateToken["Compare vs<br/>AUTOMEM_API_TOKEN"]
AddAuthHeader["Add Authorization:<br/>Bearer header"]
end
subgraph "Flask API :8001"
RequireAPIToken["@require_api_token"]
ExtractToken["extract_token(request)<br/>multiple sources"]
CheckLevel["Check endpoint<br/>requires ADMIN?"]
ValidateAdmin["Validate<br/>ADMIN_API_TOKEN"]
ProcessRequest["Route to handler"]
end
BearerHeader --> GetAuthToken
APIKeyHeader --> GetAuthToken
QueryParam --> GetAuthToken
GetAuthToken --> ValidateToken
ValidateToken -->|Valid| AddAuthHeader
ValidateToken -->|Invalid| Reject401["401 Unauthorized"]
AddAuthHeader --> RequireAPIToken
RequireAPIToken --> ExtractToken
ExtractToken --> CheckLevel
CheckLevel -->|Standard| ProcessRequest
CheckLevel -->|Admin endpoint| ValidateAdmin
ValidateAdmin -->|Valid| ProcessRequest
ValidateAdmin -->|Invalid| Reject403["403 Forbidden"]
Admin Authentication
Section titled “Admin Authentication”Admin endpoints require both the API token and an additional admin token. The admin token is provided in a separate X-Admin-Token header:
curl -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "X-Admin-Token: YOUR_ADMIN_TOKEN" \ -X POST https://your-service.railway.app/enrichment/reprocessAdmin-Protected Endpoints
Section titled “Admin-Protected Endpoints”| Endpoint | Method | Purpose |
|---|---|---|
/admin/reembed | POST | Regenerate embeddings in batches |
/enrichment/reprocess | POST | Re-queue memories for enrichment |
/enrichment/status | GET | View enrichment pipeline status |
Endpoint Authentication Requirements
Section titled “Endpoint Authentication Requirements”graph TB
subgraph "Public Endpoints"
Health["/health<br/>GET"]
end
subgraph "API Token Required"
Memory["/memory<br/>POST, GET, PATCH, DELETE"]
Recall["/recall<br/>GET"]
Associate["/associate<br/>POST"]
ByTag["/memory/by-tag<br/>GET"]
Consolidate["/consolidate<br/>POST, GET"]
Analyze["/analyze<br/>GET"]
StartupRecall["/startup-recall<br/>GET"]
end
subgraph "Admin Token Required"
Reembed["/admin/reembed<br/>POST"]
Reprocess["/enrichment/reprocess<br/>POST"]
EnrichStatus["/enrichment/status<br/>GET"]
end
style Health fill:#90EE90
style Memory fill:#FFD700
style Recall fill:#FFD700
style Associate fill:#FFD700
style ByTag fill:#FFD700
style Consolidate fill:#FFD700
style Analyze fill:#FFD700
style StartupRecall fill:#FFD700
style Reembed fill:#FF6B6B
style Reprocess fill:#FF6B6B
style EnrichStatus fill:#FF6B6B
| Category | Endpoints | API Token | Admin Token |
|---|---|---|---|
| Public | /health | No | No |
| Standard | /memory, /recall, /associate, /memory/by-tag, /consolidate, /analyze, /startup-recall | Yes | No |
| Admin | /admin/reembed, /enrichment/reprocess, /enrichment/status | Yes | Yes |
Configuration
Section titled “Configuration”Environment Variables
Section titled “Environment Variables”Configure authentication tokens via environment variables loaded in this order:
- Process environment (e.g.,
export AUTOMEM_API_TOKEN=...) .envfile in project root~/.config/automem/.env(user-specific configuration)
The variables API_TOKEN and ADMIN_TOKEN are accepted as backward-compatible aliases for AUTOMEM_API_TOKEN and ADMIN_API_TOKEN respectively.
Token Generation
Section titled “Token Generation”Railway (Automatic):
Railway’s template automatically generates secure tokens using the generator: secret directive in railway-template.json. No manual action required.
Manual (Local Development):
Generate secure tokens using OpenSSL:
# Generate API tokenopenssl rand -hex 32
# Generate Admin token (use a different value)openssl rand -hex 32Client Integration Examples
Section titled “Client Integration Examples”Python (requests)
Section titled “Python (requests)”import requests
headers = { "Authorization": f"Bearer {api_token}", "Content-Type": "application/json"}
response = requests.post( "https://your-service.railway.app/memory", headers=headers, json={"content": "Important decision made today", "type": "Decision"})JavaScript (fetch)
Section titled “JavaScript (fetch)”const response = await fetch("https://your-service.railway.app/recall?q=decisions", { headers: { "Authorization": `Bearer ${apiToken}`, }});const data = await response.json();# Store a memorycurl -X POST https://your-service.railway.app/memory \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"content": "Prefer PostgreSQL for relational data", "type": "Preference"}'
# Recall memoriescurl "https://your-service.railway.app/recall?q=database+preferences" \ -H "Authorization: Bearer YOUR_TOKEN"MCP Client Authentication
Section titled “MCP Client Authentication”NPM Package (@verygoodplugins/mcp-automem)
Section titled “NPM Package (@verygoodplugins/mcp-automem)”Desktop tools like Claude Desktop and Cursor IDE use the NPM package, which requires API token configuration in the platform’s MCP config file:
{ "mcpServers": { "automem": { "command": "npx", "args": ["-y", "@verygoodplugins/mcp-automem"], "env": { "AUTOMEM_ENDPOINT": "https://your-service.railway.app", "AUTOMEM_API_KEY": "YOUR_API_TOKEN" } } }}The client automatically injects the token as Authorization: Bearer header on all requests.
SSE Bridge (mcp-sse-server)
Section titled “SSE Bridge (mcp-sse-server)”For cloud-based AI platforms (ChatGPT, ElevenLabs), the SSE bridge requires AUTOMEM_API_TOKEN set in the Railway environment. The bridge validates incoming requests against this token and forwards them to the AutoMem API transparently.
Security Best Practices
Section titled “Security Best Practices”| Practice | Description | Priority |
|---|---|---|
| Strong tokens | Use cryptographically random tokens (32+ bytes) | Critical |
| Environment variables | Never hardcode tokens in code or commit to Git | Critical |
| Separate admin tokens | Use different tokens for API and admin access | Critical |
| HTTPS only | Always use HTTPS in production (Railway provides automatically) | Critical |
| Prefer Bearer auth | Use Authorization: Bearer over query params | High |
| Rotate regularly | Change tokens every 90 days or after suspected exposure | High |
| Environment separation | Different tokens for dev/staging/production | High |
| Monitor logs | Watch for 401 errors indicating unauthorized attempts | Medium |
| Audit trail | Log who performs admin operations (via admin token) | Medium |
Common Security Mistakes
Section titled “Common Security Mistakes”| Mistake | Risk | Solution |
|---|---|---|
| Committing tokens to Git | Public exposure, unauthorized access | Use .gitignore, environment variables |
| Using same token everywhere | Single point of compromise | Separate tokens per environment |
| Query param authentication in production | Tokens logged in server logs | Use Bearer header |
| No admin token separation | Anyone with API access can perform admin ops | Configure separate ADMIN_API_TOKEN |
| Weak tokens (e.g., “password123”) | Easy to guess/brute force | Use cryptographic generators |
Token Rotation Procedure
Section titled “Token Rotation Procedure”When rotating tokens (for example, after suspected exposure or periodic maintenance):
- Generate new tokens:
openssl rand -hex 32 - Update server environment variables (Railway dashboard or CLI)
- Update all clients with new tokens before removing old tokens
- Test connectivity with new tokens
- Remove old tokens from server configuration entirely
- Restart the service to ensure old tokens are not cached
Troubleshooting
Section titled “Troubleshooting”401 Unauthorized
Section titled “401 Unauthorized”Symptom: All requests return 401 Unauthorized
Common causes:
- Token not set in environment variable — verify with
echo $AUTOMEM_API_TOKEN - Typo in token value — check for trailing spaces or newlines
- Using wrong token (API token vs admin token)
- Token mismatch between client and server
Diagnosis:
# Test your token directlycurl -v -H "Authorization: Bearer YOUR_TOKEN" \ https://your-service.railway.app/recall?q=testAdmin Endpoint Returns 401
Section titled “Admin Endpoint Returns 401”Symptom: Standard endpoints work, but admin endpoints return 401 Unauthorized
Common causes:
- Missing
X-Admin-Tokenheader — admin endpoints require both headers ADMIN_API_TOKENnot configured on server- Admin token mismatch between client and server
Token Exposure Response
Section titled “Token Exposure Response”If a token is exposed (committed to Git, shared in logs):
- Immediate rotation: Generate a new token and update server configuration — deploy immediately
- Audit access: Check server logs for unauthorized requests; look for unusual patterns in
/healthor/analyzeendpoints - Revoke old token: Remove from environment variables and restart the service to ensure it is not cached