Overview
KrakenD provides built-in JWT validation to protect your endpoints. The Playground demonstrates two authentication approaches:
- Keycloak Integration - Validate tokens issued by an external Identity Provider
- 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
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:
| Username | Password | Roles |
|---|
| moderator | moderator | moderator |
| reader | reader | reader |
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