JWT Decoder & Verifier
What the JWT decoder reads from a token, every rule it applies to the header, the signature and the claims, what each finding means for the application that receives the token, and how to fix and verify each one.
The tool page is tamperbox.dev/jwt. It opens on a synthetic token signed in your tab, answers in one sentence whether that token would be rejected and why, and shows the header, the claims and the rebuilt token under it. This page is the long version: what the page reads, every rule it applies, what each finding means for the application that receives the token, and how to fix and verify each one.
jku and x5u addresses in a header are never fetched and an embedded jwk is never used. Nothing is uploaded and nothing is stored.What the tool answers
Section titled “What the tool answers”Four questions, in the order a resource server asks them:
- Is this a well-formed JWS? Three unpadded Base64URL segments, a UTF-8 JSON header and payload, no duplicate keys, no number too large to show exactly.
- Does the signature verify with your key? Only once you supply a key, only for the algorithm you expect, and never for
alg: none. - Is it current?
expnot passed,nbfreached,iatnot in the future, each within the clock tolerance you allow. - Is it meant for you?
issequal to the issuer you expect andaudcontaining the audience you expect, when you enter them.
The verdict joins every failure into one “Rejected:” sentence. Otherwise it states how long the token stays current and whether the signature matched. The chips repeat each check in the order above.
Inputs
Section titled “Inputs”The token
Section titled “The token”The page takes a token typed, pasted anywhere on the page, dropped as a file or brought from the Unix Timestamp Converter. Before anything is read:
| Step | What happens |
|---|---|
| Trim | Surrounding whitespace is removed, then a leading Bearer (any case) |
| Size | More than 100,000 characters is refused: “This token is too large” |
| Shape | Five dot-separated parts is declined as an encrypted JWE; any count other than three gets “A JWT needs three parts: header.payload.signature” |
| Paste cleanup | A pasted Authorization: Bearer line or a quoted token is reduced to the token, and the hint says “Token kept from what you pasted”. Text that is not a token stays in the field with the decode error under it; Heal it offers a fix when it is almost a token (Remove Base64 padding, Convert to Base64URL, Remove line breaks and spaces, Keep the token only). The key is pasted into its own field |
A segment must contain only letters, digits, - and _, as RFC 4648 section 5 defines the URL-safe alphabet, with no = padding, as RFC 7515 section 2 requires for JWS. A segment whose final character carries non-zero unused bits is refused as “noncanonical Base64URL padding bits”; it usually means a hand-edited or truncated token.
The key or secret
Section titled “The key or secret”The key field is read only when it holds text, and only after the token decoded. What it accepts depends on the algorithm:
| Algorithm family | Accepted | Refused with |
|---|---|---|
| HS256, HS384, HS512 | The shared secret as UTF-8 text, whitespace included; with “Secret is Base64URL-encoded” ticked, unpadded Base64URL or padded standard Base64 | “The secret is not valid Base64URL” when + or / is mixed with - or _, “invalid Base64 padding” |
RS, PS, ES, Ed25519 (and EdDSA) |
A public JWK object, or a PEM block beginning -----BEGIN PUBLIC KEY----- (SPKI) |
“Use a public key, not a private key” for a JWK with d; a JWK whose alg differs from the selection or whose use is not sig; an Ed25519 JWK without kty: OKP and crv: Ed25519; a PKCS#1 BEGIN RSA PUBLIC KEY block or a certificate |
A key over 100,000 characters is refused. Verification needs a secure context (HTTPS or localhost) because Web Crypto is unavailable elsewhere; the page says so instead of guessing.
Expected algorithm, issuer, audience and tolerance
Section titled “Expected algorithm, issuer, audience and tolerance”“Expected algorithm” defaults to the token’s own alg. Choosing a different one stops verification with “The token algorithm does not match the algorithm you selected” rather than trying the key anyway. The expected issuer and audience are compared exactly, character for character. Clock tolerance takes 0 to 300 seconds and applies to exp, nbf and iat; outside that range the field is marked invalid, the claims are evaluated with zero tolerance, and the verdict adds “clock tolerance is invalid”.
Reading the result
Section titled “Reading the result”Verdict and chips
Section titled “Verdict and chips”The verdict sentence names the outcome: “Rejected: expired 2 hours ago, signature does not match.” or “Current for 59 minutes. Signature matches your key.” or, with no key, “Current for 59 minutes. Signature unchecked.” Each chip is one check: exp, nbf, iat, iss, aud, the signature and, when needed, the clock tolerance. A chip for a check you can act on is a button that focuses the field in question: the key for an unchecked or failed signature, the expected values for issuer and audience, the tolerance field when it is invalid.
Findings
Section titled “Findings”Under the verdict, every check is listed worst first with its detail: the UTC time of a time claim and its relative age, “Matches your expected value”, “Not checked. Enter the value your application expects.” Passes fold into one line once there are two or more.
Header and Payload
Section titled “Header and Payload”The two segments are shown as tables (Enter applies an edit, Escape restores it) or as JSON you can edit freely. A time claim’s value is followed by its UTC date. An edit that would change a claim’s JSON type is refused (“exp must be a number of seconds since 1970”), as is a number that cannot be kept exactly.
The rebuilt token is shown with its state: unchanged, re-signed, unsigned, or “signature broken”. An HMAC token is re-signed with the secret in the key field; the synthetic asymmetric examples are re-signed with the private key generated in this tab; a pasted RS, PS, ES or Ed25519 token keeps its old signature, which no longer matches the edited bytes, because the page never accepts a private key.
History
Section titled “History”Every Break it preset, every claim edit and every revert is logged with what it replaced. Revert undoes the newest change; Reset input restores the token you entered, which is also what happens when your edits bring every claim back to its original value.
Take it further
Section titled “Take it further”Each time claim the token carries, exp, nbf and iat, is offered as a link into the Unix Timestamp Converter. The value travels through same-site tab memory to a new tab; the token and the key stay on this page and nothing is put in a URL.
Method
Section titled “Method”The checks run in this order; a structural failure stops decoding, and the signature and claim checks then run independently of each other.
Structure and encoding
Section titled “Structure and encoding”| Rule | Finding wording | Source |
|---|---|---|
| Each segment is unpadded Base64URL | “Header is not valid unpadded Base64URL.” | RFC 7515 section 2, RFC 4648 section 5 |
| Unused bits in the last character are zero | “Header has noncanonical Base64URL padding bits.” | RFC 4648 section 3.5 |
| Header and payload are UTF-8 | “Payload contains invalid UTF-8.” | RFC 7515 section 7.1 |
| Both are JSON objects | “Payload must be a JSON object.” | RFC 7519 section 3 |
| No duplicate member names, at any depth | “Payload has a duplicate key: sub.” | RFC 7519 section 4 |
| Integers within 2^53 - 1 | “Payload has a number too large to display without losing precision.” | tool rule |
RFC 7519 section 4 says “The Claim Names within a JWT Claims Set MUST be unique; JWT parsers MUST either reject JWTs with duplicate Claim Names or use a JSON parser that returns only the lexically last duplicate member name”. The tool rejects, because implementations that keep the first and those that keep the last disagree about what the token says, and the duplicate check sees escaped spellings of the same name. The safe-integer rule is the tool’s own: JavaScript cannot show a larger integer exactly, so the page refuses rather than display a rounded claim.
Header and algorithm
Section titled “Header and algorithm”| Rule | Finding wording | Source |
|---|---|---|
alg is a non-empty string |
“The header must name a signing algorithm in alg.” | RFC 7515 section 4.1.1 |
alg: none has an empty signature |
“Unsigned tokens (alg: none) must have an empty signature.” | RFC 7518 section 3.6 |
| Any other algorithm has a signature | “The signature is missing.” | RFC 7515 section 5.2 |
crit or b64: false present |
verification stops: “Critical header extensions and unencoded payloads are not supported for verification.” | RFC 7515 section 4.1.11, RFC 7797 |
An alg: none token still decodes, so you can read it, but the verdict always lists “unsigned (alg: none)” among the rejection reasons and the chip reads “alg: none · unsigned”. RFC 8725 section 2.1 describes why: a verifier that accepts none because the token asked for it has no verifier at all. jku, x5u and jwk are shown as plain header members and never acted on, so a token cannot choose its own key, the attack that RFC 8725 section 2.1 and section 3.10 warn about.
Signature verification
Section titled “Signature verification”Verification runs only with a key in the field and only for the expected algorithm, which must equal the token’s alg. RFC 8725 section 3.1 is the rule: “Libraries MUST enable the caller to specify a supported set of algorithms and MUST NOT use any other algorithms when performing cryptographic operations”. The algorithm also decides which key shapes are accepted, which is the key-algorithm binding of RFC 8725 section 3.2: an HMAC secret is never tried against an RSA token and a public key is never used as an HMAC secret.
| Identifier | Web Crypto operation | Notes |
|---|---|---|
| HS256, HS384, HS512 | HMAC with SHA-256, SHA-384, SHA-512 | RFC 7518 section 3.2; a secret shorter than the hash output verifies but is flagged |
| RS256, RS384, RS512 | RSASSA-PKCS1-v1_5 | RFC 7518 section 3.3 |
| PS256, PS384, PS512 | RSA-PSS with salt lengths 32, 48 and 64 bytes | RFC 7518 section 3.5: the salt length equals the hash output |
| ES256, ES384, ES512 | ECDSA on P-256, P-384, P-521 | RFC 7518 section 3.4 |
Ed25519, EdDSA |
Ed25519 | RFC 8037 section 3.1; EdDSA accepted for the Ed25519 curve only |
The signed input is the ASCII of the first two segments joined by a dot, as RFC 7515 section 5.2 step 8 requires. The result is “Signature matches this key” or “Signature does not match this key”. A mismatch means the wrong key, a key rotated out of the issuer’s set (compare kid), the wrong secret encoding, or a token changed after signing. A match proves only that this key verifies these bytes; it says nothing about whether this key should be trusted.
Time claims
Section titled “Time claims”exp, nbf and iat must be NumericDates, “a JSON numeric value representing the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time” (RFC 7519 section 2). A quoted value, or a number a JavaScript date cannot hold, fails with “Expected a NumericDate”. With tolerance t seconds and the device clock now:
| Claim | Fails when | Chip |
|---|---|---|
exp |
now is at or past exp + t |
“exp · expired 2 hours ago”; inside the tolerance: “exp · within tolerance” |
nbf |
nbf is later than now + t |
“nbf · starts in 59 minutes” |
iat |
later than now + t, as a notice only |
“iat · in the future” |
exp absent |
never; a notice | “exp · never expires” |
RFC 7519 section 4.1.4: “the current date/time MUST be before the expiration date/time listed in the exp claim”; section 4.1.5: “the current date/time MUST be after or equal to the not-before date/time”. Both allow “some small leeway, usually no more than a few minutes, to account for clock skew”, which is the 300-second ceiling. Whether exp is required is the application’s decision, so its absence is a notice. Times come from your device clock and the verdict re-evaluates every ten seconds while the tab is visible. auth_time is shown as a date but not checked.
Issuer and audience
Section titled “Issuer and audience”iss must be a string; aud a string or an array of strings (RFC 7519 section 4.1.1 and section 4.1.3). Another type fails as “wrong type”. With an expected value entered, iss must equal it and the expected audience must equal aud or be one of its members: “If the principal processing the claim does not identify itself with a value in the aud claim when this claim is present, then the JWT MUST be rejected.” The comparison is exact, so a trailing slash or a different case is a mismatch, which is what RFC 7519 section 2 prescribes for StringOrURI values. An empty expectation reports “not checked”, never a pass; RFC 8725 section 3.8 is why the audience check matters: a token for one service replayed against another passes every other check.
Rebuilding edited tokens
Section titled “Rebuilding edited tokens”An edited header or payload is re-encoded and the token rebuilt. With a usable signing key the state is “signed”; otherwise the old signature is kept and the state is “stale”, because the bytes it covered have changed. Break signature replaces the first character of the signature with A (or B when it already is A), which keeps the segment canonical and guarantees a mismatch. A rebuilt alg: none token has an empty signature.
Standards and conformance
Section titled “Standards and conformance”RFC 7519: JSON Web Token
Section titled “RFC 7519: JSON Web Token”Implemented: section 2 (NumericDate, exact StringOrURI comparison), section 3 (the Claims Set is a JSON object), section 4 (unique claim names), sections 4.1.1 to 4.1.6 (iss, sub shown only, aud, exp, nbf, iat), section 7.2 steps 1 to 10 for a JWS. Not implemented: step 7 for nested JWTs (cty: JWT is shown, not unwrapped), section 5.3 replicating claims as header parameters, and any JWE path. Stricter than the text: duplicates are rejected, not resolved. The tool does not apply RFC 7519 section 4.1.7 jti replay detection; it has no store to check against.
RFC 7515 and RFC 7518: JWS and JWA
Section titled “RFC 7515 and RFC 7518: JWS and JWA”Implemented: compact serialisation (section 3.1 of RFC 7515), Base64URL without padding (section 2), the signing input of section 5.2, the alg parameter (section 4.1.1), refusal of crit (section 4.1.11) and of b64: false from RFC 7797 section 3. From RFC 7518 the algorithms in the table above and none (section 3.6). Not implemented: jku, x5u, x5c and x5t resolution (section 4.1.2 to 4.1.8), JSON serialisation, RS and PS keys supplied as PKCS#1, and ECDSA curves beyond the three named. Where it differs: RFC 7518 section 3.2 says an HMAC key “MUST be” at least the hash size; the tool verifies a shorter secret and flags it, so a test token still reads while the weakness is named.
RFC 7517 and RFC 8037: keys
Section titled “RFC 7517 and RFC 8037: keys”A JWK is accepted when it is a public key (RFC 7517 section 4 members; a private d from RFC 7518 section 6 is refused), its use is absent or sig (section 4.2) and its alg is absent or equal to the selection (section 4.4). Ed25519 keys follow RFC 8037 section 2 (kty: OKP, crv: Ed25519); the JOSE identifier EdDSA from section 3.1 is accepted and mapped to the browser’s Ed25519 operation. Ed448 is not supported. JWK Sets (keys arrays) are not read; paste the one key, chosen by kid.
RFC 8725: best current practices
Section titled “RFC 8725: best current practices”Followed: 2.1 and 3.1 (no none verification, caller-chosen algorithms), 3.2 (key and algorithm bound), 3.8 (audience checked when supplied), 3.10 (no key fetched from the token). Partly followed: 3.9 (the typ header is shown, not enforced) and 3.11 (exact issuer match when supplied). Not applicable: 3.5 to 3.7 (key management in the application).
What the tool does not check
Section titled “What the tool does not check”Revocation, replay (jti), nested tokens, encryption (RFC 7516 tokens are declined on sight), certificate chains behind x5c, and the application’s own rules about scopes, subjects and roles.
Finding reference
Section titled “Finding reference”Structure
Section titled “Structure”| Finding | Severity | Section | Meaning for the receiver | Fix |
|---|---|---|---|---|
| A JWT needs three parts | fail | RFC 7515 §3.1 | Not a JWS; nothing can be read | Copy the whole token; check for a cut at a line break |
| Encrypted token (JWE) | fail | RFC 7516 | Claims are encrypted; this tool cannot read them | Decrypt with the recipient’s key elsewhere |
| Not valid unpadded Base64URL | fail | RFC 7515 §2 | Standard Base64 or padding was used | Re-encode with the URL-safe alphabet, no = |
| Noncanonical padding bits | fail | RFC 4648 §3.5 | The segment was edited or truncated by hand | Regenerate the token |
| Invalid UTF-8, not valid JSON, must be a JSON object | fail | RFC 7519 §3 | The segment does not hold a claims object | Fix the producer’s serialisation |
| Duplicate key | fail | RFC 7519 §4 | Libraries disagree about which value wins | Emit each claim once |
| Number too large | fail | tool rule | The value cannot be shown exactly | Carry large identifiers as strings |
Header, algorithm and signature
Section titled “Header, algorithm and signature”| Finding | Severity | Section | Meaning for the receiver | Fix |
|---|---|---|---|---|
| alg: none · unsigned | fail | RFC 8725 §2.1 | Anyone can change the claims; the token proves nothing | Sign with a real algorithm; reject none at the verifier |
| The signature is missing | fail | RFC 7515 §5.2 | A signed algorithm with nothing to verify | Regenerate the token |
| signature · add a key | notice | RFC 7515 §5.2 | Nothing verified yet | Enter the secret or public key |
| signature · does not match | fail | RFC 7515 §5.2 | Wrong key, wrong encoding or altered token | Compare kid with the issuer’s current keys; check the secret’s encoding |
| signature · broken by your edits | fail | RFC 7515 §5.2 | The old signature no longer covers the bytes | Re-sign with the secret, or use as a negative test |
| signature · broken on purpose | fail | RFC 7515 §5.2 | A deliberate bad-signature fixture | None; every server should reject it |
| signature · could not check | fail | RFC 7518 §3 | Algorithm mismatch, key refused, crit, b64: false or no secure context |
Read the detail: it names the cause |
| Weak HMAC secret | notice | RFC 7518 §3.2 | Fine for tests, not for production | Use a secret at least as long as the hash output |
Time, issuer and audience
Section titled “Time, issuer and audience”| Finding | Severity | Section | Meaning for the receiver | Fix |
|---|---|---|---|---|
| exp · expired | fail | RFC 7519 §4.1.4 | A conforming server rejects it | Issue a new token; check the issuer’s clock and lifetime |
| exp · within tolerance | pass | RFC 7519 §4.1.4 | Accepted only thanks to your leeway | Treat as expiring; renew |
| exp · never expires | notice | RFC 7519 §4.1.4 | Valid until the key is rotated | Add exp unless the application forbids it |
| nbf · starts in | fail | RFC 7519 §4.1.5 | Not yet usable | Wait, or fix the issuer’s clock |
| iat · in the future | notice | RFC 7519 §4.1.6 | The issuer’s clock is ahead | Synchronise clocks |
| not a valid time | fail | RFC 7519 §2 | A string or out-of-range number where seconds were expected | Emit a JSON number of seconds |
| iss or aud · does not match | fail | RFC 7519 §4.1.1, §4.1.3 | Issued by, or for, someone else | Check the expected value for trailing slashes and case; reject the token otherwise |
| iss or aud · wrong type | fail | RFC 7519 §4.1.1, §4.1.3 | The claim is not a string (or array of strings) | Fix the issuer |
| iss or aud · not checked | notice | RFC 8725 §3.8 | You have not said who you are | Enter the expected value |
| clock tolerance · invalid | fail | RFC 7519 §4.1.4 | Settings error; claims judged with zero tolerance | Enter 0 to 300 |
The token is expired, or not valid yet
Section titled “The token is expired, or not valid yet”- Read the
expornbfchip: it names the UTC time and the distance from now. - Compare with the issuer’s clock. A few seconds off is clock skew; set a tolerance of up to 300 seconds and see whether the chip turns to “within tolerance”. More than that is a lifetime or a clock problem at the issuer.
- Obtain a fresh token and paste it. The verdict should read “Current for” the remaining lifetime.
exp decodes to a year far in the future
Section titled “exp decodes to a year far in the future”The claim was written in milliseconds. The table shows the date tens of thousands of years ahead and the chip says the token never meaningfully expires. Divide by 1000 at the issuer, or send the value to the Unix Timestamp Converter from Take it further and read it as milliseconds to confirm.
Wrong audience or issuer
Section titled “Wrong audience or issuer”Enter the exact values your application compares against. A mismatch chip opens the expected-values panel and focuses the field. If the token’s aud is an array, your value must be one of its members; a trailing slash on either side is a mismatch, not a near miss.
alg: none
Section titled “alg: none”The token decodes, the chip reads “alg: none · unsigned”, and the verdict rejects it. No key makes it pass. If a token from a real issuer arrives this way, the issuer is misconfigured; if your server accepted it, the verifier must be configured with an explicit algorithm allow-list.
The signature does not match
Section titled “The signature does not match”| Check | How |
|---|---|
| Algorithm | Expected algorithm equals the header’s alg; a different selection stops with a mismatch message |
| Key | kid in the header against the issuer’s current key set; a rotated key is the usual cause |
| Secret encoding | A Base64-exported secret needs “Secret is Base64URL-encoded”; a text secret must keep its exact whitespace |
| Token integrity | Any edit after signing changes the bytes; Reset input and verify the original |
A key is refused
Section titled “A key is refused”The detail names the cause: a private JWK (d present), a JWK with use other than sig or a conflicting alg, a PKCS#1 block instead of SPKI, a certificate, or no secure context. Export the public key as SPKI (openssl pkey -in private.pem -pubout) or as a public JWK.
Break it cases
Section titled “Break it cases”| Button | What it loads | What it shows |
|---|---|---|
| Expire it | exp one hour ago |
“Rejected: expired 1 hour ago” |
| Not yet valid | nbf one hour ahead, exp moved to two hours ahead if it was sooner |
“not valid for another 1 hour” |
| Wrong audience | aud set to someone-else |
“audience does not match” once an expected audience is entered |
| alg: none | header alg set to none |
“unsigned (alg: none)” |
| Break signature | the first signature character swapped | “signature altered” |
Every preset rebuilds the token: the HMAC example is re-signed with its secret, so the only failing check is the one the preset introduced. Revert in History undoes one preset; Reset input undoes them all.
An independent check
Section titled “An independent check”Verify an HS256 token outside Tamperbox with OpenSSL. With the token in $T and the secret in $S:
data=$(printf %s "$T" | cut -d. -f1-2)printf %s "$data" | openssl dgst -sha256 -hmac "$S" -binary | openssl base64 -A | tr '+/' '-_' | tr -d '='printf %s "$T" | cut -d. -f3The two printed lines are equal when the signature verifies. For an RS256 token, decode the signature segment to a file and run openssl dgst -sha256 -verify public.pem -signature sig.bin over the same first two segments.
Worked example
Section titled “Worked example”The page opens on a synthetic HS256 token created in your tab when the page loads: header alg: HS256, typ: JWT; payload sub: qa-example, name: Demo user, iss: https://issuer.example, aud: tamperbox-demo, role: tester, iat now and exp one hour ahead. It is signed with a demo secret the page shows you, and the secret is already in the key field, so the opening verdict reads “Current for 59 minutes. Signature matches your key.” with every chip green except iss and aud, which read “not checked” until you enter https://issuer.example and tamperbox-demo. The token is reserved sample data with a reserved issuer name; it is not a credential for anything and a new one is signed on every load, so its exact bytes are never the same twice. Choosing an asymmetric example generates a key pair in the tab, shows the public key as PEM, and keeps the private key non-extractable, which is why those examples can be re-signed while a pasted RS256 token cannot.
For agents
Section titled “For agents”The Tamperbox MCP server exposes two MCP tools: use search to inspect the catalog and schema, then use execute to call the selected operation through tamperbox.request. The JWT page maps to four POST /v1/tools/... operations:
| Operation | Required input | Result |
|---|---|---|
jwt_decode |
An application/jwt text artifact |
A JSON artifact containing the decoded header and payload; no verification |
jwt_verify |
token, key and an explicit algorithm |
Separate signature evidence, claim checks, header and payload |
jwt_rebuild |
JSON header and payload; optionally an HMAC secret or old signature |
A token whose state is unsigned, signed, stale or broken |
jwt_fixture |
Optional algorithm, header and payload |
A synthetic token, selected algorithm and verification key; private keys are not retained |
All responses also carry warnings and provenance. Keep these with any conclusion:
- A decoded token is readable, not trusted; a verified signature proves only that the supplied key verifies those bytes.
- Fixtures are not application credentials, and a rebuilt token passes for anyone who trusts the same key.
- None of the operations establishes application authorisation: scopes, roles and
jtireplay are the application’s rules.
See Connect an MCP client and Code mode for the calling pattern, and Security and privacy for where a token travels when an agent, rather than the browser page, decodes it.
Limits
Section titled “Limits”- Decoding proves readability, not origin; verification proves that one key verifies these bytes, not that the key is the right one to trust.
- No key is fetched from
jku,x5uor an embeddedjwk, and no key set is read; choose the key bykidyourself. - JWE, nested JWTs,
critextensions andb64: falsepayloads are declined or left unverified. - Private asymmetric keys are never accepted, so only HMAC tokens and the tab’s own examples can be re-signed.
- Times come from your device clock; a wrong local clock produces wrong expiry findings.
- Exact string comparison for issuer and audience; no normalisation of case or trailing slashes.
- Input is limited to 100,000 characters for the token and the key.
- Nothing is stored, and the token is not put in a URL; the Take it further link carries only the selected claim value.
References
Section titled “References”- RFC 7519, JSON Web Token (JWT). Proposed Standard, May 2015; updated by RFC 7797 and RFC 8725. Sections used: 2, 3, 4, 4.1.1, 4.1.3, 4.1.4, 4.1.5, 4.1.6, 4.1.7 (not applied) and 7.2.
- RFC 7515, JSON Web Signature (JWS). Proposed Standard, May 2015. Sections used: 2, 3.1, 4.1.1, 4.1.11, 5.2 and 7.1.
- RFC 7518, JSON Web Algorithms (JWA). Proposed Standard, May 2015; updated by RFC 9864. Sections used: 3.2, 3.3, 3.4, 3.5, 3.6 and 6.
- RFC 7517, JSON Web Key (JWK). Proposed Standard. Sections used: 4, 4.2 and 4.4.
- RFC 8037, CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JOSE. Proposed Standard, January 2017. Sections used: 2 and 3.1.
- RFC 8725, JSON Web Token Best Current Practices. Best Current Practice, February 2020; updates RFC 7519. Sections used: 2.1, 3.1, 3.2, 3.8 and 3.10.
- RFC 7797, JSON Web Signature (JWS) Unencoded Payload Option. Proposed Standard; updates RFC 7519. Section used: 3 (declined for verification).
- RFC 7516, JSON Web Encryption (JWE). Proposed Standard. Five-part tokens are declined; no section is applied.
- RFC 4648, The Base16, Base32, and Base64 Data Encodings. Proposed Standard. Sections used: 3.5 and 5.