Configure JWT authentication
Learn how to create a JWT access token, set up Vault to authenticate it, and use the token to access the REST API
You can use a JWT access token generated by an external identity provider to request a Vault IAM role that enables a call to the Vault REST API. The JWT can be defined to restrict access further than the role, and you can configure Vault to validate a token based on additional access restrictions.
In this guide, you create an access token that requests the use of a role and define the IAM configuration file settings to validate that token.
For security reasons, don't use your JWTs for other applications with Vault; issue JWTs dedicated to communication with Vault.
JWT authentication basics
When you call the REST API, you provide a JWT access token in the call's Authorization
header in the same manner as done for a Bearer token. When Vault receives the call, it validates the JWT access token to confirm that:
- It has not expired.
- The token's
iss
andaud
key values match those in anidps
table in the IAM configuration file. - The
roles
claim contains only one role, and that role is in the IAM configuration. - It's signed using the public key defined in the IAM configuration.
- It's claims are valid and match any settings in the IAM configuration file.
If the token is valid, Vault uses the roles
claim in the token to set the user's role.
Overview
The steps you take to create the JWT access token and set up Vault to validate it are:
- Create public and private keys to sign the token and prepare the keys for use in a JWT token.
- Create the JWT token using jwt.io. For production, you must use an identity provider such as Auth0, Azure AD, etc.
- Add an
idps
table to the IAM configuration file. - Call the REST API using your JWT token as the bearer token.
Step-by-step
In practice, you create the JWT token through your chosen identity provider and receive a JWKS endpoint link for the public key.
Create a signing key-pair
Generate a public and private key using these commands:
openssl genrsa -out pvault_jwt_private_key.pem 2048
openssl rsa -pubout -in pvault_jwt_private_key.pem -out pvault_jwt_public_key.pem
Now open the pvault_jwt_private_key.pem
and pvault_jwt_public_key.pem
file to obtain the keys, for example:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt3wbPZPZFAKln1dzrEd6
sg3FFG0/lqkvFgKaEQB8ZMPnFJm16CMY8C4zjO4TVktsY6klqzFL2mEldLiKJ1Ze
kiAy0eZgW8Icm6tRkMiYkSTRAcCqxNxKQOS6Yr8q6FMkAcnxWIoJyAwdXj9BWzet
CKBfW+vQ3z6CXs0e+ty5JMN7UqxwWPBBeEYxgNrZggR5tyKB3TFMXZFvBAbNM7vx
fEy7ObxL60IYMguTKNLJJyYx6AZsDXHt+iW72pmoUhhm/rCuFo4aKqJvGqoYkOST
Vigm8OfjD921fWp1v8Remq9hf9hS19VsP4yRL8ogFRnhoGy32FcOugnoo23jaXVG
5QIDAQAB
-----END PUBLIC KEY-----
Turn the public key into JWT format using JWK Creator with these settings:
- Public Key Use:
Signing
- Algorithm:
RS256
- Key ID:
abc
- PEM encoded key: the public key you generated.
Click Convert, and you're returned the key in JWI format, for example:
{
"kty": "RSA",
"n": "t3wbPZPZFAKln1dzrEd6sg3FFG0_lqkvFgKaEQB8ZMPnFJm16CMY8C4zjO4TVktsY6klqzFL2mEldLiKJ1ZekiAy0eZgW8Icm6tRkMiYkSTRAcCqxNxKQOS6Yr8q6FMkAcnxWIoJyAwdXj9BWzetCKBfW-vQ3z6CXs0e-ty5JMN7UqxwWPBBeEYxgNrZggR5tyKB3TFMXZFvBAbNM7vxfEy7ObxL60IYMguTKNLJJyYx6AZsDXHt-iW72pmoUhhm_rCuFo4aKqJvGqoYkOSTVigm8OfjD921fWp1v8Remq9hf9hS19VsP4yRL8ogFRnhoGy32FcOugnoo23jaXVG5Q",
"e": "AQAB",
"alg": "RS256",
"kid": "abc",
"use": "sig"
}
If you don't get the same key-value pairs, refresh the page and try again.
Vault supports using a JWKS endpoint to fetch a public key by setting "jwks_uri"
in the IAM configuration. Identity providers, such as Auth0, provide a URL to a JWKS endpoint that contains the public key in JWT format.
Update the IAM configuration file
First, define the content of the idps
table. This includes:
- The issuer (
iss
) is an identifier for the site used to create the token or the third-party provider that needs to match the information provided in the token. In this case, use the URL of the site you use to generate the token, i.e.,https://jwt.io/
. - The audience (
aud
) is an arbitrary value to match with the IAM file configuration: use a meaningful value. For this example, usevault1
. - The key (
key
) is the JSON you got from JWK Creator when you encoded the public key. - An identifier for the tables for this identity provider. This identifier can appear in Vault logs. In this case, use
app1
.
If the IdP uses a role claim name other than "roles"
set roles_claim
to identify the role claim.
This results in an idps
table like this:
[idps]
[idps.app1]
type = "direct-jwt"
[idps.app1.conf]
iss = "https://jwt.io/"
aud = "vault1"
keys = "{\"kty\":\"RSA\",\"n\":\"t3wbPZPZFAKln1dzrEd6sg3FFG0_lqkvFgKaEQB8ZMPnFJm16CMY8C4zjO4TVktsY6klqzFL2mEldLiKJ1ZekiAy0eZgW8Icm6tRkMiYkSTRAcCqxNxKQOS6Yr8q6FMkAcnxWIoJyAwdXj9BWzetCKBfW-vQ3z6CXs0e-ty5JMN7UqxwWPBBeEYxgNrZggR5tyKB3TFMXZFvBAbNM7vxfEy7ObxL60IYMguTKNLJJyYx6AZsDXHt-iW72pmoUhhm_rCuFo4aKqJvGqoYkOSTVigm8OfjD921fWp1v8Remq9hf9hS19VsP4yRL8ogFRnhoGy32FcOugnoo23jaXVG5Q\",\"e\":\"AQAB\",\"alg\":\"RS256\",\"kid\":\"abc\",\"use\":\"sig\"}"
Add this content to the IAM toml file following the instructions in Update the IAM configuration. Note that there may be a default empty [idps]
table in your toml file.
Generate a JWT access token
To generate the access token, use jwt.io.
First, create the header content. Here you set the:
- Algorithm (
"alg"
) used to encode the token to"RS256"
. - Type (
"typ"
) to"JWT"
. - Key ID (
"kid"
) to the one you set when converting your public key, i.e.,"abc"
.
Which results in this JSON that you add to the HEADER section:
{
"alg": "RS256",
"typ": "JWT",
"kid": "abc"
}
Next, create the payload where the:
- Issuer (
"iss"
) ishttps://jwt.io/
. - Audience (
"aud"
) isvault1
. - Subject (
"sub"
) is the user claiming the role. For this example, use the"VaultAdmin"
user, but you could use an email or any other helpful identifier. - Token's expiration date (
"exp"
) is a time in the future. - Claimed role (
"roles"
) must be present in the IAM configuration. For this example, use the "VaultAdmin" role.
Which results in this JSON that you add to the PAYLOAD section:
{
"iss": "https://jwt.io/",
"aud": "vault1",
"sub": "VaultAdmin",
"exp": 1893412799,
"roles": ["VaultAdminRole"]
}
Finally, add the public and private keys you generated earlier to the VERIFY SIGNATURE section.
Now, generate the encoded token. You get a result similar to this:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFiYyJ9.eyJpc3MiOiJodHRwczovL2p3dC5pby8iLCJhdWQiOiJ2YXVsdDEiLCJzdWIiOiJWYXVsdEFkbWluIiwiZXhwIjoxODkzNDEyNzk5LCJyb2xlcyI6WyJWYXVsdEFkbWluUm9sZSJdfQ.CXTyS-j9rVyJw0VOkysQDUmRiF4GW1jNqPBxD2cRhcG9RwJRFnMx_U0l6h9C--dESGHhf8yeOIgkB_24FpuyyWzc8rPpewa2DzfPJS-iqQD9JjKIParSpp79p6ZfFLwRdHEvME8Xbdj_YVP2IchrEhuk3LwgFIfS1Scq7z9aEsB3h_fARI81hPugzODYkl77vo3D0hb0W9SmZprKuVtCY8NA2-qDK6HWZNXSjVkWJgzLttlzjwfU6WhKCR0cYHgmiE9Mt_tBeHF_m03Y8BqhF2yDQKpOo6ptohUZLYynarhBlApGrOkbs9zQdwKmQwaVlQxRQhnEjcxsIu7HwkYmxg
Test the JWT access token
Use the JWT access token to authenticate to Vault. For example, to get the version of Vault, you use pvault --authtoken <jwt> version
, which would look something like this:
pvault --authtoken eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFiYyJ9.eyJpc3MiOiJodHRwczovL2p3dC5pby8iLCJhdWQiOiJ2YXVsdDEiLCJzdWIiOiJWYXVsdEFkbWluIiwiZXhwIjoxODkzNDEyNzk5LCJyb2xlcyI6WyJWYXVsdEFkbWluUm9sZSJdfQ.CXTyS-j9rVyJw0VOkysQDUmRiF4GW1jNqPBxD2cRhcG9RwJRFnMx_U0l6h9C--dESGHhf8yeOIgkB_24FpuyyWzc8rPpewa2DzfPJS-iqQD9JjKIParSpp79p6ZfFLwRdHEvME8Xbdj_YVP2IchrEhuk3LwgFIfS1Scq7z9aEsB3h_fARI81hPugzODYkl77vo3D0hb0W9SmZprKuVtCY8NA2-qDK6HWZNXSjVkWJgzLttlzjwfU6WhKCR0cYHgmiE9Mt_tBeHF_m03Y8BqhF2yDQKpOo6ptohUZLYynarhBlApGrOkbs9zQdwKmQwaVlQxRQhnEjcxsIu7HwkYmxg version
You get a response like this:
+--------------------+-----------------------------+----------------------+-------------------+
| vault_id | vault_version | cli_version | db_schema_version |
+--------------------+-----------------------------+----------------------+-------------------+
| 384662711408558080 | 1.14.0.12018547267-g52945f2 | v1.14.0-0-g52945f25a | 20241125194329 |
+--------------------+-----------------------------+----------------------+-------------------+
What next
- See IAM configuration examples for JWT authentication
- See JWT configuration in the IAM file for more information on the JWT settings in the IAM configuration file.