Configure JSON Web Encryption (JWE)
By default, Auth0 issues access tokens that are formatted as a signed JSON Web Token (JWT), meaning that while they are integrity protected, clients and other intermediaries can still inspect them. This can lead to a loss of information privacy on data intended only to be exposed to a resource server.
To prevent unauthorized inspection of access tokens, Auth0 supports the use of nested JWT access tokens, where access information is signed in a JWT and then encrypted and represented with JSON Web Encryption (JWE). Resource servers are expected to both decrypt these access tokens and verify the signature of the JWT payload while the information is opaque to any other parties.
Generate RSA key pair
Before configuring an API to use JWE, you must generate an RSA key pair.
The private key must be kept secret. Upload the public key to Auth0 encoded in PEM format as described in Generate RSA Key Pair. Only the resource server or API server can securely access the private key to decrypt the access token.
Configure JWE for an API
Use the Auth0 Dashboard to configure JWE for your API. To begin, enable the JSON Web Encryption (JWE) toggle under Token Settings for your API.
When prompted, add a JSON Web Encryption (JWE) key:
Enter a friendly name for easy identification.
Upload a certificate with the public key encoded in PEM format.
Select the encryption algorithm.
(Optional) Enter a key identifier.
Click Add to save the JWE key, which will generate a thumbprint of the certificate.
Use the Auth0 Management API to configure JWE for a resource server or API server. You must configure JWE for each API, so each API has its own public encryption key.
The following POST request configures a new API to receive encrypted access tokens:
curl -X POST --location "https://{domain}/api/v2/resource-servers" \
-H "Authorization: Bearer {managementAccessToken}" \
-H "Content-Type: application/json" \
--data-raw '{
"name": "{apiName}",
"identifier": "{apiIdentifier}",
"token_encryption": {
"format": "compact-nested-jwe",
"encryption_key":
{
"name": "{credentialName}",
"pem": "{pem}",
"alg": "{alg}",
"kid": "{kid}"
}
}
}'
Was this helpful?
The following table explains what the different parameters mean:
Parameter | Required? | Description |
---|---|---|
apiName |
Required | The name of your new API. |
apiIdentifier |
Required | The unique identifier for your API. This will be used as your token audience. |
credentialName |
Optional | The name for your public key. |
pem |
Required | Public key encoded in PEM format. |
alg |
Required | The encryption algorithm must be either RSA-OAEP-256 , RSA-OAEP-384 , or RSA-OAEP-512 . |
kid |
Optional | The identifier used to write to the kid header in your JWE token. This can be used to identify the key used for encryption during key rotation. |
The response contains the id
property which uniquely identifies the resource server. The response also contains a generated thumbprint_sha256
field that can be used to identify the credential. Auth0 will not return key material after initial creation (in this case, your PEM).
There are many ways to generate the thumbprint_sha256
. For more information, see the RFC 8705 OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens.
To ensure that you generated the correct thumbprint_sha256
, you can use the following Node.js code sample to extract the thumbprint:
const fs = require('fs');
const crypto = require('crypto');
const { calculateJwkThumbprint, exportJWK } = require('jose');
const publicKeyObject = crypto.createPublicKey(fs.readFileSync('./my_cert.pem'));
exportJWK(publicKeyObject).then((jwk) => {
calculateJwkThumbprint(jwk, 'sha256').then((thumbprint) => {
console.log(thumbprint);
});
});
Was this helpful?