Skip to main content

Token Verification

FunctionDescriptionMeta
io.jwt.decode

output := io.jwt.decode(jwt)

Decodes a JSON Web Token and outputs it as an object.

Arguments:
jwt (string)

JWT token to decode

Returns:
output (array<object[any: any], object[any: any], string>)

[header, payload, sig], where header and payload are objects; sig is the hexadecimal representation of the signature on the token.

SDK-dependent
io.jwt.decode_verify

output := io.jwt.decode_verify(jwt, constraints)

Verifies a JWT signature under parameterized constraints and decodes the claims if it is valid. Supports the following algorithms: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512, PS256, PS384 and PS512.

Arguments:
jwt (string)

JWT token whose signature is to be verified and whose claims are to be checked

constraints (object[string: any])

claim verification constraints

Returns:
output (array<boolean, object[any: any], object[any: any]>)

[valid, header, payload]: if the input token is verified and meets the requirements of constraints then valid is true; header and payload are objects containing the JOSE header and the JWT claim set; otherwise, valid is false, header and payload are {}

SDK-dependent
io.jwt.verify_es256

result := io.jwt.verify_es256(jwt, certificate)

Verifies if a ES256 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

SDK-dependent
io.jwt.verify_es384

result := io.jwt.verify_es384(jwt, certificate)

Verifies if a ES384 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
io.jwt.verify_es512

result := io.jwt.verify_es512(jwt, certificate)

Verifies if a ES512 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
io.jwt.verify_hs256

result := io.jwt.verify_hs256(jwt, secret)

Verifies if a HS256 (secret) JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

secret (string)

plain text secret used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

SDK-dependent
io.jwt.verify_hs384

result := io.jwt.verify_hs384(jwt, secret)

Verifies if a HS384 (secret) JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

secret (string)

plain text secret used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
io.jwt.verify_hs512

result := io.jwt.verify_hs512(jwt, secret)

Verifies if a HS512 (secret) JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

secret (string)

plain text secret used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
io.jwt.verify_ps256

result := io.jwt.verify_ps256(jwt, certificate)

Verifies if a PS256 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

SDK-dependent
io.jwt.verify_ps384

result := io.jwt.verify_ps384(jwt, certificate)

Verifies if a PS384 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
io.jwt.verify_ps512

result := io.jwt.verify_ps512(jwt, certificate)

Verifies if a PS512 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
io.jwt.verify_rs256

result := io.jwt.verify_rs256(jwt, certificate)

Verifies if a RS256 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

SDK-dependent
io.jwt.verify_rs384

result := io.jwt.verify_rs384(jwt, certificate)

Verifies if a RS384 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
io.jwt.verify_rs512

result := io.jwt.verify_rs512(jwt, certificate)

Verifies if a RS512 JWT signature is valid.

Arguments:
jwt (string)

JWT token whose signature is to be verified

certificate (string)

PEM encoded certificate, PEM encoded public key, or the JWK key (set) used to verify the signature

Returns:
result (boolean)

true if the signature is valid, false otherwise

v0.20.0 SDK-dependent
info

Note that the io.jwt.verify_XX built-in methods verify only the signature. They do not provide any validation for the JWT payload and any claims specified. The io.jwt.decode_verify built-in will verify the payload and all standard claims.

The input string is a JSON Web Token encoded with JWS Compact Serialization. JWE and JWS JSON Serialization are not supported. If nested signing was used, the header, payload and signature will represent the most deeply nested token.

For io.jwt.decode_verify, constraints is an object with the following members:

NameMeaningRequired
certA PEM encoded certificate, PEM encoded public key, or a JWK key (set) containing an RSA or ECDSA public key.See below
secretThe secret key for HS256, HS384 and HS512 verification.See below
algThe JWA algorithm name to use. If it is absent then any algorithm that is compatible with the key is accepted.Optional
issThe issuer string. If it is present the only tokens with this issuer are accepted. If it is absent then any issuer is accepted.Optional
timeThe time in nanoseconds to verify the token at. If this is present then the exp and nbf claims are compared against this value. If it is absent then they are compared against the current time.Optional
audThe audience that the verifier identifies with. If this is present then the aud claim is checked against it. If it is absent then the aud claim must be absent too.Optional

Exactly one of cert and secret must be present. If there are any unrecognized constraints then the token is considered invalid.

Token Verification Examples

The examples below use the following token:

package jwt

es256_token := "eyJ0eXAiOiAiSldUIiwgImFsZyI6ICJFUzI1NiJ9.eyJuYmYiOiAxNDQ0NDc4NDAwLCAiaXNzIjogInh4eCJ9.lArczfN-pIL8oUU-7PU83u-zfXougXBZj6drFeKFsPEoVhy9WAyiZlRshYqjTSXdaw8yw2L-ovt4zTUZb2PWMg"

Using JWKS

This example shows a two-step process to verify the token signature and then decode it for further checks of the payload content. This approach gives more flexibility in verifying only the claims that the policy needs to enforce.

package jwt

jwks := `{
"keys": [{
"kty":"EC",
"crv":"P-256",
"x":"z8J91ghFy5o6f2xZ4g8LsLH7u2wEpT2ntj8loahnlsE",
"y":"7bdeXLH61KrGWRdh7ilnbcGQACxykaPKfmBccTHIOUo"
}]
}`
JWKS Verify

This example shows a two-step process to verify the token signature and then decode it for further checks of the payload content. This approach gives more flexibility in verifying only the claims that the policy needs to enforce.

data.json
"{}"
input.json
"{}"
package jwt

result.verify := io.jwt.verify_es256(es256_token, jwks) # Verify the token with the JWKS
result.payload := io.jwt.decode(es256_token) # Decode the token
result.check := result.payload[1].iss == "xxx" # Ensure the issuer (`iss`) claim is the expected value
JWKS Single Verify

This next example shows doing the token signature verification, decoding, and content checks all in one call using io.jwt.decode_verify. Note that this gives less flexibility in validating the payload content as all claims defined in the JWT spec are verified with the provided constraints.

data.json
{}
input.json
{}
package jwt

result := [valid, header, payload] if {
[valid, header, payload] := io.jwt.decode_verify(es256_token, {
"cert": jwks,
"iss": "xxx",
})
}

Using PEM encoded X.509 Certificate

The following examples will demonstrate verifying tokens using an X.509 Certificate defined as:

package jwt

cert := `-----BEGIN CERTIFICATE-----
MIIBcDCCARagAwIBAgIJAMZmuGSIfvgzMAoGCCqGSM49BAMCMBMxETAPBgNVBAMM
CHdoYXRldmVyMB4XDTE4MDgxMDE0Mjg1NFoXDTE4MDkwOTE0Mjg1NFowEzERMA8G
A1UEAwwId2hhdGV2ZXIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATPwn3WCEXL
mjp/bFniDwuwsfu7bASlPae2PyWhqGeWwe23Xlyx+tSqxlkXYe4pZ23BkAAscpGj
yn5gXHExyDlKo1MwUTAdBgNVHQ4EFgQUElRjSoVgKjUqY5AXz2o74cLzzS8wHwYD
VR0jBBgwFoAUElRjSoVgKjUqY5AXz2o74cLzzS8wDwYDVR0TAQH/BAUwAwEB/zAK
BggqhkjOPQQDAgNIADBFAiEA4yQ/88ZrUX68c6kOe9G11u8NUaUzd8pLOtkKhniN
OHoCIHmNX37JOqTcTzGn2u9+c8NlnvZ0uDvsd1BmKPaUmjmm
-----END CERTIFICATE-----`
Certificate Verify

This example shows a two-step process to verify the token signature and then decode it for further checks of the payload content. This approach gives more flexibility in verifying only the claims that the policy needs to enforce.

data.json
"{}"
input.json
"{}"
package jwt

result.verify := io.jwt.verify_es256(es256_token, cert) # Verify the token with the certificate
result.payload := io.jwt.decode(es256_token) # Decode the token
result.check := result.payload[1].iss == "xxx" # Ensure the issuer (`iss`) claim is the expected value
Certificate Verify Single

This next example shows doing the same token signature verification, decoding, and content checks but instead with a single call to io.jwt.decode_verify. Note that this gives less flexibility in validating the payload content as all claims defined in the JWT spec are verified with the provided constraints.

data.json
"{}"
input.json
"{}"
package jwt

result := [valid, header, payload] if {
[valid, header, payload] := io.jwt.decode_verify(es256_token, {
"cert": cert,
"iss": "xxx",
})
}

Round Trip - Sign and Verify

These examples show how to encode a token, verify, and decode it with the different options available.

Sign and Verify Raw

This exambles demonstrates how to do this using the io.jwt.encode_sign_raw built-in:

data.json
"{}"
input.json
"{}"
package jwt

raw_result_hs256 := io.jwt.encode_sign_raw(
`{"alg":"HS256","typ":"JWT"}`,
`{}`,
`{"kty":"oct","k":"Zm9v"}` # "Zm9v" == base64url.encode_no_pad("foo")
)

# Important! - Use the un-encoded plain text secret to verify and decode
raw_result_valid_hs256 := io.jwt.verify_hs256(raw_result_hs256, "foo")
raw_result_parts_hs256 := io.jwt.decode_verify(raw_result_hs256, {"secret": "foo"})
Sign and Verify

This one demonstrates how to encode the and sign the same token contents as in the example above but with io.jwt.encode_sign instead of the raw variant.

data.json
"{}"
input.json
"{}"
package jwt

result_hs256 := io.jwt.encode_sign(
{
"alg":"HS256",
"typ":"JWT"
},
{},
{
"kty":"oct",
"k":"Zm9v"
}
)

# Important! - Use the un-encoded plain text secret to verify and decode
result_parts_hs256 := io.jwt.decode_verify(result_hs256, {"secret": "foo"})
result_valid_hs256 := io.jwt.verify_hs256(result_hs256, "foo")
info

Note that the resulting encoded token is different from the first example using io.jwt.encode_sign_raw. The reason is that the io.jwt.encode_sign function is using canonicalized formatting for the header and payload whereas io.jwt.encode_sign_raw does not change the whitespace of the strings passed in. The decoded and parsed JSON values are still the same.