JSON Web Token (JWT)

JSON Web Token (JWT) is an internet standard (RFC 7519) that defines a process for secure data exchange between two parties.
Infura projects use JSON Web Tokens for authorizing users and external parties.
Currently, Infura supports JWTs for Ethereum networks.

JWTs with Infura projects

Only authenticated users can access Infura projects by including JWTs in request headers.


  1. 1.
    Infura security settings enforce authorized access with JWTs.
  2. 2.
    A user logs into the project application and receives a JWT.
  3. 3.
    Each request the user makes to Infura with the application's Project ID includes the JWT in the header.
  4. 4.
    The JWT is verified and the request is successful.
  5. 5.
    The request is rejected if the JWT is invalid.
JWTs may also include allowlists that enforce further restrictions.

Set up your project to use JWTs

Generate keys

Infura supports the algorithms RS256 and ES256.
Ensure your private key stays private!
The following example creates key pairs with OpenSSL.
RSA key pair
EC (256) key pair
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pembas
openssl ecparam -name prime256v1 -genkey -noout -out private.pem
openssl ec -in private.pem -pubout -out public.pembash

Upload public key

  1. 1.
    Go to the SECURITY section in your project settings.
Security settings
You must implement separate security settings for each project.
2. Check the Require JWT for all requests box to enforce JWT on all requests. This is optional.
Use allowlists to specify a subset of requests that must use JWTs.
3. Give the public key a name.
4. Paste the public key into the JWT PUBLIC KEY input box. It looks something like this:
-----END PUBLIC KEY-----
5. Click ADD to add the key to the settings.
6. The key is added to security settings.
JWT set up
7. The key has a NAME, ID, FINGERPRINT. These are used for creating and verifying JWTs.
For key rotation, upload up to three keys for each project.

Send requests with JWTs

If JWTs are required for all requests, the following fails with an invalid JWT error.
curl -X POST \
-H "Content-Type: application/json" \
--data '{"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []}' \
To get the request to pass, generate a JWT, and add it to the request.

Generate a JWT

A JWT for use with Infura must:
  • Use a supported algorithm (RS256 or ES256) and declare it in the alg header field.
  • Specify JWT in the typ header field.
  • Include the project key ID in the kid header field.
  • Validate with the public key associated with the kid in the header.
  • Have an unexpired exp timestamp in the payload data.
To generate a timestamp for testing, use an online timestamp convertor tool.
  • Specify in the aud field.
To see how this works, go to a site like and enter the data.
Generate a JWT online
Copy the generated token as part of the -H "Authorization: Bearer entry:
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjQyZjUxODRlMzE1ZTQwZDRiNzkzMjU3Nzg2OTEwOTNhIn0.eyJleHAiOjE4OTM0NTI0MDAsImF1ZCI6ImluZnVyYS5pbyJ9.rIBKHmxDsSEiiqEcbWPWkN6F28R95a0beGdnVgVQnnD7ESOKGosr2t9iQ7QyGvNO8-74gaPy_DqVn4sy1FvnullrWQc8Tmf5PrrX2ULiGfSUATvr-JPOga-KAgS6ftcStoACNmcN7QI-n7Gv7NqZC3zWMGzK_1SvYcSodXzoWwtkWmrMW9uPiu4MvROQH0sK7MJ4WHBIHii-x4wogH4PHEdGi_vFZohq2bRaaDKXBeJK7Tkke2whcydTHGuiAPQvRiHu5_wVptgDbTbKIQ28ZFQ4LpYStXE9Bck4JoVDeRQezWJN8Dx9ThU7j1xhWQqxQFWw3SPHry-cIejAWEfDTQ" \
--data '{"jsonrpc": "2.0", "id": 1, "method": "eth_blockNumber", "params": []}' \

Set up allowlists

Allowlists restrict specific activity to users without JWTs. For example, in a system with proxy contracts, allowlists can restrict a user to sending requests to their own proxy only.
JWT allowlists override all other security settings for requests.
A JWT with allowlists must have all of the above settings, plus properly formatted allowlists.
Set allowlists with one or more of the following keys:
  • methods
  • addresses
  • origins
  • user_agents
The following example JWT definition allows only eth_getBalance requests, on a single specified address, coming from any HTTP origin, and any user agent.
"alg": "RS256",
"typ": "JWT",
"exp": 1893452400, // a long way off
"aud": "",
"methods": ["eth_getBalance"],
"addresses": ["0x1937c5c515057553ccbd46d5866455ce66290284"]
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IjQyZjUxODRlMzE1ZTQwZDRiNzkzMjU3Nzg2OTEwOTNhIn0.eyJleHAiOjE4OTM0NTI0MDAsImF1ZCI6ImluZnVyYS5pbyIsImFkZHJlc3NlcyI6WyIweDE5MzdjNWM1MTUwNTc1NTNjY2JkNDZkNTg2NjQ1NWNlNjYyOTAyODQiXSwibWV0aG9kcyI6WyJldGhfZ2V0QmFsYW5jZSJdfQ.SwonSCVgybdT_GPQXe5SfhujmyzG-qpgH6zzVEzLZbZpZKsVQzOzFu3X1zHydvITzl3WhKXq5q8acHdMEO8y2TpUeyeLB25A-bnSZj8YlxacQvsnSNzm4ySJrTglmjD9rsr6JzKfgub03RuHuz0AWWO4omD6UrPcfcpxUF9YXEcT98SIsodPP_41WPrRvBuo8kLhmByr2Qs-XQRCDzxHxHb5jXI5RzoxLeEjTU_3GfWqgqgh4XHogcK43_VFGz9gv8QEoUiPnySafV6H80WXo12XwTeF-lr2cy_q79ZOvSp0WC4_j8dQMhNwj2dhZv1VPsViZMeHjBAJwK5mzIxBlQ" \
--data '{"jsonrpc": "2.0", "id": 1, "method": "eth_getBalance", "params": [ "0x1937c5c515057553ccbd46d5866455ce66290284", "latest"]}' \

Verify JWTs

To identify the public key you have used to create a JWT, verify it with the FINGERPRINT.
Take the private key, output it in DER encoding; take the SHA256 of that, and base64 encode the result.
RSA key
EC (256) key
openssl rsa -in private.pem -pubout -outform DER | openssl sha256 -binary | openssl base64
openssl ec -in private.pem -pubout -outform DER | openssl sha256 -binary | openssl base64