You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
JWTs issued by the Identity backend can be issued with a TTL that is longer than the signing key used to create them will be visible to clients on the identity/oidc/.well-known/keys endpoint, causing services to verifying those JWTs to reject the JWTs as invalid prior to exp claim included in the JWT.
Signing keys remain visible on the identity/oidc/.well-known/keys endpoint for the length of time configured by the identity keys' verification_ttl configuration.
An Identity backend token role can be configured to issue JWTs with any TTL value using the ttl configuration. This ttl determines how the exp claim in the JWT is populated.
When a service receives a request authenticated with a JWT from Vault and needs to verify it, it will validate the that the iss claim is a known/trusted value and then (periodically) retrieve the JSON Web Key Set from $issuer_url/.well-known/keys. The service will then validate that the kid claim in the JWT header matches a kid returned by the .well-known/keys endpoint for that issuer.
If a Vault OIDC Identity signing key is configured with a verification_ttl of 1 hour and an Identity token role is configured with a ttl value of 24h, a token created immediately prior to a key rotation will have a 24h ttl, but the key used to sign it will be removed from .well-known/keys after an hour, leaving up to 23 hours where the JWT is nominally valid but will fail authentication/validation by servers as they refresh the JWKS keyset for that issuer
To Reproduce
run a vault dev server: vault server -dev -dev-root-token-id=dev-root-token -log-level=debug
in another terminal pane or tab:
VAULT_ADDR=http://127.0.0.1:8200
VAULT_TOKEN=dev-root-token
# create identity role/keyset
vault write identity/oidc/key/a-key rotation_period=1m verification_ttl=1m allowed_client_ids="*"
vault write identity/oidc/role/a-role key=a-key ttl=60m
# configure and use identity based user -- root tokens can't get identity tokens
policy=identity
cat <<- EOF >> ${policy}
path "identity/oidc/*" {
capabilities = ["read"]
}
EOF
vault write $policy $policy
vault auth enable userpass
vault write auth/userpass/users/dave.matthews password=underthetableanddreaming token_policies=$policy
# switch to configured identity based user
unset VAULT_TOKEN
vault login -method=userpass username=dave.matthews password=underthetableanddreaming
# Retrieve an identity token, print key id of the signing key, as well as human readable form of `exp` claim
JWT=$(vault read identity/oidc/token/a-role -format=json | jq '.data.token' -r)
HEADERS=$(echo $JWT | awk 'BEGIN{FS="."}{print $1}' | base64 -d)
KID=$(echo $HEADERS | jq -r '.kid')
echo "JWT was signed with key $KID"
CLAIMS=$(echo $JWT | awk 'BEGIN{FS="."}{print $2}' | base64 -d)
EXPIRE=$(echo $CLAIMS | jq -r '.exp')
echo "Expires at $(date -d @$EXPIRE)" # this will be 1 hour in the future
# Print currently vended signing key Key IDs -- it will include the same value set to $KID above:
curl --silent $VAULT_ADDR/v1/identity/oidc/.well-known/keys | jq -r '.keys[].kid'
# sleep 10 minutes, or wait until anytime between now + 5 minutes and the expiration time printed above (`date -d @$EXPIRE`)
sleep 600
# Print currently vended signing key Key IDs -- $KID will no longer be present, and servers verifying this JWT will treat it as invalid, even though we have not reached the expected expiration time based on the `exp` claim returned by Vault
curl --silent $VAULT_ADDR/v1/identity/oidc/.well-known/keys | jq -r '.keys[].kid'
Expected behavior
Vault should either not allow identity token roles to have a TTL that is greater than the verification_ttl time of the signing key they use, or should dynamically truncate the identity token role TTL to never be greater than remaining time until rotation + verification_ttl at the time a token is issued.
This would avoid clients believing their token should be valid until exp being surprised by servers rejecting the JWT prior to the time encoded in the exp claim
Environment:
Vault Server Version (retrieve with vault status): v1.6.2
Vault CLI Version (retrieve with vault version): v1.6.2
Server Operating System/Architecture: OS X
Vault server configuration file(s):
None, works with vault server -dev and no config
Additional context
None
The text was updated successfully, but these errors were encountered:
@ianferguson Thanks for the report, and you're absolutely right. We do some checking between verification_ttl and rotation_ttl, but not between token_ttl and verification_ttl. Adding such a check is a good idea.
Describe the bug
JWTs issued by the Identity backend can be issued with a TTL that is longer than the signing key used to create them will be visible to clients on the
identity/oidc/.well-known/keys
endpoint, causing services to verifying those JWTs to reject the JWTs as invalid prior toexp
claim included in the JWT.Signing keys remain visible on the
identity/oidc/.well-known/keys
endpoint for the length of time configured by the identity keys'verification_ttl
configuration.An Identity backend token role can be configured to issue JWTs with any TTL value using the
ttl
configuration. Thisttl
determines how theexp
claim in the JWT is populated.When a service receives a request authenticated with a JWT from Vault and needs to verify it, it will validate the that the
iss
claim is a known/trusted value and then (periodically) retrieve the JSON Web Key Set from$issuer_url/.well-known/keys
. The service will then validate that thekid
claim in the JWT header matches akid
returned by the.well-known/keys
endpoint for that issuer.If a Vault OIDC Identity signing key is configured with a
verification_ttl
of 1 hour and an Identity token role is configured with attl
value of 24h, a token created immediately prior to a key rotation will have a 24h ttl, but the key used to sign it will be removed from.well-known/keys
after an hour, leaving up to 23 hours where the JWT is nominally valid but will fail authentication/validation by servers as they refresh the JWKS keyset for that issuerTo Reproduce
vault server -dev -dev-root-token-id=dev-root-token -log-level=debug
Expected behavior
Vault should either not allow identity token roles to have a TTL that is greater than the
verification_ttl
time of the signing key they use, or should dynamically truncate the identity token role TTL to never be greater thanremaining time until rotation + verification_ttl
at the time a token is issued.This would avoid clients believing their token should be valid until
exp
being surprised by servers rejecting the JWT prior to the time encoded in theexp
claimEnvironment:
vault status
): v1.6.2vault version
): v1.6.2Vault server configuration file(s):
None, works with
vault server -dev
and no configAdditional context
None
The text was updated successfully, but these errors were encountered: