This is a JWK Set client proxy, JCP for short. It is used to validate JWTs that were signed by a key that lives in a remote JWK Set. JCP caches the JWK Set in memory and automatically refreshes the JWK Set as configured.
This project serves a few primary use cases:
- The language or shell a program is written in does not have an adequate JWK Set client. Validate JWTs with
curl? Why not? - Restrictive networking policies prevent a program from accessing the remote JWK Set directly.
- Many co-located services need to validate JWTs that were signed by a key that lives in a remote JWK Set.
It is recommended that JCP is hosted in the same environment (data center) as the program verifying JWTs to reduce latency.
flowchart LR
subgraph Public Internet
J[Remote JWK Set]
end
subgraph Your Datacenter
Y[Your code]
JCP
end
Y-->JCP
JCP-->Y
JCP-->J
J-->JCP
This proxy server implements a Swagger 2.0 and OpenAPI 3 specification. Please see swagger.yml for the Swagger 2.0
specification and openapi.yml for the OpenAPI 3 specification.
These specification files can be used to generate client code for your favorite language. However, there is only one small endpoint for JWT validation so hand-coding a client is reasonable.
This project can be installed via a Docker or using the Go toolchain.
Pull the image:
docker pull micahparks/jcpSee docker-compose.yml for a working Docker Compose example.
Confirm you have Go installed. The minimum required version can be found in go.mod.
go install github.com/MicahParks/jcp/cmd/proxy@latestOr you can compile the by downloading this repository, making it your current working directory and running the below commands:
cd cmd/proxy/
go buildAfter these commands have been run, the proxy executable will be in the cmd/proxy/ directory.
Below is a table of JWT registered claims and the validation behavior of JCP.
| JWT Validation Type | Behavior |
|---|---|
| Cryptographic signature | automatic |
alg header |
automatic |
exp claim |
automatic |
iat claim |
automatic |
nbf claim |
automatic |
aud claim |
per request |
iss claim |
per request |
sub claim |
per request |
This project is configured via JSON. This program will check three places for this configuration JSON on startup in this order:
- The
CONFIG_JSONenvironment variable's raw contents. - The
CONFIG_PATHenvironment variable will be read. If non-empty, it will attempt to parse the file at that path. - The
config.jsonfile in the current working directory.
{
"jwks": {
"https://example.com/jwks.json": {
"refreshInterval": "1h",
"refreshTimeout": "10s"
}
},
"listenAddress": ":8080",
"logFormat": "json",
"requestMaxBytes": 1048576
}| JSON Attribute | Description | Example | Default Value | Required |
|---|---|---|---|---|
jwks |
An object mapping remote JWK Set URLs to their options. | see above | none | required |
refreshInterval |
The amount of time to wait before automatically refreshing the remote JWK Set resource. It uses Go syntax for time.ParseDuration. |
1h30m5s |
1h |
optional |
refreshTimeout |
The amount of time to wait failing a remote JWK Set refresh due to a timeout. It uses Go syntax for time.ParseDuration. |
5s |
10s |
optional |
listenAddress |
The address to listen on. It uses Go syntax for net.Listen. |
:3000 |
:8080 |
optional |
logFormat |
The format to log in. This determines which zap output logging is used. Valid values are human and json. |
human |
json |
optional |
requestMaxBytes |
The maximum number of bytes to read from the request body. | 10000 |
1048576 |
optional |
For most use cases, ensure all JWK Set URLs are HTTPS to prevent MITM attacks.
This project currently has greater than 90% test coverage:
$ go test -cover -race
PASS
coverage: 91.1% of statements
ok github.com/MicahParks/jcp 0.043s
Run these commands in the listed order in separate terminals.
Start a local JWK Set server:
go run cmd/local_jwkset/main.goStart the JCP server (debugger instructions not shown):
CONFIG_PATH=config.local.json go run cmd/proxy/main.goThis project was built on the following JSON Object Signing and Encryption (JOSE) related libraries: