Document updated on Apr 29, 2024
Revoke Server for clusters
The Revoke Server (a.k.a Revoker) is a standalone server that coordinates token revocation in a KrakenD Cluster. When you start the service, it offers a ping endpoint for all KrakenD instances to self-register and pushes token revocation instructions to all nodes in the cluster.
The Revoker passes the instructions to all instances by connecting to their bloom filter RPC port. It offers centralized management despite the size of your cluster. You no longer need to know how many KrakenDs are running using the Revoke Server and interact with them individually.
The interaction with the Revoke Server is through a REST API (described below) that offers several endpoints to administer token expiration from a single place.
Remember that the Revoke Server does not issue tokens. Still, it can communicate to all running gateways, reporting when they need to start rejecting tokens (or types of tokens) that are still valid by looking at their expiration.
The diagram below shows how it works:
Starting the Revoke Server
To start the Revoke Server you only need to pass the configuration file as described in the sections below. For instance:
Starting the revoke server
$krakend revoker -c config.json
There are no other additional flags needed, as you can see in the help, as the interaction is through its service:
Starting the revoke server
$krakend revoker --help
╓▄█ ▄▄▌ ╓██████▄µ
▐███ ▄███╨▐███▄██H╗██████▄ ║██▌ ,▄███╨ ▄██████▄ ▓██▌█████▄ ███▀╙╙▀▀███╕
▐███▄███▀ ▐█████▀"╙▀▀"╙▀███ ║███▄███┘ ███▀""▀███ ████▀╙▀███H ███ ╙███
▐██████▌ ▐███⌐ ,▄████████M║██████▄ ║██████████M███▌ ███H ███ ,███
▐███╨▀███µ ▐███ ███▌ ,███M║███╙▀███ ███▄```▄▄` ███▌ ███H ███,,,╓▄███▀
▐███ ╙███▄▐███ ╙█████████M║██▌ ╙███▄`▀███████╨ ███▌ ███H █████████▀
`` `'`
Version: 2.6
Starts a revocation service.
Usage:
krakend revoker [flags]
Aliases:
revoker, revoke
Examples:
krakend revoker -c config.json
Flags:
-c, --config string Path to the revoker server configuration file. (default "./revoker.json")
-h, --help help for revoker
Revoke Server configuration
The configuration of the Revoke Server can use the same krakend.json
file your KrakenD instances use, or you can dedicate a separate file to it (probably a better option). In either case, the configuration file of the Revoker validates against the same KrakenD schema ("$schema": "https://www.krakend.io/schema/v2.6/krakend.json"
), and it’s a regular KrakenD configuration file in all aspects.
Whether you recycle your existing gateway configuration for the Revoke Server or not, these are the things you might have in mind:
The Revoke Server needs a listening port
as the gateway does. If you intend to run them on a single machine, you must override the port in the file with an environment var KRAKEND_PORT
during startup to avoid collisions using the same file.
The Revoke Server uses the auth/revoker
section. If you use two configuration files, both must be present and match strictly on both sides.
You can also use flexible configuration and the krakend check command for the Revoke Server.
auth/revoker
for both the gateway and the revoke server must be identical. Otherwise you might have scenarios where you are trying to revoke tokens of unsupported keys, desynchronization, or have communication problems.Revoke server configuration file
The configuration that the Revoke Server needs, whether it is a krakend.json
or dedicated revoke.json
file, is:
{
"version": 3,
"port": 8081,
"extra_config": {
"auth/revoker": {
"hash_name": "default",
"N": 10000000,
"P": 1e-7,
"port": 1234,
"token_keys": [
"jti", "sub"
],
"TTL": 1500,
"revoke_server_ping_url": "http://localhost:8081/instances",
"revoke_server_ping_interval": "30s",
"revoke_server_api_key": "639ee23f-f4c5-40c4-855c-912bf01fae87",
"revoke_server_max_workers":5
}
}
}
In this documentation, we will call:
- Server: The Revoke server communicates with all the KrakenDs to provide them with instructions.
- Client(s): The KrakenD gateways reporting to the Revoker.
The configuration is parsed both in the clients and in the server and has the following fields:
port
(integer): In the server, the port where the Revoker will expose its API (see endpoints below). In the client, it’s the KrakenD port. Notice there is also a port
entry inside the auth/revoker
configuration. The latter is for the RPC service to communicate with the bloom filter.
Then, inside the extra_config
’s auth/revoker
(the Bloom filter configuration):
Fields of Revoke Server
N
* integer- The maximum
N
umber of elements you want to keep in the bloom filter. Tens of millions work fine on machines with low resources.Example:10000000
P
* number- The
P
robability of returning a false positive. E.g.,1e-7
for one false positive every 10 million different tokens. The valuesN
andP
determine the size of the resulting bloom filter to fulfill your expectations. E.g: 0.0000001Examples:1e-7
,1e-7
TTL
* integer- The lifespan of the JWT you are generating in seconds. The value must match the expiration you are setting in the identity provider when creating the tokens.
hash_name
*- Either
optimal
(recommended) ordefault
. Theoptimal
consumes less CPU but has less entropy when generating the hash, although the loss is negligible.Possible values are:"optimal"
,"default"
port
* integer- The port number exposed on each KrakenD instance for the RPC service to interact with the bloomfilter. This port is allocated only to the clients (running KrakenDs).
revoke_server_api_key
string- A string used as an exchange API key to secure the communication between the Revoke Server and the KrakenD instances and to consume the REST API of the Revoker Server as well. E.g., a string generated with
uuidgen
.Example:"639ee23f-f4c5-40c4-855c-912bf01fae87"
revoke_server_max_retries
integer- Maximum number of retries after a connection fails. When the value is less than zero it is changed automatically to zero.Defaults to
0
revoke_server_max_workers
integer- How many workers are used concurrently to execute an action (e.g., push a token) to all registered instances, allowing you to limit the amount of memory consumed by the server. For example, if you have 100 KrakenD servers and need to push 5MB of data each, you need to send 500MB in total. A max_workers=5 will consume a maximum of
5MB x 5 workers = 25MB
of memory in a given instant. Defaults to the same number of CPUs available.Defaults to5
revoke_server_ping_interval
string- Time the server and the client wait to verify they are alive with each other (health check). Defaults to
30s
. Do not lower this value a lot; otherwise, you will have a lot of internal traffic.Specify units usingns
(nanoseconds),us
orµs
(microseconds),ms
(milliseconds),s
(seconds),m
(minutes), orh
(hours).Example:"30s"
revoke_server_ping_url
string- The address to the
/instances
endpoint in the Revoke Server.Example:"http://revoke-server:8081/instances"
token_keys
* array- The list with all the claims in your JWT payload that need watching. These fields establish the criteria to revoke accesses in the future. The Revoker does not use this value, only the clients.Example:
"jti"
Additional configuration
The Revoke Server also accepts settings from:
- Any HTTP server setting except
sequential_start
andcache_ttl
- Any HTTP transport setting except
disable_rest
- Any TLS setting
- Any improved logging setting
Revoke Server API Endpoints
The system is eventually consistent, meaning that after a maximum 2 x TTL
, the state converges and becomes consistent. Moreover, the operations are idempotent, so it’s safe to resend the same write methods multiple times.
Authorization: bearer
with the same API key you have set in the configuration (except for the /__health/
).POST /tokens/{token_key}/{value}
Adds a new token to revoke in the local bloom filter, and the server will spread it across all registered KrakenD instances.
Parameters:
{token_key}
: The name of the claim (e.g.,jti
,sub
,aud
, etc.){value}
: The claim value you want to revoke
/tokens/{token_key}/{value}
$curl -iH'Authorization: bearer 639ee23f-f4c5-40c4-855c-912bf01fae87' -XPOST http://localhost:8081/tokens/jti/43b7a832-8337-4b50-a3b3-f221800e42d5
HTTP/1.1 201 Created
Date: Thu, 06 Oct 2022 17:36:10 GMT
Content-Length: 0
The example above invalidates the token with jti=43b7a832-8337-4b50-a3b3-f221800e42d5
.
GET /tokens/{token_key}/{value}
The endpoint checks in all registered KrakenD instances the existence of the requested token and returns two keys: the hits
or instances recognizing the token as invalid or revoked, and the misses
: not present in the revoked set.
Parameters:
{token_key}
: The name of the claim (e.g.,jti
,sub
,aud
, etc.){value}
: The claim value you want to verify
The Revoke Server checks in its bloom filter and every KrakenD’s bloom filter the existence or not of the value. It identifies itself as revoker
in the hits
or misses
list.
/tokens/{token_key}/{value}
$curl -iH'Authorization: bearer 639ee23f-f4c5-40c4-855c-912bf01fae87' http://localhost:8081/tokens/jti/43b7a832-8337-4b50-a3b3-f221800e42d5
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 06 Oct 2022 17:15:39 GMT
Content-Length: 49
{"hits":["192.168.23.35:1234","revoker"],"misses":[]}
POST /tokens/{token_key}
Adds a list of tokens to the requested claim. Endpoint used for batch processing.
The body or file you send to the endpoint must contain one value per line.
Term
$curl -iH'Authorization: bearer 639ee23f-f4c5-40c4-855c-912bf01fae87' -XPOST --data-binary @invalid_tokens.txt http://localhost:8081/tokens/jti
HTTP/1.1 100 Continue
HTTP/1.1 201 Created
Date: Thu, 06 Oct 2022 17:39:07 GMT
Content-Length: 0
GET /instances
Returns the list of all KrakenD instances registered in the Revoke Server.
Term
$curl -iH'Authorization: bearer 639ee23f-f4c5-40c4-855c-912bf01fae87' http://localhost:8081/instances
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 06 Oct 2022 17:42:14 GMT
Content-Length: 32
{"instances":["127.0.0.1:1234"]}
POST /instances
Although the system automatically handles instances’ registration, this endpoint allows you to register a new instance manually.
The body of the request must have the following JSON fields:
{
"instance_id": "string. An UUID for your machine",
"cluster_id": "string. The MD5 hash or similar of your configuration",
"cn": "string. Your license CN as shown in 'openssl x509 -in LICENSE -text -noout'",
"n": "N value as in the configuration",
"p": "P value as in the configuration",
"ttl": "integer. TTL value as in the configuration",
"hash_name": "enum. hash_name value as in the configuration",
"ip": "string. the IP where to find this new KrakenD",
"port": "integer. the port where the bloom filter runs",
}
DELETE /instances/{instance}
Use the DELETE method to unregister a KrakenD instance from the Revoke Server. Keep in mind that if you unregister a KrakenD instance using this call, but it keeps running, the instance will rejoin the server on the next health check. The request does not need a body.
Parameters:
{instance}
: The instance to delete in the formatIP:port
, e.g.,192.168.1.1:8080
.
GET /status
Returns the status of the internal Revoker’s bloom filter and the selected settings.
Term
$curl -iH'Authorization: bearer 639ee23f-f4c5-40c4-855c-912bf01fae87' http://localhost:8081/status
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Mon, 24 Oct 2022 11:47:46 GMT
Content-Length: 166
{"config":{"Seed":"","N":10000000,"P":1e-7,"HashName":"optimal","TTL":1500,"Workers":5,"PingInterval":30000000000,"CN":"c2d1f2a3-8fc2-4278-b1c1-c002557b6b45","MaxRetries":3},"percentage_consumed":0}
GET /__health
The only endpoint that does not require authentication, returns a 200
status code when the server is running. You can disable this endpoint by setting it in its [router options](/docs/service-settings/router-options/# disable_health).
Docker compose example
The following docker-compose spins up several krakend instances connected to a revoke server:
version: "3"
services:
revoker:
image: krakend/krakend-ee:2
ports:
- 8081:8081
volumes:
- "./:/etc/krakend"
command: ["revoke", "-c", "revoker.json"]
krakend:
image: krakend/krakend-ee:2
ports:
- 8080:8080
volumes:
- "./:/etc/krakend"
krakend2:
image: krakend/krakend-ee:2
volumes:
- "./:/etc/krakend"
krakend3:
image: krakend/krakend-ee:2
volumes:
- "./:/etc/krakend"
krakend4:
image: krakend/krakend-ee:2
volumes:
- "./:/etc/krakend"
The associated configuration files are left below. Notice they are exact except for the port and the logging prefix:
krakend.json
{
"$schema": "https://www.krakend.io/schema/v2.6/krakend.json",
"version": 3,
"port": 8080,
"extra_config": {
"auth/revoker": {
"hash_name": "default",
"N": 10000000,
"P": 1e-7,
"port": 1234,
"token_keys": [
"jti", "sub"
],
"TTL": 1500,
"revoke_server_ping_url": "http://revoker:8081/instances",
"revoke_server_ping_interval": "30s",
"revoke_server_api_key": "639ee23f-f4c5-40c4-855c-912bf01fae87",
"revoke_server_max_workers":5
},
"telemetry/logging": {
"level": "DEBUG",
"prefix": "[KRAKEND]",
"stdout": true
}
}
}
revoker.json
{
"$schema": "https://www.krakend.io/schema/v2.6/krakend.json",
"version": 3,
"port": 8081,
"extra_config": {
"auth/revoker": {
"hash_name": "default",
"N": 10000000,
"P": 1e-7,
"port": 1234,
"token_keys": [
"jti", "sub"
],
"TTL": 1500,
"revoke_server_ping_url": "http://revoker:8081/instances",
"revoke_server_ping_interval": "30s",
"revoke_server_api_key": "639ee23f-f4c5-40c4-855c-912bf01fae87",
"revoke_server_max_workers":5
},
"telemetry/logging": {
"level": "DEBUG",
"prefix": "[REVOKER]",
"stdout": true
}
}
}