About
This extension implements JSON Web Encryption (JWE) decryption in a Go extension for Envoy. JWE is a standard defined in RFC 7516 that provides encrypted content using JSON-based data structures, built on top of the JSON Web Algorithms (JWA) and JSON Web Key (JWK) specifications.
JWT inside JWE — For clients that encrypt a JWT (RFC 7519) into a JWE token before sending it to the server, this extension decrypts the JWE and recovers the original JWT so that Envoy's built-in JWT Authentication filter can read it, extract the token claims and use them for authorization.
Usage Examples
Quickstart
In this example, we will generate a JWE token containing a JWT token as the payload, and then use the JWE decryption extension in Envoy to decrypt the JWE token and recover the original JWT token.
In order to decrypt JWE tokens, you will need to provide the private key that matches the public key used for encryption. You can use online tools such as Authgear's JWK generator to generate the necessary keypair, then use Authgear's JWT & JWE Debugger to generate sample JWT tokens, and encrypt them into JWE tokens using the generated public key.
You can then run the JWE decryption extension in Envoy to decrypt the JWE token and recover the original JWT token.
# Run the extension reading the token from the `Authorization` header
boe run --extension jwe-decrypt --config '{
"private_key": { "file": "/path/to/private-key.pem" },
"input_header": "Authorization",
"prefix": "Bearer ",
"output_header": "Authorization"
}'
# Send a request with the JWE token and see that the upstream receives the decrypted JWT token in the `Authorization` header.
curl http://localhost:10000/headers -H 'Authorization: Bearer <JWE_TOKEN>'
{
"headers": {
"Accept": "*/*",
"Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiQm9FIFVzZXJzIl0sImlhdCI6MTc3MTI1NTU2NCwicHJpdmF0ZUNsYWltS2V5IjoiSGVsbG8sIFdvcmxkISIsInN1YiI6IlNhbXBsZUpXVCJ9.Gx8GzN4cQZDbgz9RbTyARbQX5LJ1FAggyYH2LGoxR5pXGGpO4m1bHmqQABRJaP-oCFwfXsX1aiA9WoN6Fxy5JdDNtAZpu7uR5u_PD2Cw24u_quRB-s_LeWYEwwftoDfnzEQfJeKappWbq9VCvk9Axg5sE-EnLPekhfo0gYhnn4TX-fg_v50AuvBSvXCR6WiIQn79TBIKPUe1UEFZz5kzgQXGWUR3SgczYqRGo0oqAMl7YLiviUUt--Jr0ozYkSA3j7_3ZqLEdyUqRxTe54gRSIym2HRiaSA75Fd12JJWF26YqzsoJ1anw1X037nRpetmV1_ANbOwcmUXTgIqL5NILA",
"Host": "localhost",
"User-Agent": "curl/8.13.0",
"X-Amzn-Trace-Id": "Root=1-69933906-43c5ac60421eeeb57f50a55e",
"X-Envoy-Expected-Rq-Timeout-Ms": "15000"
}
} Decrypt and forward a Bearer token
Process a request with the Authorization: Bearer <JWE compact token> header,
decrypt the JWE token, and emit the decrypted payload back into the Authorization
header with the Bearer prefix restored.
boe run --extension jwe-decrypt --config '{
"private_key": { "file": "/path/to/private-key.pem" },
"input_header": "Authorization",
"prefix": "Bearer ",
"output_header": "Authorization"
}' Using inline key
You can provide the PEM PKCS8 private key directly in the config using the inline field.
The value must be the base64-encoded PEM content.
You will also need to specify the header that contains the JWE token, and the header or metadata key where
the decrypted payload should be stored.
boe run --extension jwe-decrypt --config '{
"private_key": { "inline": "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t...base64-encoded-PEM..." },
"input_header": "X-JWE-Token",
"output_header": "X-Decrypted-JWE-Token"
}' Using key file
You can provide the path to a file containing the PEM PKCS8 private key using the file field.
You will also need to specify the header that contains the JWE token, and the header or metadata key where
the decrypted payload should be stored.
boe run --extension jwe-decrypt --config '{
"private_key": { "file": "/path/to/private-key.pem" },
"input_header": "X-JWE-Token",
"output_header": "X-Decrypted-JWE-Token"
}' Add decrypted payload to metadata
Set output_metadata in the config to store the decrypted payload in Envoy's dynamic metadata instead of a
header. Specify the key to store the value under. The namespace defaults to jwe-decrypt if omitted.
Downstream filters such as JWT authn, OPA, or ext_authz can then read the value from this metadata.
# Store the decrypted payload in the default "jwe-decrypt" namespace
boe run --extension jwe-decrypt --config '{
"private_key": { "file": "/path/to/private-key.pem" },
"input_header": "X-JWE-Token",
"output_metadata": { "key": "jwe_decrypted_payload" }
}'
# Store the decrypted payload in a custom namespace
boe run --extension jwe-decrypt --config '{
"private_key": { "file": "/path/to/private-key.pem" },
"input_header": "X-JWE-Token",
"output_metadata": { "namespace": "my-namespace", "key": "jwe_decrypted_payload" }
}'