The Redis Agent Memory Server supports multiple authentication modes for secure API access. All API endpoints (except /v1/health, /docs, and /openapi.json) require valid authentication unless disabled for development.
The server supports three authentication modes:
- Disabled (default): No authentication required - suitable for development only
- Token Authentication: Simple API tokens stored in Redis with optional expiration
- OAuth2/JWT: Industry-standard authentication using JWT access tokens
- Simple Token Authentication: Generate and manage API tokens via CLI with optional expiration
- OAuth2/JWT Bearer Token Authentication: Industry-standard authentication using JWT access tokens
- JWKS Public Key Validation: Automatic fetching and caching of public keys for token signature verification
- Multi-Provider Support: Compatible with Auth0, AWS Cognito, Okta, Azure AD, and any standard OAuth2 provider
- Flexible Configuration: Environment variable-based configuration for different deployment scenarios
- Development Mode:
DISABLE_AUTHsetting for local development and testing - Role and Scope Support: Fine-grained access control using JWT claims
- CLI Token Management: Create, list, view, and remove tokens via command line
Authentication is configured using environment variables:
# Authentication Mode Selection
AUTH_MODE=disabled # Options: disabled, token, oauth2 (default: disabled)
# OR legacy setting:
DISABLE_AUTH=true # Set to true to bypass all authentication (development only)
# Token Authentication (when AUTH_MODE=token)
TOKEN_AUTH_ENABLED=true # Alternative way to enable token auth
# OAuth2 Provider Configuration (when AUTH_MODE=oauth2)
OAUTH2_ISSUER_URL=https://your-auth-provider.com
OAUTH2_AUDIENCE=your-api-audience
OAUTH2_JWKS_URL=https://your-auth-provider.com/.well-known/jwks.json # Optional, auto-derived from issuer
OAUTH2_ALGORITHMS=["RS256"] # Supported signing algorithmsTo use token authentication:
-
Enable token authentication:
export AUTH_MODE=token # OR export TOKEN_AUTH_ENABLED=true
-
Create tokens using the CLI:
# Create a token with 30-day expiration uv run agent-memory token add --description "API access token" --expires-days 30 # Create a permanent token (no expiration) uv run agent-memory token add --description "Service account token"
-
Use the token in API requests:
curl -H "Authorization: Bearer YOUR_TOKEN" \ http://localhost:8000/v1/working-memory/
The CLI provides comprehensive token management:
# List all tokens (shows masked token hashes)
uv run agent-memory token list
# Show details for a specific token (supports partial hash matching)
uv run agent-memory token show abc12345
# Remove a token (with confirmation)
uv run agent-memory token remove abc12345
# Remove a token without confirmation
uv run agent-memory token remove abc12345 --forceYou can use the token CLI to bootstrap authentication tokens in CI pipelines and infrastructure-as-code tools like Terraform.
The key features that make this work well are:
--format jsonon token commands (add,list,show) for machine-readable output--tokenontoken addto register a pre-generated secret from your CI or secrets manager
The example below generates a short-lived token during a workflow run and exposes it via GITHUB_ENV for later steps:
- name: Create agent-memory token for CI
run: |
TOKEN_JSON=$(agent-memory token add \
--description "CI bootstrap token" \
--expires-days 30 \
--format json)
echo "AGENT_MEMORY_TOKEN=$(echo "$TOKEN_JSON" | jq -r '.token')" >> "$GITHUB_ENV"Later steps can use AGENT_MEMORY_TOKEN as the bearer token when calling the API.
JSON output format for token add
When you use --format json, agent-memory token add returns a JSON object with fields like:
{
"token": "the-plaintext-token",
"hash": "abc12345def67890...",
"description": "CI bootstrap token",
"created_at": "2025-07-10T18:30:00.000000+00:00",
"expires_at": "2025-08-09T18:30:00.000000+00:00"
}You can extract any of these fields in your scripts (for example, .token or .hash with jq).
If you generate tokens outside Redis Agent Memory Server (for example via a secrets manager), you can register them using --token so the server only ever stores a hash:
variable "agent_memory_token" {
type = string
sensitive = true
}
resource "terraform_data" "agent_memory_token" {
provisioner "local-exec" {
environment = {
AGENT_MEMORY_TOKEN = var.agent_memory_token
}
command = <<EOT
TOKEN_JSON=$(agent-memory token add \
--description "Terraform bootstrap" \
--token "$AGENT_MEMORY_TOKEN" \
--format json)
echo "$TOKEN_JSON" > agent-memory-token.json
EOT
}
}For Terraform versions earlier than 1.4, you can use a null_resource instead of terraform_data.
In both cases, store the plaintext token in a secure secret store (GitHub Actions secrets, Terraform variables, Vault, etc.). The server will hash it before storing. When the CLI generates a token (without --token), it displays the plaintext only once; when using --token with a pre-generated value, ensure you've already stored it securely.
Security Features:
- Tokens are hashed using bcrypt before storage
- Only hashed values are stored in Redis (server never has access to plaintext tokens)
- Automatic expiration using Redis TTL
- Secure token generation using
secrets.token_urlsafe()
OAUTH2_ISSUER_URL=https://your-domain.auth0.com/
OAUTH2_AUDIENCE=https://your-api.comOAUTH2_ISSUER_URL=https://cognito-idp.region.amazonaws.com/your-user-pool-id
OAUTH2_AUDIENCE=your-app-client-idOAUTH2_ISSUER_URL=https://your-domain.okta.com/oauth2/default
OAUTH2_AUDIENCE=api://defaultOAUTH2_ISSUER_URL=https://login.microsoftonline.com/your-tenant-id/v2.0
OAUTH2_AUDIENCE=your-application-id# First, create a token
uv run agent-memory token add --description "My API token" --expires-days 30
# Use the returned token in API requests
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
http://localhost:8000/v1/working-memory/
# Python example
import httpx
headers = {
"Authorization": "Bearer YOUR_API_TOKEN",
"Content-Type": "application/json"
}
response = httpx.get("http://localhost:8000/v1/working-memory/", headers=headers)# Make authenticated API request with JWT
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
http://localhost:8000/v1/working-memory/
# Python example
import httpx
headers = {
"Authorization": "Bearer YOUR_JWT_TOKEN",
"Content-Type": "application/json"
}
response = httpx.get("http://localhost:8000/v1/working-memory/", headers=headers)# Set environment variable to disable auth
export DISABLE_AUTH=true
# Now you can make requests without tokens
curl -H "Content-Type: application/json" \
http://localhost:8000/v1/working-memory/- Valid token: Must exist in Redis and not be expired
- Secure generation: Generated using cryptographically secure random bytes
- Optional expiration: Tokens can be created with or without expiration dates
JWT tokens must include:
- Valid signature: Verified using JWKS public keys from the issuer
- Not expired:
expclaim must be in the future - Valid audience:
audclaim must matchOAUTH2_AUDIENCE(if configured) - Valid issuer:
issclaim must matchOAUTH2_ISSUER_URL - Subject:
subclaim identifying the user/client
Authentication failures return HTTP 401 with details:
{
"detail": "Invalid JWT: Token has expired",
"status_code": 401
}Common error scenarios:
General Authentication Errors:
Missing authorization header: NoAuthorization: Bearerheader providedMissing bearer token: Empty or malformed authorization header
Token Authentication Errors:
Invalid token: Token not found in Redis or malformedToken has expired: Token expiration date has passed
OAuth2/JWT Authentication Errors:
Invalid token header: Malformed JWT structureToken has expired: JWTexpclaim is in the pastInvalid audience: JWTaudclaim doesn't match expected audienceUnable to find matching public key: JWKS doesn't contain key for token'skid
- Never use
DISABLE_AUTH=truein production - Use HTTPS in production to protect tokens in transit
- Monitor authentication failures and implement rate limiting if needed
- Handle 401 responses appropriately in your clients
- Validate tokens server-side - never trust client-side validation alone
- Use token expiration when creating tokens for enhanced security
- Rotate tokens regularly by removing old tokens and creating new ones
- Store tokens securely in your applications (use environment variables, not code)
- Remove unused tokens using the CLI to minimize attack surface
- Monitor token usage and remove tokens that are no longer needed
- Implement token refresh in your clients for long-running applications
- Use appropriate scopes/roles for fine-grained access control
- Validate token expiration and audience claims properly
- Cache JWKS appropriately but refresh periodically
For comprehensive Auth0 testing instructions, see the manual OAuth testing guide.