Skip to main content

Overview

KrakenD provides built-in JWT validation to protect your endpoints. The Playground demonstrates two authentication approaches:
  1. Keycloak Integration - Validate tokens issued by an external Identity Provider
  2. Custom JWT Signer - Validate tokens signed by KrakenD itself

Keycloak-Based Authentication

The /private/moderate endpoint requires a valid JWT token from the built-in Keycloak instance with the moderator role.

Try It

# Without token - returns 401
curl http://localhost:8080/private/moderate

# With valid token
curl -H "Authorization: Bearer YOUR_TOKEN" \
  http://localhost:8080/private/moderate

Configuration

From config/krakend/krakend.json:
{
  "endpoint": "/private/moderate",
  "backend": [
    {
      "url_pattern": "/user/1.json"
    }
  ],
  "extra_config": {
    "auth/validator": {
      "alg": "RS256",
      "audience": ["playground"],
      "roles_key_is_nested": true,
      "roles_key": "realm_access.roles",
      "roles": ["moderator"],
      "jwk_url": "http://keycloak:8080/realms/krakend/protocol/openid-connect/certs",
      "disable_jwk_security": true
    }
  }
}

Key Parameters

Algorithm

"alg": "RS256"
Keycloak uses RSA signatures (RS256). The public key is fetched from the JWK endpoint.

Audience Validation

"audience": ["playground"]
The token must include playground in its aud claim.

Role-Based Access

"roles_key_is_nested": true,
"roles_key": "realm_access.roles",
"roles": ["moderator"]
The JWT must contain the moderator role. Since Keycloak stores roles in a nested structure (realm_access.roles), we set roles_key_is_nested to true. Example JWT payload:
{
  "aud": "playground",
  "realm_access": {
    "roles": ["moderator", "user"]
  }
}

JWK URL

"jwk_url": "http://keycloak:8080/realms/krakend/protocol/openid-connect/certs"
KrakenD fetches public keys from this endpoint to verify token signatures.
disable_jwk_security: true is only for development. In production, always use HTTPS for JWK URLs.

Custom JWT Signer

The /private/custom endpoint validates tokens signed by KrakenD using a symmetric key (HS256).

Try It

First, get a signed token from the /token endpoint:
curl http://localhost:8080/token
Then use it to access the protected endpoint:
curl -H "Authorization: Bearer YOUR_SIGNED_TOKEN" \
  http://localhost:8080/private/custom

Configuration

{
  "endpoint": "/private/custom",
  "backend": [
    {
      "url_pattern": "/user/1.json"
    }
  ],
  "extra_config": {
    "auth/validator": {
      "alg": "HS256",
      "audience": ["http://api.example.com"],
      "roles_key": "roles",
      "issuer": "https://krakend.io",
      "roles": ["role_a", "role_c"],
      "jwk_url": "http://fake_api/jwk/symmetric.json",
      "disable_jwk_security": true
    }
  }
}

Differences from Keycloak

  • Algorithm: HS256 (symmetric) instead of RS256 (asymmetric)
  • Roles Structure: Simple roles array, not nested
  • Multiple Roles: User must have either role_a OR role_c
  • Issuer: Validates the iss claim matches https://krakend.io

JWT Signing

The /token endpoint demonstrates how KrakenD can sign JWT tokens.

Configuration

{
  "endpoint": "/token",
  "backend": [
    {
      "url_pattern": "/token.json"
    }
  ],
  "extra_config": {
    "auth/signer": {
      "alg": "HS256",
      "kid": "sim2",
      "keys_to_sign": ["access_token", "refresh_token"],
      "jwk_local_path": "/opt/krakend/jwk-symmetric.json",
      "disable_jwk_security": true
    }
  }
}
The backend returns raw token data, and KrakenD signs specified fields (access_token, refresh_token) before returning them to the client.

Playground Users

The Keycloak instance includes two pre-configured users:
UsernamePasswordRoles
moderatormoderatormoderator
readerreaderreader
Access the Keycloak admin panel at http://localhost:8085 (credentials: admin/admin).

Testing Authentication

Using the Web Client

Visit http://localhost:3000 to use the included SPA that handles Keycloak authentication automatically.

Manual Token Generation

Get a token from Keycloak:
curl -X POST "http://localhost:8085/realms/krakend/protocol/openid-connect/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "username=moderator" \
  -d "password=moderator" \
  -d "grant_type=password" \
  -d "client_id=playground"

Learn More

Build docs developers (and LLMs) love