This is a http proxy filter which converts opaque authorization tokens to signed JWT's containing claims provided by an OAuth2 token introspection endpoint. RFC: OAuth 2.0 Token Introspection
Run make in the project root:
make build
The built wasm file should be located at target/wasm32-wasi/release/proxy_wasm_opaque_to_jwt.wasm
.
An example configuration of the filter.
introspect_endpoint:
authority: "id.example.com" # Hostname of the endpoint
path: "/oauth2/introspect" # Introspection endpoint path
upstream: "oauth2-authorization-serve" # Under e.g. Envoy Proxy the name of the cluster which provides the endpoint
jwt:
key: '' # Key to use for jwt signing. Generate new key with command "openssl genpkey -algorithm ed25519"
output_header_name: "X-JWT-User" # Header name to store the JWT in. This header is appended to the incoming request available for upstream services
algorithm: "EdDSA" # Algorithm to use for jwt signing
jsonnet_template: |- # Jsonnet function to use for transforming the introspection data to jwt claims
function(introspect_json) {
// If expiration is not set, set it to 0 to make it invalid
exp: if(std.objectHas(introspect_json, "exp")) then introspect_json.exp else 0,
iat: if(std.objectHas(introspect_json, "iat")) then introspect_json.iat,
nbf: if(std.objectHas(introspect_json, "nbf")) then introspect_json.nbf,
iss: if(std.objectHas(introspect_json, "iss")) then introspect_json.iss,
// If supplied aud is not an array convert it to one with 1 element.
aud: if(std.objectHas(introspect_json, "aud")) then (if(std.isArray(introspect_json.aud)) then introspect_json.aud else [introspect_json.aud]),
jti: if(std.objectHas(introspect_json, "jti")) then introspect_json.jti,
sub: if(std.objectHas(introspect_json, "sub")) then introspect_json.sub
}
A full example envoy v3 config can be found in examples/envoy-minimal.yml.
Algorithm | Supported |
---|---|
HMAC | |
HS256 |
✔️ |
HS384 |
✔️ |
HS512 |
✔️ |
RSA | |
RS256 |
✔️ |
RS384 |
✔️ |
RS512 |
✔️ |
PS256 |
✔️ |
PS384 |
✔️ |
PS512 |
✔️ |
ECDSA (support planned) | |
ES256 |
🚧 |
ES384 |
🚧 |
ES512 |
🚧 |
EdDSA | |
EdDSA |
✔️ |
These claims are included in the JWT by default if provided:
Claim | Supported |
---|---|
exp |
✔️ |
iat |
✔️ |
nbf |
✔️ |
iss |
✔️ |
aud (as array) |
✔️ |
jti |
✔️ |
sub |
✔️ |
With Jsonnet you are able to include custom claims or synthesize new ones or add static claims.
The default claims already use a jsonnet template to construct the JWT token. With help from jsonnet.org and the default template you should be able to change the generated JWT to your requirements.
This filter uses Top-Level Arguments. Basically the filter needs a function which generates the jwt claims. It is called with the introspection json as a parameter. In the function you can add all claims you want to add to your jwt token. An example can be found at src/default.jsonnet.
function(introspect_json) {
// ... put your claims inside here
}