JWT Middleware
The JWT Middleware validates JSON Web Tokens (JWT) in incoming requests to ensure only authenticated requests reach your upstream services. It provides flexible authentication methods and advanced claim validation capabilities.
Quick Start
middlewares:
- name: jwt-auth
type: jwtAuth
paths: ["/*"]
rule:
secret: "your-secret-key-here"
algo: "HS256"
Authentication Methods
The middleware supports four authentication methods. You must configure exactly one:
Shared Secret (HMAC)
Use a shared secret key for HMAC algorithms like HS256, HS384, or HS512.
rule:
secret: "MgsEUFgn9xiMym9Lo9rcRUa3wJbQBo..."
algo: "HS256"
Public Key (RSA/ECDSA)
Use a PEM-formatted public key for RSA or ECDSA algorithms.
rule:
publicKey: |
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----
algo: "RS256"
You can also provide:
- File path:
/path/to/public-key.pem
- Base64 encoded key:
LS0tLS1CRUdJTi...
JWKS URL
Dynamically fetch public keys from a JSON Web Key Set endpoint.
rule:
jwksUrl: "https://your-auth-provider.com/.well-known/jwks.json"
algo: "RS256"
JWKS File
Use a local JWKS file for key validation.
rule:
jwksFile: "/path/to/jwks.json"
# Or embed the content directly:
# jwksFile: '{"keys":[{"kty":"RSA",...}]}'
Configuration Reference
Core Settings
Option | Type | Required | Description |
---|---|---|---|
secret | string | * | Shared secret for HMAC algorithms |
publicKey | string | * | PEM public key (content, file path, or base64) |
jwksUrl | string | * | URL to fetch JWKS dynamically |
jwksFile | string | * | JWKS file path or content |
algo | string | No | Expected JWT algorithm (highly recommended) |
* One of these four options is required
Token Validation
Option | Type | Description | Example |
---|---|---|---|
issuer | string | Expected iss claim value | "https://auth.example.com" |
audience | string | Expected aud claim value | "api.example.com" |
claimsExpression | string | Boolean expression for custom claim validation | See Claims Validation |
Header Forwarding
Option | Type | Description |
---|---|---|
forwardHeaders | map | Forward JWT claims as HTTP headers to upstream services |
forwardAuthorization | boolean | Whether to forward the original Authorization header (default: true ) |
Claims Validation
Use claimsExpression
to implement complex validation logic with boolean expressions:
Available Functions
Function | Purpose | Syntax | Example |
---|---|---|---|
Equals | Exact match comparison | Equals(claim, value) | Equals('email_verified', true) |
Prefix | String starts with | Prefix(claim, prefix) | Prefix('email', 'admin@') |
Contains | Value exists in string/array | Contains(claim, value) | Contains('roles', 'admin') |
OneOf | Value matches any option | OneOf(claim, val1, val2, ...) | OneOf('plan', 'pro', 'enterprise') |
Logical Operators
!
— NOT (highest precedence)&&
— AND (medium precedence)||
— OR (lowest precedence)
Use parentheses ()
to control evaluation order.
Expression Examples
# Simple validation
claimsExpression: "Equals('active', true)"
# Multiple conditions
claimsExpression: "Equals('email_verified', true) && OneOf('role', 'admin', 'moderator')"
# Complex logic with grouping
claimsExpression: >
(Contains('organizations', 'acme') || Contains('organizations', 'globex')) &&
Equals('email_verified', true) &&
!Equals('suspended', true)
Header Forwarding
Forward JWT claims as HTTP headers to your upstream services:
forwardHeaders:
X-User-ID: sub # Standard claim
X-User-Email: email # Standard claim
X-User-Role: user.role # Nested claim (dot notation)
X-Department: profile.department # Deeply nested claim
X-Is-Admin: permissions.admin # Boolean claims become "true"/"false"
Complete Examples
Basic Authentication
middlewares:
- name: simple-jwt
type: jwtAuth
paths: ["/api/*"]
rule:
secret: "your-256-bit-secret"
algo: "HS256"
issuer: "https://your-auth-service.com"
Enterprise Setup with OIDC
middlewares:
- name: enterprise-jwt
type: jwtAuth
paths: ["/*"]
rule:
jwksUrl: "https://auth.company.com/.well-known/jwks.json"
issuer: "https://auth.company.com"
audience: "api.company.com"
algo: "RS256"
forwardAuthorization: false
claimsExpression: >
Equals('email_verified', true) &&
OneOf('department', 'engineering', 'product', 'security') &&
!Equals('account_disabled', true)
forwardHeaders:
X-User-ID: sub
X-User-Email: email
X-User-Name: name
X-User-Department: department
X-User-Roles: roles
Multi-Tenant SaaS
middlewares:
- name: tenant-jwt
type: jwtAuth
paths: ["/tenant/*/api/*"]
rule:
publicKey: "/etc/ssl/jwt-public.pem"
algo: "RS256"
claimsExpression: >
Equals('email_verified', true) &&
Contains('scopes', 'api:read') &&
OneOf('tenant_role', 'admin', 'user', 'viewer')
forwardHeaders:
X-Tenant-ID: tenant_id
X-User-Role: tenant_role
X-Permissions: scopes