Authentication and authorization agent for Sentinel reverse proxy. Supports JWT/Bearer tokens, OIDC/OAuth 2.0, API keys, Basic authentication, SAML SSO, and mTLS client certificates.
- JWT/Bearer tokens - HS256, RS256, ES256 and other algorithms
- OIDC/OAuth 2.0 - OpenID Connect with automatic JWKS key rotation
- API keys - Simple header-based authentication
- Basic auth - Username/password authentication
- SAML SSO - Enterprise single sign-on with session persistence
- mTLS Client Certificates - X.509 certificate-based authentication
- Cedar Policy Engine - Policy-as-code authorization with fine-grained access control
- Token Exchange (RFC 8693) - Convert between token types (SAML to JWT, external to internal JWT)
- Configurable user ID and auth method headers
- Fail-open mode for graceful degradation
- Comprehensive audit logging
- Configuration Reference - Complete configuration options
- SAML Authentication - SAML SSO setup and IdP integration
- Session Management - Session persistence and lifecycle
- OIDC Authentication - OIDC/OAuth 2.0 with JWKS
- mTLS Authentication - Client certificate authentication
- Authorization - Cedar policy engine guide
- Token Exchange - RFC 8693 token exchange
cargo install sentinel-agent-authgit clone https://github.com/raskell-io/sentinel-agent-auth
cd sentinel-agent-auth
cargo build --releasesentinel-auth-agent --socket /var/run/sentinel/auth.sock \
--jwt-secret "your-secret-key" \
--api-keys "key1:app1,key2:app2"| Option | Environment Variable | Description | Default |
|---|---|---|---|
--socket |
AGENT_SOCKET |
Unix socket path | /tmp/sentinel-auth.sock |
--jwt-secret |
JWT_SECRET |
JWT secret key (for HS256) | - |
--jwt-public-key |
JWT_PUBLIC_KEY |
JWT public key file (for RS/ES) | - |
--jwt-algorithm |
JWT_ALGORITHM |
JWT algorithm | HS256 |
--jwt-issuer |
JWT_ISSUER |
Required JWT issuer | - |
--jwt-audience |
JWT_AUDIENCE |
Required JWT audience | - |
--api-keys |
API_KEYS |
API keys (key:name,key:name) | - |
--api-key-header |
API_KEY_HEADER |
API key header name | X-API-Key |
--basic-auth-users |
BASIC_AUTH_USERS |
Basic auth users (user:pass) | - |
--user-id-header |
USER_ID_HEADER |
Header for user ID | X-User-Id |
--auth-method-header |
AUTH_METHOD_HEADER |
Header for auth method | X-Auth-Method |
--fail-open |
FAIL_OPEN |
Allow on auth failure | false |
--verbose |
AUTH_VERBOSE |
Enable debug logging | false |
See Configuration Reference for OIDC, mTLS, Cedar authorization, and token exchange options.
# Configure with HS256 secret
sentinel-auth-agent --jwt-secret "your-32-char-minimum-secret-key"
# Configure with RS256 public key
sentinel-auth-agent --jwt-algorithm RS256 --jwt-public-key /path/to/public.pem
# With issuer and audience validation
sentinel-auth-agent \
--jwt-secret "secret" \
--jwt-issuer "https://auth.example.com" \
--jwt-audience "my-api"Client request:
curl -H "Authorization: Bearer eyJ..." http://localhost:8080/api# Configure API keys
sentinel-auth-agent --api-keys "sk_live_abc123:production,sk_test_xyz:development"Client request:
curl -H "X-API-Key: sk_live_abc123" http://localhost:8080/api# Configure users
sentinel-auth-agent --basic-auth-users "admin:secretpass,user:userpass"Client request:
curl -u "admin:secretpass" http://localhost:8080/apiConfigure OIDC with automatic JWKS key fetching and refresh:
config {
oidc {
enabled true
issuer "https://auth.example.com"
jwks-url "https://auth.example.com/.well-known/jwks.json"
audience "my-api"
required-scopes "read,write"
}
}Client request:
curl -H "Authorization: Bearer <oauth2-access-token>" http://localhost:8080/apiAuthenticate clients using X.509 certificates (requires Sentinel proxy to forward client cert):
config {
mtls {
enabled true
client-cert-header "X-Client-Cert"
allowed-dns "CN=service.example.com,O=Example"
extract-cn-as-user true
}
}The Sentinel proxy forwards the client certificate in a header after TLS termination.
After authentication, requests can be authorized using Cedar policies:
config {
authz {
enabled true
policy-file "/etc/sentinel/policies/auth.cedar"
default-decision "deny"
}
}Example Cedar policy:
permit(
principal,
action == Action::"GET",
resource
) when {
resource.path like "/api/public/*"
};
permit(
principal,
action,
resource
) when {
principal.roles.contains("admin")
};
See Authorization Guide for more details.
On successful authentication, the agent adds these headers to the request:
| Header | Description | Example |
|---|---|---|
X-User-Id |
Authenticated user ID | user123 |
X-Auth-Method |
Authentication method used | jwt, oidc, mtls, api_key, basic, saml |
X-Auth-Claim-* |
JWT/OIDC claims (for token auth) | X-Auth-Claim-role: admin |
X-Client-Cert-* |
Certificate info (for mTLS) | X-Client-Cert-CN: service.example.com |
agents {
agent "auth" {
type "custom"
transport "unix_socket" {
path "/var/run/sentinel/auth.sock"
}
events ["request_headers"]
timeout-ms 50
failure-mode "open"
}
}
routes {
route "api" {
matches { path-prefix "/api" }
upstream "backend"
agents ["auth"]
}
}# Environment variables
JWT_SECRET: "your-secret-key"
JWT_ISSUER: "https://auth.example.com"
API_KEYS: "key1:app1,key2:app2"
FAIL_OPEN: "false"| Code | Description |
|---|---|
| 401 | No valid credentials provided |
| (passthrough) | Credentials valid, request forwarded |
The agent adds WWW-Authenticate: Bearer realm="sentinel" header on 401 responses.
# Run with debug logging
RUST_LOG=debug cargo run -- \
--socket /tmp/test.sock \
--jwt-secret "test-secret-at-least-32-characters" \
--api-keys "test-key:test-app"
# Run tests
cargo test- Always use strong, random JWT secrets (minimum 32 characters for HS256)
- Store secrets in environment variables, not command line args
- Use RS256/ES256 with public keys for production when possible
- Enable
fail_opencautiously - only for non-critical paths - Consider rate limiting alongside authentication
Apache-2.0