API Server Authentication
Authentication for auto-generated API servers created by praisonai deploy
from praisonaiagents import Agent
agent = Agent(name="auth-agent", instructions="Handle authenticated API requests.")
agent.start("Verify the API key and process this request.")API servers generated by praisonai deploy run --type api require bearer token authentication by default as of PraisonAI 4.6.34.
The user calls a deployed API with a bearer token; the server rejects unauthenticated requests before the agent runs.
Quick Start
- Default (auth on)
Start the API server and capture the auto-generated token from stderr:
bash praisonai deploy run --type api # Look for output like: # [praisonai-api] generated API token: abc123def456ghi789...Then make authenticated requests:
bash curl -H "Authorization: Bearer abc123def456ghi789..." \ http://127.0.0.1:8080/agents - Bring your own token
Set your own bearer token before starting:
bash export PRAISONAI_API_TOKEN=your-secret-token praisonai deploy run --type apiUse your token in requests:
bash curl -H "Authorization: Bearer your-secret-token" \ http://127.0.0.1:8080/agents - Disable auth (legacy)
Disable authentication explicitly:
bash export PRAISONAI_API_AUTH=disabled export PRAISONAI_API_HOST=0.0.0.0 # Optional: bind to all interfaces praisonai deploy run --type api
How It Works
| Component | Purpose |
|---|---|
| Bearer Token | Secret key required in Authorization header |
| Constant-time Comparison | Prevents timing oracle attacks |
| stderr Output | Auto-generated tokens printed securely |
| Environment Override | PRAISONAI_API_TOKEN for custom tokens |
Environment Variables
| Variable | Default | Purpose |
|---|---|---|
PRAISONAI_API_AUTH | enabled | enabled (default) or disabled |
PRAISONAI_API_TOKEN | auto-generated | Bearer token required when auth is enabled. If unset, a 32-byte URL-safe random token is generated at startup and printed to stderr. |
PRAISONAI_API_HOST | 127.0.0.1 | Bind host. Set to 0.0.0.0 only behind an authenticating proxy. |
PRAISONAI_API_PORT | 8080 | Bind port. |
Configuration Examples
# Default secure setup
praisonai deploy run --type api
# Custom token
export PRAISONAI_API_TOKEN=my-secret-key-123
praisonai deploy run --type api
# Disable auth (not recommended)
export PRAISONAI_API_AUTH=disabled
praisonai deploy run --type api
# Bind to all interfaces with auth
export PRAISONAI_API_HOST=0.0.0.0
export PRAISONAI_API_TOKEN=secure-token
praisonai deploy run --type apiAPIConfig Reference
The APIConfig class in praisonai.deploy.models now defaults to secure settings:
deploy:
type: api
api:
host: 127.0.0.1 # Changed from 0.0.0.0
port: 8080
workers: 1
cors_enabled: true
auth_enabled: true # Changed from falseBefore vs After 4.6.34
deploy:
type: api
api:
- host: 0.0.0.0
+ host: 127.0.0.1
port: 8080
workers: 1
cors_enabled: true
- auth_enabled: false
+ auth_enabled: trueSecurity Details
Security Features
- Constant-time token comparison using
secrets.compare_digest()prevents timing oracle attacks - Auto-generated tokens are cryptographically secure (32 bytes, URL-safe)
- stderr output only – tokens never appear in HTTP responses or logs
- Localhost binding by default – reduces attack surface
- Unauthenticated health endpoint at
/healthfor monitoring
Token Generation
# Equivalent to the auto-generation process
import secrets
token = secrets.token_urlsafe(32) # 43 character URL-safe stringCommon Patterns
cURL Examples
# Get available agents
curl -H "Authorization: Bearer YOUR_TOKEN" \
http://127.0.0.1:8080/agents
# Chat with agent
curl -X POST http://127.0.0.1:8080/chat \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "Hello, how can you help me?"}'
# Health check (no auth required)
curl http://127.0.0.1:8080/healthPython Requests
import requests
# Set up session with auth
session = requests.Session()
session.headers.update({
"Authorization": "Bearer YOUR_TOKEN",
"Content-Type": "application/json"
})
# Get agents
response = session.get("http://127.0.0.1:8080/agents")
agents = response.json()
# Chat with agent
response = session.post("http://127.0.0.1:8080/chat", json={
"message": "What is artificial intelligence?"
})
chat_response = response.json()Environment File Setup
# .env file
PRAISONAI_API_TOKEN=your-secure-token-here
PRAISONAI_API_HOST=127.0.0.1
PRAISONAI_API_PORT=8080
PRAISONAI_API_AUTH=enabledMigration from < 4.6.34
I just want my old setup back
Quick fix for existing deployments:
# Disable auth and bind to all interfaces (like before)
export PRAISONAI_API_AUTH=disabled
export PRAISONAI_API_HOST=0.0.0.0
praisonai deploy run --type apiI want to keep auth on but rotate the token
Recommended approach:
# Generate your own token
export PRAISONAI_API_TOKEN=$(openssl rand -base64 32)
praisonai deploy run --type api
echo "Your token: $PRAISONAI_API_TOKEN"Store the token securely and update your clients.
I want my server reachable on the LAN
Secure LAN deployment:
# Bind to all interfaces but keep auth enabled
export PRAISONAI_API_HOST=0.0.0.0
export PRAISONAI_API_TOKEN=your-secure-shared-token
praisonai deploy run --type apiShare the token only with trusted clients on your network.
Best Practices
Token Management
- Generate strong tokens: Use
openssl rand -base64 32or similar - Rotate tokens regularly: Update
PRAISONAI_API_TOKENand restart - Store securely: Never commit tokens to version control
- Use environment variables: Keep tokens out of configuration files
- Scope tokens appropriately: Different tokens for dev/staging/prod
Network Security
- Default localhost binding: Keep
host: 127.0.0.1unless necessary - TLS termination: Front with nginx/cloudflare for HTTPS
- Firewall rules: Restrict port 8080 access to known sources
- VPN access: Use VPN instead of public exposure when possible
Development vs Production
- Development: Use auto-generated tokens, localhost binding
- Staging: Custom tokens, restricted network access
- Production: Strong tokens, TLS frontend, monitoring
- CI/CD: Separate tokens per environment, secret management
Monitoring and Logging
- Monitor
/health: Unauthenticated endpoint for status checks - Log 401 responses: Track authentication failures
- Alert on token exposure: Watch for tokens in logs/errors
- Audit token usage: Track which clients use which tokens
SDK .launch() Authentication
Agent.launch() and Agents.launch() are a different server from praisonai deploy and use PRAISONAI_LAUNCH_AUTH_TOKEN (not PRAISONAI_API_TOKEN).
| Server | Env var | Default host |
|---|---|---|
praisonai deploy run --type api | PRAISONAI_API_TOKEN | 127.0.0.1 |
Agent.launch() / Agents.launch() | PRAISONAI_LAUNCH_AUTH_TOKEN | 127.0.0.1 |
.launch() has three states:
| State | Trigger | Behaviour |
|---|---|---|
| Keyless dev | No token + loopback host | No auth. agent.launch(port=8000) works locally. |
| Enforced | PRAISONAI_LAUNCH_AUTH_TOKEN set | Every request needs the token or gets 401. |
| Fail-closed | No token + non-loopback host | The SDK auto-generates a one-time token, prints it to stdout, and enforces it. |
export PRAISONAI_LAUNCH_AUTH_TOKEN=$(openssl rand -base64 32)from praisonaiagents import Agent
agent = Agent(name="public", instructions="Answer.")
agent.launch(host="0.0.0.0", port=8000) # enforces the token abovecurl -X POST http://SERVER:8000/ \
-H "Authorization: Bearer $PRAISONAI_LAUNCH_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"message": "hi"}'Full details: Agent API Launch → Authentication.