Skip to main content

a6-plugin-jwt-auth

Overview

The jwt-auth plugin authenticates requests using JSON Web Tokens. Consumers register a key and secret (or public key for asymmetric algorithms). Clients include a signed JWT in the request header, query parameter, or cookie. APISIX validates the signature and claims, then forwards the request with consumer identity headers.

When to Use

  • Token-based stateless authentication
  • Asymmetric key verification (RS256, ES256, EdDSA) where APISIX only needs the public key
  • Custom claims-based consumer identification
  • Integration with external token issuers (your own auth server, Auth0, etc.)

Consumer Credential Reference

FieldTypeRequiredDefaultDescription
keystringYesUnique identifier in JWT payload to match consumer
secretstringConditionalShared secret for HMAC algorithms (HS256/HS384/HS512). Encrypted in etcd.
public_keystringConditionalPEM public key for RSA/ECDSA/EdDSA algorithms
algorithmstringNo"HS256"Signing algorithm (see supported list below)
expintegerNo86400Token lifetime in seconds (not UNIX timestamp)
base64_secretbooleanNofalseSet true if secret is base64-encoded
lifetime_grace_periodintegerNo0Clock skew tolerance in seconds
key_claim_namestringNo"key"JWT claim containing the consumer key

Supported Algorithms

FamilyAlgorithms
HMACHS256, HS384, HS512
RSARS256, RS384, RS512
RSA-PSSPS256, PS384, PS512
ECDSAES256, ES384, ES512
EdDSAEdDSA

Route/Service Configuration Reference

FieldTypeRequiredDefaultDescription
headerstringNo"authorization"Header to extract JWT from
querystringNo"jwt"Query parameter to extract JWT from
cookiestringNo"jwt"Cookie to extract JWT from
hide_credentialsbooleanNofalseRemove JWT before forwarding upstream
key_claim_namestringNo"key"JWT claim containing consumer key (must match credential config)
anonymous_consumerstringNoConsumer for unauthenticated requests
claims_to_verifyarrayNo["exp","nbf"]Claims to verify (exp, nbf)

Token Lookup Priority

  1. Header (default: authorization) — supports Bearer <token> prefix
  2. Query parameter (default: jwt)
  3. Cookie (default: jwt)

Step-by-Step: Enable jwt-auth with HS256

1. Create a consumer

a6 consumer create -f - <<'EOF'
{
"username": "alice"
}
EOF

2. Add jwt-auth credential

curl "$(a6 context current -o json | jq -r .server)/apisix/admin/consumers/alice/credentials" \
-X PUT \
-H "X-API-KEY: $(a6 context current -o json | jq -r .api_key)" \
-d '{
"id": "cred-alice-jwt",
"plugins": {
"jwt-auth": {
"key": "alice-key",
"secret": "alice-secret-minimum-32-chars-long",
"algorithm": "HS256",
"exp": 86400
}
}
}'

3. Create a route with jwt-auth

a6 route create -f - <<'EOF'
{
"id": "jwt-protected",
"uri": "/api/*",
"plugins": {
"jwt-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF

4. Generate a JWT and test

Create a JWT with payload {"key": "alice-key", "exp": <future_timestamp>} signed with alice-secret-minimum-32-chars-long using HS256.

curl -i http://127.0.0.1:9080/api/test \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..."

Step-by-Step: Enable jwt-auth with RS256

1. Generate RSA key pair

openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem

2. Create credential with public key

curl "$(a6 context current -o json | jq -r .server)/apisix/admin/consumers/bob/credentials" \
-X PUT \
-H "X-API-KEY: $(a6 context current -o json | jq -r .api_key)" \
-d '{
"id": "cred-bob-jwt",
"plugins": {
"jwt-auth": {
"key": "bob-key",
"algorithm": "RS256",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjAN...\n-----END PUBLIC KEY-----"
}
}
}'

Sign tokens with private.pem externally. APISIX only needs the public key.

Common Patterns

Custom claim name (use iss instead of key)

# Credential config:
{
"jwt-auth": {
"key": "my-issuer-id",
"secret": "my-secret",
"key_claim_name": "iss"
}
}

# Route config:
{
"jwt-auth": {
"key_claim_name": "iss"
}
}

# JWT payload:
{
"iss": "my-issuer-id",
"exp": 1879318541
}

Clock skew tolerance

{
"jwt-auth": {
"key": "consumer-key",
"secret": "my-secret",
"lifetime_grace_period": 30
}
}

Allows 30 seconds clock drift between token issuer and APISIX.

Token in query parameter

{
"plugins": {
"jwt-auth": {
"query": "token"
}
}
}

Client sends: curl "http://127.0.0.1:9080/api/test?token=eyJ..."

Secret management with environment variables

{
"jwt-auth": {
"key": "consumer-key",
"secret": "$env://JWT_SECRET"
}
}

Secret management with HashiCorp Vault

{
"jwt-auth": {
"key": "consumer-key",
"secret": "$secret://vault/jwt/consumer-name/jwt-secret"
}
}

Headers Added to Upstream

HeaderValue
X-Consumer-UsernameConsumer's username
X-Credential-IdentifierCredential ID
X-Consumer-Custom-IdConsumer's labels.custom_id (if set)

Error Responses

HTTP CodeMessageCause
401"Missing JWT token in request"No token in header/query/cookie
401"JWT token invalid"Malformed token
401"failed to verify jwt"Bad signature, expired, or invalid claims
401"Invalid user key in JWT token"Consumer key not found

Troubleshooting

SymptomCauseFix
401 "failed to verify jwt"Token expiredGenerate new token with future exp
401 "failed to verify jwt"Algorithm mismatchEnsure credential algorithm matches token
401 "Invalid user key"Wrong claim nameSet key_claim_name on both credential and route
Public key rejectedMissing newlines in PEMInclude \n after header/before footer lines
Clock skew errorsTime driftSet lifetime_grace_period on credential

Config Sync Example

version: "1"
consumers:
- username: alice
routes:
- id: jwt-protected
uri: /api/*
plugins:
jwt-auth: {}
upstream_id: my-upstream
upstreams:
- id: my-upstream
type: roundrobin
nodes:
"backend:8080": 1

Note: Consumer credentials (including JWT keys/secrets) must be created separately via the Admin API; a6 config sync manages the consumer resource but credentials are sub-resources.


This page is generated from a6-plugin-jwt-auth/SKILL.md in the api7/a6 repository. Browse all skills on the AI Agent Skills page.

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation