Authentication Guide
Complete authentication reference for the AI Security Gateway API.
📘 Quick Reference: This guide covers authentication for the 20 most commonly used API endpoints. Additional authentication features (RBAC, user groups, delegation) will be documented in future releases.
Overview
The AI Security Gateway supports three authentication methods for API access:
- Admin JWT Tokens - For administrative access via username/password
- OAuth Session Tokens - For users authenticated via OAuth providers
- API Keys - For service accounts and automation
All three methods use the same Authorization: Bearer header format (except API keys which use X-API-Key).
Method 1: Admin JWT Authentication
Best for: Command-line tools, scripts, administrative access
Login to Get JWT Token
Endpoint: POST /api/v1/auth/login
Authentication: None required (public endpoint)
Request:
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "admin",
"password": "yourpassword"
}' | jqResponse:
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 1,
"username": "admin",
"email": "admin@company.com",
"role": "admin"
},
"expires_at": "2026-02-04T12:00:00Z"
}
}Save Token for Reuse:
# Extract and save token
export JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' | jq -r '.data.token')
# Verify token is set
echo $JWT_TOKENUse JWT Token in API Requests
All subsequent API requests include the Authorization header:
# List all proxies
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/ | jq
# Get proxy status
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/1/status | jq
# Create new proxy (requires admin role)
curl -s -X POST http://localhost:8080/api/v1/proxies/ \
-H "Authorization: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-proxy",
"type": "mcp",
"target": "http://localhost:3000",
"port": 8081
}' | jqGet Current User Profile
Endpoint: GET /api/v1/auth/me
Authentication: Required (JWT token)
Request:
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/auth/me | jqResponse:
{
"success": true,
"data": {
"id": 1,
"username": "admin",
"email": "admin@company.com",
"role": "admin",
"created_at": "2026-01-15T10:00:00Z"
}
}Refresh JWT Token
Endpoint: POST /api/v1/auth/refresh
Authentication: Required (existing JWT token, even if expired)
Request:
curl -s -X POST http://localhost:8080/api/v1/auth/refresh \
-H "Authorization: Bearer $JWT_TOKEN" | jqResponse:
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_at": "2026-02-05T12:00:00Z"
}
}Update Token Variable:
# Refresh and save new token
export JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/refresh \
-H "Authorization: Bearer $JWT_TOKEN" | jq -r '.data.token')Logout
Endpoint: POST /api/v1/auth/logout
Authentication: Required (JWT token)
Request:
curl -s -X POST http://localhost:8080/api/v1/auth/logout \
-H "Authorization: Bearer $JWT_TOKEN" | jqResponse:
{
"success": true,
"message": "Logged out successfully"
}Method 2: OAuth Session Tokens
Best for: Users authenticated via OAuth providers (GitHub, Google, Microsoft, Okta, Azure AD)
Obtain OAuth Session Token
Option A: Via Web UI (Recommended)
# Navigate to web interface
open http://localhost:8080/
# Click "Login with [Provider]" (GitHub, Google, etc.)
# After successful authentication, extract session token from:
# - Browser localStorage: localStorage.getItem('session_token')
# - Or from the OAuth callback responseOption B: Programmatic OAuth Flow
See OAuth API Reference for complete OAuth flow documentation.
Use OAuth Session Token
OAuth session tokens work identically to admin JWT tokens:
# Save OAuth session token
export JWT_TOKEN="<session-token-from-oauth-login>"
# Use same Authorization header format
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/ | jqNo difference in API usage - OAuth session tokens and admin JWT tokens are interchangeable in API requests.
Validate OAuth Session
Endpoint: POST /api/v1/oauth/validate
Authentication: None required (validates provided token)
Request:
curl -s -X POST http://localhost:8080/api/v1/oauth/validate \
-H "Content-Type: application/json" \
-d '{
"session_token": "YOUR_SESSION_TOKEN"
}' | jqResponse:
{
"success": true,
"data": {
"valid": true,
"user_identity": "alice@company.com",
"user_email": "alice@company.com",
"user_name": "Alice Smith",
"expires_at": "2026-02-04T15:00:00Z"
}
}Method 3: API Key Authentication
Best for: Service accounts, automation, CI/CD pipelines
Create API Key
API keys are created via admin endpoints or web UI (creation endpoint documentation coming in future release).
Use API Key
Unlike JWT tokens, API keys use the X-API-Key header:
# Use X-API-Key header instead of Authorization
curl -s -H "X-API-Key: YOUR_API_KEY" \
http://localhost:8080/api/v1/proxies/ | jq
# API keys are scoped to user groups with specific permissions
curl -s -H "X-API-Key: YOUR_API_KEY" \
http://localhost:8080/api/v1/proxies/1/status | jqAPI Key Characteristics:
- Scoped to user groups (limited access to authorized proxies/agents)
- Subject to rate limits per user group
- Cannot perform admin operations (create users, manage OAuth providers)
- Best for read-only monitoring or limited automation
Role-Based Access Control (RBAC)
Different API endpoints require different roles:
Role Hierarchy
| Role | Permissions |
|---|---|
| Viewer | Read-only access (list proxies, view status, logs, statistics) |
| Operator | Viewer permissions + start/stop proxies |
| Admin | Full access (create, update, delete proxies/policies/users) |
Examples by Role
Viewer Role - Can Access:
# List proxies
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/ | jq
# Get proxy status
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/1/status | jq
# View logs
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/1/logs | jqAdmin Role - Required For:
# Create proxy (admin only)
curl -s -X POST http://localhost:8080/api/v1/proxies/ \
-H "Authorization: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{...}' | jq
# Assign policies (admin only)
curl -s -X POST http://localhost:8080/api/v1/proxies/1/policies \
-H "Authorization: Bearer $JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{...}' | jq
# Discover MCP tools (admin only)
curl -s -X POST http://localhost:8080/api/v1/proxies/1/tools/discover \
-H "Authorization: Bearer $JWT_TOKEN" | jqPublic Endpoints (No Authentication Required)
The following endpoints are public and do not require authentication:
Health Checks
# System health check
curl -s http://localhost:8080/api/v1/health | jq
# OAuth health check
curl -s http://localhost:8080/api/v1/oauth/health | jqOAuth Flow Endpoints
# OAuth authorization (redirects to provider)
curl -s http://localhost:8080/api/v1/oauth/authorize
# OAuth callback (handled by browser)
# http://localhost:8080/api/v1/oauth/callback?code=...&state=...Authentication Endpoints
# Login (get token)
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{...}' | jq
# Token refresh (technically requires token, but accepts expired ones)
curl -X POST http://localhost:8080/api/v1/auth/refresh \
-H "Authorization: Bearer $EXPIRED_TOKEN" | jqCommon Authentication Scenarios
Scenario 1: Command-Line Script
#!/bin/bash
# Login once, reuse token
JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' | jq -r '.data.token')
# Check if login succeeded
if [ -z "$JWT_TOKEN" ] || [ "$JWT_TOKEN" = "null" ]; then
echo "Login failed"
exit 1
fi
# Use token for multiple requests
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/ | jq
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/1/status | jqScenario 2: CI/CD Pipeline
# GitHub Actions example
steps:
- name: Monitor Proxy Status
env:
API_KEY: ${{ secrets.GATEWAY_API_KEY }}
run: |
curl -s -H "X-API-Key: $API_KEY" \
http://gateway.company.com/api/v1/proxies/status | jqScenario 3: OAuth User Script
#!/bin/bash
# User already has OAuth session token from web login
export JWT_TOKEN="<paste-session-token-here>"
# Use for API access
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/ | jqTroubleshooting
401 Unauthorized
Problem: API returns 401 Unauthorized
Solutions:
# Check if token is set
echo $JWT_TOKEN
# Verify token is valid
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/auth/me | jq
# Token expired? Refresh it
export JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/refresh \
-H "Authorization: Bearer $JWT_TOKEN" | jq -r '.data.token')
# Still failing? Login again
export JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' | jq -r '.data.token')403 Forbidden
Problem: API returns 403 Forbidden
Cause: Insufficient permissions (wrong role)
Solution: Check user role and endpoint requirements
# Get current user info
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/auth/me | jq '.data.role'
# Admin operations require admin role
# Viewer role can only read dataToken Refresh Fails
Problem: Refresh endpoint returns error
Solution: Token is too old or invalid, login again
# Force new login
unset JWT_TOKEN
export JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' | jq -r '.data.token')Best Practices
Security
- Never commit tokens to git - Use environment variables or secrets management
- Use API keys for automation - More auditable than shared admin credentials
- Rotate tokens regularly - Use refresh endpoint for long-running scripts
- Minimum permissions - Use viewer role when read-only access is sufficient
Token Management
# Good: Save token to secure location
echo "$JWT_TOKEN" > ~/.gateway-token
chmod 600 ~/.gateway-token
# Load token when needed
export JWT_TOKEN=$(cat ~/.gateway-token)
# Bad: Don't hardcode in scripts
JWT_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # ❌ Don't do thisError Handling
# Always check for errors
response=$(curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/proxies/ | jq)
if echo "$response" | jq -e '.success == false' > /dev/null; then
echo "Error: $(echo "$response" | jq -r '.error')"
exit 1
fiRelated Documentation
- API Examples - Practical usage examples for common workflows
- Proxy API Reference - Complete proxy management API documentation
- OAuth API Reference - OAuth provider setup and management
- A2A API Reference - Agent-to-Agent (A2A) API documentation
Quick Reference
Login Commands
# Admin JWT login
export JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin"}' | jq -r '.data.token')
# Refresh token
export JWT_TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/refresh \
-H "Authorization: Bearer $JWT_TOKEN" | jq -r '.data.token')
# Get current user
curl -s -H "Authorization: Bearer $JWT_TOKEN" \
http://localhost:8080/api/v1/auth/me | jq
# Logout
curl -s -X POST http://localhost:8080/api/v1/auth/logout \
-H "Authorization: Bearer $JWT_TOKEN" | jqHeader Formats
# JWT/OAuth tokens
-H "Authorization: Bearer $JWT_TOKEN"
# API keys
-H "X-API-Key: YOUR_API_KEY"