RFC 7519

JSON Web Token (JWT)

๐Ÿ“… published May 2015, from ietf

RFC 7519: JSON Web Token (JWT) โœจ

Okay bestie, let's do the title block first ๐Ÿ’… This is RFC 7519, called JSON Web Token (JWT). The Internet Engineering Task Force (IETF) published it in May 2015 ๐ŸŒธ The authors are M. Jones at Microsoft, J. Bradley at Ping Identity, and N. Sakimura at NRI ๐Ÿซถ It's a Standards Track document, so it's a real Internet standard, not just a suggestion. The ISSN is 2070-1721. The header doesn't have any "Obsoletes" or "Updates" line, so this RFC isn't replacing or amending anything ๐Ÿฆ‹

Abstract

Okay so the TL;DR is that a JSON Web Token (JWT) is a compact, URL-safe way to represent claims that get passed between two parties ๐ŸŽ€ The claims are stored as a JSON object, and that object becomes the payload of a JSON Web Signature (JWS) structure or the plaintext of a JSON Web Encryption (JWE) structure. That means the claims can be digitally signed, protected with a Message Authentication Code (MAC), and/or encrypted โœจ It's giving security, bestie ๐Ÿ”

Status of This Memo

This is an Internet Standards Track document. โญ

It's a product of the Internet Engineering Task Force (IETF), and it represents the consensus of the IETF community ๐Ÿ’œ It went through public review and got approved for publication by the Internet Engineering Steering Group (IESG). If you want more info on Internet Standards, check out Section 2 of RFC 5741 ๐Ÿ“š

For the current status of this document, any errata, and how to give feedback, go to http://www.rfc-editor.org/info/rfc7519 ๐Ÿ”—

Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved. ๐ŸŒˆ

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info), as they stood on the date this document was published. Please read these carefully, because they spell out your rights and restrictions for this document ๐Ÿง Code Components pulled out of this document must include the Simplified BSD License text, as described in Section 4.e of the Trust Legal Provisions. They're also provided without warranty, as described in the Simplified BSD License ๐Ÿ’€

Table of Contents

1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   4
  1.1.  Notational Conventions  . . . . . . . . . . . . . . . . .   4
2.  Terminology . . . . . . . . . . . . . . . . . . . . . . . . .   4
3.  JSON Web Token (JWT) Overview . . . . . . . . . . . . . . . .   6
  3.1.  Example JWT . . . . . . . . . . . . . . . . . . . . . . .   7
4.  JWT Claims  . . . . . . . . . . . . . . . . . . . . . . . . .   8
  4.1.  Registered Claim Names  . . . . . . . . . . . . . . . . .   9
    4.1.1.  "iss" (Issuer) Claim  . . . . . . . . . . . . . . . .   9
    4.1.2.  "sub" (Subject) Claim . . . . . . . . . . . . . . . .   9
    4.1.3.  "aud" (Audience) Claim  . . . . . . . . . . . . . . .   9
    4.1.4.  "exp" (Expiration Time) Claim . . . . . . . . . . . .   9
    4.1.5.  "nbf" (Not Before) Claim  . . . . . . . . . . . . . .  10
    4.1.6.  "iat" (Issued At) Claim . . . . . . . . . . . . . . .  10
    4.1.7.  "jti" (JWT ID) Claim  . . . . . . . . . . . . . . . .  10
  4.2.  Public Claim Names  . . . . . . . . . . . . . . . . . . .  10
  4.3.  Private Claim Names . . . . . . . . . . . . . . . . . . .  10
5.  JOSE Header . . . . . . . . . . . . . . . . . . . . . . . . .  11
  5.1.  "typ" (Type) Header Parameter . . . . . . . . . . . . . .  11
  5.2.  "cty" (Content Type) Header Parameter . . . . . . . . . .  11
  5.3.  Replicating Claims as Header Parameters . . . . . . . . .  12
6.  Unsecured JWTs  . . . . . . . . . . . . . . . . . . . . . . .  12
  6.1.  Example Unsecured JWT . . . . . . . . . . . . . . . . . .  12
7.  Creating and Validating JWTs  . . . . . . . . . . . . . . . .  13
  7.1.  Creating a JWT  . . . . . . . . . . . . . . . . . . . . .  13
  7.2.  Validating a JWT  . . . . . . . . . . . . . . . . . . . .  14
  7.3.  String Comparison Rules . . . . . . . . . . . . . . . . .  15
8.  Implementation Requirements . . . . . . . . . . . . . . . . .  16
9.  URI for Declaring that Content is a JWT . . . . . . . . . . .  17
10. IANA Considerations . . . . . . . . . . . . . . . . . . . . .  17
  10.1.  JSON Web Token Claims Registry . . . . . . . . . . . . .  17
    10.1.1.  Registration Template  . . . . . . . . . . . . . . .  18
    10.1.2.  Initial Registry Contents  . . . . . . . . . . . . .  18
  10.2.  Sub-Namespace Registration of
         urn:ietf:params:oauth:token-type:jwt . . . . . . . . . .  19
    10.2.1.  Registry Contents  . . . . . . . . . . . . . . . . .  19
  10.3.  Media Type Registration  . . . . . . . . . . . . . . . .  20
    10.3.1.  Registry Contents  . . . . . . . . . . . . . . . . .  20
  10.4.  Header Parameter Names Registration  . . . . . . . . . .  20
    10.4.1.  Registry Contents  . . . . . . . . . . . . . . . . .  21
11. Security Considerations . . . . . . . . . . . . . . . . . . .  21
  11.1.  Trust Decisions  . . . . . . . . . . . . . . . . . . . .  21
  11.2.  Signing and Encryption Order . . . . . . . . . . . . . .  21
12. Privacy Considerations  . . . . . . . . . . . . . . . . . . .  22
13. References  . . . . . . . . . . . . . . . . . . . . . . . . .  22
  13.1.  Normative References . . . . . . . . . . . . . . . . . .  22
  13.2.  Informative References . . . . . . . . . . . . . . . . .  23

Appendix A.  JWT Examples . . . . . . . . . . . . . . . . . . . .  26
  A.1.  Example Encrypted JWT . . . . . . . . . . . . . . . . . .  26
  A.2.  Example Nested JWT  . . . . . . . . . . . . . . . . . . .  26
Appendix B.  Relationship of JWTs to SAML Assertions  . . . . . .  28
Appendix C.  Relationship of JWTs to Simple Web Tokens (SWTs) . .  28
Acknowledgements  . . . . . . . . . . . . . . . . . . . . . . . .  28
Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  29

1. Introduction โœจ

Okay, so a JSON Web Token (JWT) is a compact claims format made for space-constrained spots like HTTP Authorization headers and URI query parameters ๐Ÿงš JWTs encode their claims as a JSON [RFC7159] object. That object is either the payload of a JSON Web Signature (JWS) [JWS] structure or the plaintext of a JSON Web Encryption (JWE) [JWE] structure. So the claims can be digitally signed or integrity protected with a Message Authentication Code (MAC), and/or encrypted ๐Ÿ”ฅ JWTs are always represented using the JWS Compact Serialization or the JWE Compact Serialization, no exceptions ๐Ÿ’…

The suggested pronunciation of JWT is the same as the English word "jot" ๐Ÿ“ Say it with me, "jot" ๐Ÿซถ

1.1. Notational Conventions

Here's the key word situation ๐ŸŽ€ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in "Key words for use in RFCs to Indicate Requirement Levels" [RFC2119]. The interpretation only applies when the terms show up in all capital letters, so lowercase words are just regular words ๐Ÿ™ˆ

2. Terminology ๐Ÿ“š

Some terms are borrowed from other specs. The terms "JSON Web Signature (JWS)", "Base64url Encoding", "Header Parameter", "JOSE Header", "JWS Compact Serialization", "JWS Payload", "JWS Signature", and "Unsecured JWS" are defined by the JWS specification [JWS] ๐Ÿ’–

The terms "JSON Web Encryption (JWE)", "Content Encryption Key (CEK)", "JWE Compact Serialization", "JWE Encrypted Key", and "JWE Initialization Vector" are defined by the JWE specification [JWE] ๐Ÿฆ‹

The terms "Ciphertext", "Digital Signature", "Message Authentication Code (MAC)", and "Plaintext" are defined by the "Internet Security Glossary, Version 2" [RFC4949] ๐Ÿ”

These terms are defined by this specification:

JSON Web Token (JWT): A string that represents a set of claims as a JSON object. It's encoded in a JWS or JWE, so the claims can be digitally signed or MACed and/or encrypted ๐Ÿ’œ

JWT Claims Set: A JSON object that contains the claims carried by the JWT ๐ŸŒธ

Claim: A piece of information asserted about a subject. A claim is a name/value pair made of a Claim Name and a Claim Value โœจ

Claim Name: The name part of a claim. A Claim Name is always a string ๐ŸŽ€

Claim Value: The value part of a claim. A Claim Value can be any JSON value ๐ŸŒˆ

Nested JWT: A JWT where nested signing and/or encryption is used. In a Nested JWT, a JWT is the payload or plaintext value of an enclosing JWS or JWE structure, respectively. It's JWTs all the way down ๐Ÿช†

Unsecured JWT: A JWT whose claims are not integrity protected or encrypted ๐Ÿ™ˆ

Collision-Resistant Name: A name in a namespace that lets names get allocated so they're very unlikely to collide with other names. Examples of collision-resistant namespaces include Domain Names, Object Identifiers (OIDs) as defined in the ITU-T X.660 and X.670 Recommendation series, and Universally Unique IDentifiers (UUIDs) [RFC4122]. When you use an administratively delegated namespace, the person defining a name needs to take reasonable precautions to make sure they control the part of the namespace they're using to define it. Be responsible, bestie ๐Ÿซถ

StringOrURI: A JSON string value with an extra rule. Arbitrary string values MAY be used, but any value containing a ":" character MUST be a URI [RFC3986]. StringOrURI values are compared as case-sensitive strings, with no transformations or canonicalizations applied ๐Ÿ’…

NumericDate: A JSON numeric value that represents the number of seconds from 1970-01-01T00:00:00Z UTC until the specified UTC date/time, ignoring leap seconds. This is equivalent to the "Seconds Since the Epoch" definition in IEEE Std 1003.1, 2013 Edition [POSIX.1], where each day is accounted for by exactly 86400 seconds. The one difference is that non-integer values can be represented. For date/times in general and UTC in particular, see RFC 3339 [RFC3339] โฐ

Okay so that's the foundation, the vocab is locked in ๐Ÿ”’ Still more to come, so stay tuned ๐Ÿ‘€๐Ÿ’œ

3. JSON Web Token (JWT) Overview ๐Ÿงš

okay so JWTs are basically a bunch of claims packed into a JSON object, and that object gets encoded inside a JWS and/or JWE structure ๐ŸŽ€ this JSON object is the JWT Claims Set. Per [RFC7159], Section 4, it's zero or more name/value pairs (members), where the names are strings and the values can be any JSON values. those members are the claims the JWT carries ๐Ÿ’… This JSON object MAY contain whitespace and/or line breaks before or after any JSON values or structural characters, following Section 2 of [RFC7159]. so yes, extra spacing is allowed, bestie ๐Ÿซถ

the member names in the JWT Claims Set are called Claim Names, and the values are called Claim Values โœจ

the JOSE Header describes the crypto stuff that gets applied to the JWT Claims Set ๐Ÿ” if the JOSE Header is for a JWS, the JWT is a JWS, and the claims are digitally signed or MACed, with the JWT Claims Set as the JWS Payload ๐Ÿ–‹๏ธ if the JOSE Header is for a JWE, the JWT is a JWE, and the claims are encrypted, with the JWT Claims Set as the plaintext that the JWE encrypts ๐Ÿ”’ a JWT can even be wrapped in another JWE or JWS to make a Nested JWT, so you can stack signing and encryption together. so iconic ๐Ÿ‘‘

a JWT is a sequence of URL-safe parts separated by period ('.') characters ๐Ÿฆ‹ each part holds a base64url-encoded value. how many parts there are depends on whether the result is a JWS in the JWS Compact Serialization or a JWE in the JWE Compact Serialization ๐Ÿ’–

3.1. Example JWT

the example JOSE Header below says the encoded object is a JWT, and the JWT is a JWS that's MACed with the HMAC SHA-256 algorithm ๐ŸŒธ

{"typ":"JWT",
 "alg":"HS256"}

to clear up any confusion about how that JSON object is represented, here's the exact octet sequence of its UTF-8 form in this example. (ngl, the formatting can get messy because of platform differences: CRLF vs LF line breaks, spaces at the start and end of lines, whether the last line ends with a line break, and other stuff ๐Ÿ™ˆ in this example, the first line has no leading or trailing spaces, a CRLF line break (13, 10) sits between the first and second lines, the second line has one leading space (32) and no trailing spaces, and the last line has no terminating line break.) the octets for the UTF-8 form of the JOSE Header here, in JSON array notation, are:

[123, 34, 116, 121, 112, 34, 58, 34, 74, 87, 84, 34, 44, 13, 10, 32,
34, 97, 108, 103, 34, 58, 34, 72, 83, 50, 53, 54, 34, 125]

base64url-encoding those octets gives this encoded JOSE Header value:

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9

here's an example JWT Claims Set ๐Ÿ“

{"iss":"joe",
 "exp":1300819380,
 "http://example.com/is_root":true}

the following octet sequence is the UTF-8 form of that JWT Claims Set, and it's the JWS Payload โœจ

[123, 34, 105, 115, 115, 34, 58, 34, 106, 111, 101, 34, 44, 13, 10,
32, 34, 101, 120, 112, 34, 58, 49, 51, 48, 48, 56, 49, 57, 51, 56,
48, 44, 13, 10, 32, 34, 104, 116, 116, 112, 58, 47, 47, 101, 120, 97,
109, 112, 108, 101, 46, 99, 111, 109, 47, 105, 115, 95, 114, 111,
111, 116, 34, 58, 116, 114, 117, 101, 125]

base64url-encoding the JWS Payload gives this encoded JWS Payload (line breaks are only there for display ๐Ÿ’…)

eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly
9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ

computing the MAC of the encoded JOSE Header and encoded JWS Payload with the HMAC SHA-256 algorithm, then base64url-encoding the HMAC value the way [JWS] specifies, gives this encoded JWS Signature ๐Ÿ”ฅ

dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

now concatenate these encoded parts in this order, with period ('.') characters between them, and you get the complete JWT (line breaks are just for display again ๐ŸŽ€)

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9
.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt
cGxlLmNvbS9pc19yb290Ijp0cnVlfQ
.
dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

[JWS] goes through this computation in more detail in Appendix A.1 of [JWS]. there's also an example of an encrypted JWT in Appendix A.1 of this spec ๐Ÿฆ‹


4. JWT Claims ๐Ÿ’œ

the JWT Claims Set is a JSON object whose members are the claims the JWT carries. the Claim Names in 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, as described in Section 15.12 ("The JSON Object") of ECMAScript 5.1 [ECMAScript]. no duplicates, periodt ๐Ÿ’…

which claims a JWT has to contain to be considered valid depends on the context, and that's outside the scope of this spec ๐ŸŒˆ specific applications will need their implementations to understand and handle some claims in particular ways. but if there's no such requirement, all claims that implementations don't understand MUST be ignored โœจ

there are three classes of JWT Claim Names: Registered Claim Names, Public Claim Names, and Private Claim Names ๐Ÿงš

4.1. Registered Claim Names

the following Claim Names are registered in the IANA "JSON Web Token Claims" registry set up by Section 10.1. none of the claims below are meant to be mandatory in all cases. they're more of a starting point for a set of useful, interoperable claims ๐Ÿซถ applications using JWTs should define which specific claims they use, and when those claims are required or optional. all the names are short on purpose, because a core goal of JWTs is for the representation to be compact ๐Ÿฃ

4.1.1. "iss" (Issuer) Claim

the "iss" (issuer) claim identifies the principal that issued the JWT ๐Ÿท๏ธ how this claim gets processed is generally application specific. the "iss" value is a case-sensitive string containing a StringOrURI value. Use of this claim is OPTIONAL.

4.1.2. "sub" (Subject) Claim

the "sub" (subject) claim identifies the principal that is the subject of the JWT ๐ŸŽฏ the claims in a JWT are normally statements about the subject. the subject value MUST either be scoped to be locally unique in the context of the issuer, or be globally unique. processing this claim is generally application specific. the "sub" value is a case-sensitive string containing a StringOrURI value. Use of this claim is OPTIONAL.

4.1.3. "aud" (Audience) Claim

the "aud" (audience) claim identifies the recipients the JWT is intended for ๐Ÿ‘ฏ each principal that's meant to process the JWT MUST identify itself with a value in the audience claim. if the principal processing the JWT doesn't identify itself with a value in the "aud" claim when this claim is present, then the JWT MUST be rejected ๐Ÿšซ in the general case, the "aud" value is an array of case-sensitive strings, each containing a StringOrURI value. in the special case where the JWT has one audience, the "aud" value MAY be a single case-sensitive string containing a StringOrURI value. how audience values get interpreted is generally application specific. Use of this claim is OPTIONAL.

4.1.4. "exp" (Expiration Time) Claim

the "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing โฐ to process the "exp" claim, the current date/time MUST be before the expiration date/time listed in it.

Implementers MAY allow some small leeway, usually no more than a few minutes, to account for clock skew ๐Ÿ•ฐ๏ธ its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL.

4.1.5. "nbf" (Not Before) Claim

the "nbf" (not before) claim identifies the time before which the JWT MUST NOT be accepted for processing ๐ŸŒ… to process the "nbf" claim, the current date/time MUST be after or equal to the not-before date/time listed in it. Implementers MAY allow some small leeway, usually no more than a few minutes, to account for clock skew. its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL.

4.1.6. "iat" (Issued At) Claim

the "iat" (issued at) claim identifies the time at which the JWT was issued ๐Ÿผ this claim can be used to figure out how old the JWT is. its value MUST be a number containing a NumericDate value. Use of this claim is OPTIONAL.

4.1.7. "jti" (JWT ID) Claim

the "jti" (JWT ID) claim gives the JWT a unique identifier ๐Ÿชช the identifier value MUST be assigned in a way that makes it extremely unlikely (negligible probability) that the same value gets accidentally given to a different data object. if the application uses multiple issuers, collisions MUST be prevented among values produced by different issuers as well ๐Ÿ™… the "jti" claim can be used to stop the JWT from being replayed ๐Ÿ” the "jti" value is a case-sensitive string. Use of this claim is OPTIONAL.

4.2. Public Claim Names

anyone using JWTs can define Claim Names at will ๐ŸŽจ but to avoid collisions, any new Claim Name should either be registered in the IANA "JSON Web Token Claims" registry set up by Section 10.1, or be a Public Name: a value that contains a Collision-Resistant Name. either way, the person defining the name or value needs to take reasonable precautions to make sure they're in control of the part of the namespace they use to define the Claim Name ๐Ÿง 

4.3. Private Claim Names

a producer and consumer of a JWT MAY agree to use Claim Names that are Private Names: names that aren't Registered Claim Names (Section 4.1) or Public Claim Names (Section 4.2) ๐Ÿคซ unlike Public Claim Names, Private Claim Names are subject to collision, so they should be used with caution ๐Ÿ™ˆ


5. JOSE Header ๐ŸŽ€

for a JWT object, the members of the JSON object represented by the JOSE Header describe the crypto operations applied to the JWT, and optionally some extra properties of the JWT ๐Ÿ” depending on whether the JWT is a JWS or a JWE, the matching rules for the JOSE Header values apply.

this spec also defines the following Header Parameters for both cases, where the JWT is a JWS and where it's a JWE ๐Ÿ’–

5.1. "typ" (Type) Header Parameter

the "typ" (type) Header Parameter, defined by [JWS] and [JWE], is used by JWT applications to declare the media type [IANA.MediaTypes] of this complete JWT ๐Ÿ“‚ it's meant for when non-JWT values could also show up in an application data structure that can hold a JWT object, so the application can use this value to tell the different kinds of objects apart ๐Ÿ•ต๏ธโ€โ™€๏ธ it usually won't be used when the app already knows the object is a JWT. this parameter is ignored by JWT implementations, and any processing of it is done by the JWT application ๐Ÿคทโ€โ™€๏ธ if it's present, it is RECOMMENDED that its value be "JWT" to show that the object is a JWT. media type names aren't case sensitive, but it is RECOMMENDED that "JWT" always be spelled in uppercase characters for compatibility with legacy implementations ๐Ÿ“ฃ Use of this Header Parameter is OPTIONAL. ๐Ÿฆ‹

5.2. "cty" (Content Type) Header Parameter ๐ŸŽ€

okay so the "cty" (content type) Header Parameter is defined by [JWS] and [JWE], and this spec borrows it to share structural info about the JWT ๐Ÿ’…

in the normal case where nested signing or encryption isn't happening, using this header is NOT RECOMMENDED ๐Ÿ™ƒ but if you DO nest, this header MUST be present, and its value MUST be "JWT" to say "hey, a Nested JWT is hiding in here" โœจ media type names aren't case sensitive, but it's RECOMMENDED to spell "JWT" in uppercase for legacy implementations, bestie ๐Ÿ’– see Appendix A.2 for an example of a Nested JWT ๐Ÿงš

5.3. Replicating Claims as Header Parameters โœจ

okay so in some apps using encrypted JWTs, it's actually super useful to have an unencrypted copy of some claims ๐Ÿ”“ an app might use it in its processing rules to decide whether and how to handle the JWT before it gets decrypted. iykyk ๐Ÿซถ

this spec lets claims from the JWT Claims Set get replicated as Header Parameters in a JWT that's a JWE, whenever the app needs it. if those replicated claims show up, the app receiving them SHOULD verify that their values are identical, unless the app has its own specific processing rules for them. and it's the app's job to make sure only claims that are safe to send unencrypted get replicated as Header Parameter values in the JWT ๐Ÿšจ

Section 10.4.1 of this specification registers the "iss" (issuer), "sub" (subject), and "aud" (audience) Header Parameter names, so apps that need unencrypted replicas of those claims in encrypted JWTs have them ready to go ๐ŸŒธ other specifications MAY similarly register other names that are registered Claim Names as Header Parameter names, as needed โœจ


6. Unsecured JWTs ๐Ÿฆ‹

so this is for when the JWT content gets secured some other way, like a signature on a data structure that holds the JWT, instead of a signature and/or encryption inside the JWT itself. in those cases JWTs MAY also be created without a signature or encryption ๐Ÿซง an Unsecured JWT is a JWS that uses the "alg" Header Parameter value none and the empty string for its JWS Signature value, as defined in the JWA specification [JWA]. it's an Unsecured JWS with the JWT Claims Set as its JWS Payload ๐Ÿ’œ

6.1. Example Unsecured JWT

the following example JOSE Header says the encoded object is an Unsecured JWT ๐Ÿ‘€

{"alg":"none"}

Base64url encoding the octets of the UTF-8 representation of the JOSE Header gives you this encoded JOSE Header value ๐Ÿ“

eyJhbGciOiJub25lIn0

here's an example of a JWT Claims Set ๐Ÿ’…

{"iss":"joe",
 "exp":1300819380,
 "http://example.com/is_root":true}

Base64url encoding the octets of the UTF-8 representation of the JWT Claims Set gives you this encoded JWS Payload (with line breaks for display purposes only) ๐ŸŒˆ

eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt
cGxlLmNvbS9pc19yb290Ijp0cnVlfQ

the encoded JWS Signature is the empty string ๐Ÿซ 

concatenate these encoded parts in this order with period ('.') characters between them, and you get this complete JWT (with line breaks for display purposes only) ๐ŸŽ€

eyJhbGciOiJub25lIn0
.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFt
cGxlLmNvbS9pc19yb290Ijp0cnVlfQ
.

7. Creating and Validating JWTs ๐Ÿ’…

7.1. Creating a JWT

okay so to create a JWT, these steps happen โœจ the order of the steps doesn't matter in cases where the steps don't depend on each other's inputs and outputs.

  1. Create a JWT Claims Set containing the desired claims. Note that whitespace is explicitly allowed in the representation and no canonicalization need be performed before encoding. ๐Ÿงš
  2. Let the Message be the octets of the UTF-8 representation of the JWT Claims Set. ๐Ÿ’–
  3. Create a JOSE Header containing the desired set of Header Parameters. The JWT MUST conform to either the [JWS] or [JWE] specification. Note that whitespace is explicitly allowed in the representation and no canonicalization need be performed before encoding. ๐ŸŒธ
  4. Depending upon whether the JWT is a JWS or JWE, there are two cases: ๐Ÿฆ‹
    • If the JWT is a JWS, create a JWS using the Message as the JWS Payload; all steps specified in [JWS] for creating a JWS MUST be followed.
    • Else, if the JWT is a JWE, create a JWE using the Message as the plaintext for the JWE; all steps specified in [JWE] for creating a JWE MUST be followed.
  5. If a nested signing or encryption operation will be performed, let the Message be the JWS or JWE, and return to Step 3, using a "cty" (content type) value of "JWT" in the new JOSE Header created in that step. ๐Ÿช†
  6. Otherwise, let the resulting JWT be the JWS or JWE. ๐Ÿ‘‘

7.2. Validating a JWT

when validating a JWT, these steps happen ๐Ÿ” the order doesn't matter in cases where there are no dependencies between the inputs and outputs of the steps. if any of the listed steps fail, then the JWT MUST be rejected, which means the app treats it as an invalid input ๐Ÿšซ

  1. Verify that the JWT contains at least one period ('.') character. ๐Ÿ”Ž
  2. Let the Encoded JOSE Header be the portion of the JWT before the first period ('.') character. ๐Ÿงฉ
  3. Base64url decode the Encoded JOSE Header following the restriction that no line breaks, whitespace, or other additional characters have been used. ๐Ÿฌ
  4. Verify that the resulting octet sequence is a UTF-8-encoded representation of a completely valid JSON object conforming to RFC 7159 [RFC7159]; let the JOSE Header be this JSON object. ๐Ÿ“œ
  5. Verify that the resulting JOSE Header includes only parameters and values whose syntax and semantics are both understood and supported, or that are specified as being ignored when not understood. ๐Ÿซง
  6. Determine whether the JWT is a JWS or a JWE using any of the methods described in Section 9 of [JWE]. ๐Ÿ•ต๏ธโ€โ™€๏ธ
  7. Depending upon whether the JWT is a JWS or JWE, there are two cases: ๐ŸŽญ
    • If the JWT is a JWS, follow the steps specified in [JWS] for validating a JWS. Let the Message be the result of base64url decoding the JWS Payload.
    • Else, if the JWT is a JWE, follow the steps specified in [JWE] for validating a JWE. Let the Message be the resulting plaintext.
  8. If the JOSE Header contains a "cty" (content type) value of "JWT", then the Message is a JWT that was the subject of nested signing or encryption operations. In this case, return to Step 1, using the Message as the JWT. ๐Ÿชž
  9. Otherwise, base64url decode the Message following the restriction that no line breaks, whitespace, or other additional characters have been used. ๐ŸŒท
  10. Verify that the resulting octet sequence is a UTF-8-encoded representation of a completely valid JSON object conforming to RFC 7159 [RFC7159]; let the JWT Claims Set be this JSON object. ๐Ÿ’œ

finally, it's an application decision which algorithms may be used in a given context. even if a JWT can be successfully validated, unless the algorithms used in the JWT are acceptable to the application, it SHOULD reject the JWT ๐Ÿ›‘

7.3. String Comparison Rules

processing a JWT inevitably means comparing known strings to members and values in JSON objects ๐Ÿง  for example, when checking what the algorithm is, the Unicode [UNICODE] string encoding "alg" gets checked against the member names in the JOSE Header to see if there's a matching Header Parameter name ๐Ÿ”ค

the JSON rules for member name comparison are described in Section 8.3 of RFC 7159 [RFC7159]. since the only string comparison operations performed are equality and inequality, the same rules can be used for comparing both member names and member values against known strings ๐Ÿซถ

these comparison rules MUST be used for all JSON string comparisons, except in cases where the definition of the member explicitly calls out that a different comparison rule is to be used for that member value. in this spec, only the "typ" and "cty" member values don't use these comparison rules ๐Ÿ™…โ€โ™€๏ธ

some apps may include case-insensitive information in a case-sensitive value, like a DNS name as part of the "iss" (issuer) claim value ๐ŸŒ in those cases, the app may need to define a convention for the canonical case to use for the case-insensitive portions, like lowercasing them, if more than one party might need to produce the same value so they can be compared. (however, if all other parties consume whatever value the producing party emitted verbatim without comparing it to an independently produced value, then the producer's case won't matter ๐Ÿฅฐ)

8. Implementation Requirements ๐ŸŒˆ

this section defines which algorithms and features of this spec are mandatory to implement. apps using this spec can impose additional requirements on the implementations they use. for instance, one app might require support for encrypted JWTs and Nested JWTs, while another might require support for signing JWTs with the Elliptic Curve Digital Signature Algorithm (ECDSA) using the P-256 curve and the SHA-256 hash algorithm ("ES256") ๐Ÿ”

of the signature and MAC algorithms specified in JSON Web Algorithms [JWA], only HMAC SHA-256 ("HS256") and "none" MUST be implemented by conforming JWT implementations. it's RECOMMENDED that implementations also support RSASSA-PKCS1-v1_5 with the SHA-256 hash algorithm ("RS256") and ECDSA using the P-256 curve and the SHA-256 hash algorithm ("ES256") ๐Ÿ’– support for other algorithms and key sizes is OPTIONAL โœจ

support for encrypted JWTs is OPTIONAL ๐ŸŽ€ if an implementation provides encryption capabilities, of the encryption algorithms specified in [JWA], only RSAES-PKCS1-v1_5 with 2048-bit keys ("RSA1_5"), AES Key Wrap with 128- and 256-bit keys ("A128KW" and "A256KW"), and the composite authenticated encryption algorithm using AES-CBC and HMAC SHA-2 ("A128CBC-HS256" and "A256CBC-HS512") MUST be implemented by conforming implementations. it's RECOMMENDED that implementations also support using Elliptic Curve Diffie-Hellman Ephemeral Static (ECDH-ES) to agree upon a key used to wrap the Content Encryption Key ("ECDH-ES+A128KW" and "ECDH-ES+A256KW") and AES in Galois/Counter Mode (GCM) with 128- and 256-bit keys ("A128GCM" and "A256GCM"). support for other algorithms and key sizes is OPTIONAL ๐Ÿฆ‹

support for Nested JWTs is OPTIONAL ๐Ÿช†

9. URI for Declaring that Content is a JWT ๐Ÿ”—

this spec registers the URN urn:ietf:params:oauth:token-type:jwt for use by applications that declare content types using URIs (rather than, for instance, media types) to indicate that the content referred to is a JWT ๐Ÿงšโ€โ™€๏ธ

10. IANA Considerations ๐ŸŽ€

10.1. JSON Web Token Claims Registry

okay so this section sets up the IANA "JSON Web Token Claims" registry ๐Ÿ—‚๏ธ, which is where all the JWT Claim Names get listed, along with a pointer to the spec that defines each one. bestie, it's literally registering the Claim Names from Section 4.1 โœจ

Values get registered on a Specification Required [RFC5226] basis, after a three-week review period on the jwt-reg-review@ietf.org mailing list, with advice from one or more Designated Experts ๐Ÿง‘โ€โš–๏ธ. buuut to let values get allocated before the spec is published, the Designated Experts can approve a registration once they're satisfied that the spec will get published ๐Ÿ”ฎ.

Requests sent to that list for review should use a proper subject, like "Request to register claim: example" ๐Ÿ“จ.

Within the review period, the Designated Experts will either approve or deny the request and tell both the review list and IANA ๐Ÿ“ฃ. Denials come with an explanation and, if it makes sense, tips on how to make the request work next time ๐Ÿ’ก. If a request is still undetermined after more than 21 days, it can be brought to the IESG's attention on the iesg@ietf.org mailing list ๐Ÿšจ.

The Designated Experts check a few things: whether the registration duplicates existing functionality, whether it's likely to be generally useful or only good for one single application, and whether the description is clear ๐Ÿ”.

IANA must only accept registry updates from the Designated Experts and should direct all registration requests to the review mailing list ๐Ÿ™…โ€โ™€๏ธ.

It is suggested that multiple Designated Experts be appointed, ideally people who represent the different applications using this specification, so the reviews are broadly informed ๐ŸŒˆ. In cases where a decision could look like a conflict of interest for a particular Expert, that Expert should defer to the judgment of the other Experts ๐Ÿซถ.

10.1.1. Registration Template

Here's the form you fill out to register a claim ๐Ÿ“

   Claim Name:
      The name requested (e.g., "iss").  Because a core goal of this
      specification is for the resulting representations to be compact,
      it is RECOMMENDED that the name be short -- that is, not to exceed
      8 characters without a compelling reason to do so.  This name is
      case sensitive.  Names may not match other registered names in a
      case-insensitive manner unless the Designated Experts state that
      there is a compelling reason to allow an exception.

   Claim Description:
      Brief description of the claim (e.g., "Issuer").

   Change Controller:
      For Standards Track RFCs, list the "IESG".  For others, give the
      name of the responsible party.  Other details (e.g., postal
      address, email address, home page URI) may also be included.

   Specification Document(s):
      Reference to the document or documents that specify the parameter,
      preferably including URIs that can be used to retrieve copies of
      the documents.  An indication of the relevant sections may also be
      included but is not required.

10.1.2. Initial Registry Contents

Here's the starter set of claims that get registered right away โœจ

   o  Claim Name: "iss"
   o  Claim Description: Issuer
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.1 of RFC 7519

   o  Claim Name: "sub"
   o  Claim Description: Subject
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.2 of RFC 7519

   o  Claim Name: "aud"
   o  Claim Description: Audience
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.3 of RFC 7519
   o  Claim Name: "exp"
   o  Claim Description: Expiration Time
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.4 of RFC 7519

   o  Claim Name: "nbf"
   o  Claim Description: Not Before
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.5 of RFC 7519

   o  Claim Name: "iat"
   o  Claim Description: Issued At
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.6 of RFC 7519

   o  Claim Name: "jti"
   o  Claim Description: JWT ID
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.7 of RFC 7519

10.2. Sub-Namespace Registration of urn:ietf:params:oauth:token-type:jwt

10.2.1. Registry Contents

This one adds the value "token-type:jwt" to the IANA "OAuth URI" registry ๐Ÿฆ‹. That registry came from "An IETF URN Sub-Namespace for OAuth" [RFC6755], and this value is how you say that the content is a JWT ๐Ÿ’–.

   o  URN: urn:ietf:params:oauth:token-type:jwt
   o  Common Name: JSON Web Token (JWT) Token Type
   o  Change Controller: IESG
   o  Specification Document(s): RFC 7519

10.3. Media Type Registration

10.3.1. Registry Contents

Next up, this registers the "application/jwt" media type [RFC2046] in the "Media Types" registry [IANA.MediaTypes], done the way RFC 6838 [RFC6838] describes ๐Ÿ’œ. It's how you tell the world the content is a JWT ๐ŸŒธ.

   o  Type name: application
   o  Subtype name: jwt
   o  Required parameters: n/a
   o  Optional parameters: n/a
   o  Encoding considerations: 8bit; JWT values are encoded as a series
      of base64url-encoded values (some of which may be the empty
      string) separated by period ('.') characters.
   o  Security considerations: See the Security Considerations section
      of RFC 7519
   o  Interoperability considerations: n/a
   o  Published specification: RFC 7519
   o  Applications that use this media type: OpenID Connect, Mozilla
      Persona, Salesforce, Google, Android, Windows Azure, Amazon Web
      Services, and numerous others
   o  Fragment identifier considerations: n/a
   o  Additional information:

         Magic number(s): n/a
         File extension(s): n/a
         Macintosh file type code(s): n/a

   o  Person & email address to contact for further information:
      Michael B. Jones, mbj@microsoft.com
   o  Intended usage: COMMON
   o  Restrictions on usage: none
   o  Author: Michael B. Jones, mbj@microsoft.com
   o  Change controller: IESG
   o  Provisional registration?  No

10.4. Header Parameter Names Registration

This section registers specific Claim Names from Section 4.1 in the IANA "JSON Web Signature and Encryption Header Parameters" registry ๐Ÿ”ง. That registry was set up by [JWS], and the names are for claims that get replicated as Header Parameters in JWEs, per Section 5.3 โœจ.

10.4.1. Registry Contents

   o  Header Parameter Name: "iss"
   o  Header Parameter Description: Issuer
   o  Header Parameter Usage Location(s): JWE
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.1 of RFC 7519

   o  Header Parameter Name: "sub"
   o  Header Parameter Description: Subject
   o  Header Parameter Usage Location(s): JWE
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.2 of RFC 7519

   o  Header Parameter Name: "aud"
   o  Header Parameter Description: Audience
   o  Header Parameter Usage Location(s): JWE
   o  Change Controller: IESG
   o  Specification Document(s): Section 4.1.3 of RFC 7519

11. Security Considerations ๐Ÿ›ก๏ธ

okay this part is SERIOUS bestie ๐Ÿ˜ค. Every single security issue that matters for any cryptographic application must be addressed by JWT/JWS/JWE/JWK agents. That includes protecting the user's asymmetric private and symmetric secret keys and using countermeasures against the various attacks out there ๐Ÿ”.

All the security considerations in the JWS specification also apply to JWT, and the JWE security considerations apply too whenever encryption is used. In particular, Sections 10.12 ("JSON Security Considerations") and 10.13 ("Unicode Comparison Security Considerations") of [JWS] apply equally to the JWT Claims Set in the same way they apply to the JOSE Header ๐Ÿ’€.

11.1. Trust Decisions

A JWT's contents can't be relied upon for a trust decision unless they've been cryptographically secured and bound to the context that decision needs ๐Ÿšซ. Basically, the key(s) used to sign and/or encrypt the JWT will typically need to be verifiably under the control of the party identified as the JWT's issuer ๐Ÿ”‘.

11.2. Signing and Encryption Order

Syntactically, the signing and encryption operations for Nested JWTs can be applied in any order ๐Ÿ”„. But if you need both signing and encryption, normally producers should sign the message and then encrypt the result, which means the signature gets encrypted too ๐Ÿ”’. This stops attacks where the signature gets stripped and you're left with just an encrypted message ๐Ÿ˜ฑ, and it also gives the signer privacy ๐Ÿซฃ. Plus, signatures over encrypted text are not considered valid in many jurisdictions ๐ŸŒ.

Note that the order-of-operations security concerns are already handled by the underlying JWS and JWE specs. Because JWE only supports authenticated encryption algorithms, the cryptographic worries about needing to sign after encryption, which show up in lots of contexts, don't apply to this specification โœจ.


12. Privacy Considerations ๐Ÿ™ˆ

A JWT may contain privacy-sensitive information. When that's the case, measures MUST be taken to prevent disclosure of this information to unintended parties ๐Ÿšจ. One way to do that is to use an encrypted JWT and authenticate the recipient ๐Ÿ”. Another way is to make sure JWTs with unencrypted privacy-sensitive info only get sent over protocols that use encryption and support endpoint authentication, like Transport Layer Security (TLS) ๐Ÿ›ก๏ธ. And honestly? Leaving privacy-sensitive information out of a JWT is the simplest way to minimize privacy issues ๐ŸŽ€.

13. References ๐Ÿ“š

13.1. Normative References โœจ

These are the docs you MUST have read first, bestie ๐Ÿง  (I've left the capital letters off here, so none of these words are actual requirement keywords). Here's the list, all of it:

[ECMAScript]: Ecma International, "ECMAScript Language Specification, 5.1 Edition", ECMA Standard 262, June 2011, http://www.ecma-international.org/ecma-262/5.1/ECMA-262.pdf.

[IANA.MediaTypes]: IANA, "Media Types", http://www.iana.org/assignments/media-types.

[JWA]: Jones, M., "JSON Web Algorithms (JWA)", RFC 7518, DOI 10.17487/RFC7518, May 2015, http://www.rfc-editor.org/info/rfc7518.

[JWE]: Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)", RFC 7516, DOI 10.17487/RFC7516, May 2015, http://www.rfc-editor.org/info/rfc7516.

[JWS]: Jones, M., Bradley, J., and N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, DOI 10.17487/RFC, May 2015, http://www.rfc-editor.org/info/rfc7515. (Yes, that DOI is cut short in the original. Iconic chaos ๐Ÿ’€)

[RFC20]: Cerf, V., "ASCII format for Network Interchange", STD 80, RFC 20, DOI 10.17487/RFC0020, October 1969, http://www.rfc-editor.org/info/rfc20.

[RFC2046]: Freed, N. and N. Borenstein, "Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types", RFC 2046, DOI 10.17487/RFC2046, November 1996, http://www.rfc-editor.org/info/rfc2046.

[RFC2119]: Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, http://www.rfc-editor.org/info/rfc2119. ๐Ÿ”‘

[RFC3986]: Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, DOI 10.17487/RFC3986, January 2005, http://www.rfc-editor.org/info/rfc3986.

[RFC4949]: Shirey, R., "Internet Security Glossary, Version 2", FYI 36, RFC 4949, DOI 10.17487/RFC4949, August 2007, http://www.rfc-editor.org/info/rfc4949.

[RFC7159]: Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March 2014, http://www.rfc-editor.org/info/rfc7159.

[UNICODE]: The Unicode Consortium, "The Unicode Standard", http://www.unicode.org/versions/latest/.

13.2. Informative References ๐Ÿ“š

These are the "nice to read but you don't need them to survive" ones ๐Ÿซถ

[CanvasApp]: Facebook, "Canvas Applications", 2010, http://developers.facebook.com/docs/authentication/canvas.

[JSS]: Bradley, J. and N. Sakimura (editor), "JSON Simple Sign", September 2010, http://jsonenc.info/jss/1.0/.

[MagicSignatures]: Panzer, J., Ed., Laurie, B., and D. Balfanz, "Magic Signatures", January 2011, http://salmon-protocol.googlecode.com/svn/trunk/draft-panzer-magicsig-01.html.

[OASIS.saml-core-2.0-os]: Cantor, S., Kemp, J., Philpott, R., and E. Maler, "Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0", OASIS Standard saml-core-2.0-os, March 2005, http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf.

[POSIX.1]: IEEE, "The Open Group Base Specifications Issue 7", IEEE Std 1003.1, 2013 Edition, 2013, http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15.

[RFC3275]: Eastlake 3rd, D., Reagle, J., and D. Solo, "(Extensible Markup Language) XML-Signature Syntax and Processing", RFC 3275, DOI 10.17487/RFC3275, March 2002, http://www.rfc-editor.org/info/rfc3275.

[RFC3339]: Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, http://www.rfc-editor.org/info/rfc3339.

[RFC4122]: Leach, P., Mealling, M., and R. Salz, "A Universally Unique IDentifier (UUID) URN Namespace", RFC 4122, DOI 10.17487/RFC4122, July 2005, http://www.rfc-editor.org/info/rfc4122.

[RFC5226]: Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, DOI 10.17487/RFC5226, May 2008, http://www.rfc-editor.org/info/rfc5226.

[RFC6755]: Campbell, B. and H. Tschofenig, "An IETF URN Sub-Namespace for OAuth", RFC 6755, DOI 10.17487/RFC6755, October 2012, http://www.rfc-editor.org/info/rfc6755.

[RFC6838]: Freed, N., Klensin, J., and T. Hansen, "Media Type Specifications and Registration Procedures", BCP 13, RFC 6838, DOI 10.17487/RFC6838, January 2013, http://www.rfc-editor.org/info/rfc6838.

[SWT]: Hardt, D. and Y. Goland, "Simple Web Token (SWT)", Version 0.9.5.1, November 2009, http://msdn.microsoft.com/en-us/library/windowsazure/hh781551.aspx.

[W3C.CR-xml11-20060816]: Cowan, J., "Extensible Markup Language (XML) 1.1 (Second Edition)", World Wide Web Consortium Recommendation REC-xml11-20060816, August 2006, http://www.w3.org/TR/2006/REC-xml11-20060816.

[W3C.REC-xml-c14n-20010315]: Boyer, J., "Canonical XML Version 1.0", World Wide Web Consortium Recommendation REC-xml-c14n-20010315, March 2001, http://www.w3.org/TR/2001/REC-xml-c14n-20010315.


Appendix A. JWT Examples ๐ŸŽ€

This bit is the fun part, the examples! Here's what's in it: a few JWTs, and if you want the other example JWTs, go check Section 6.1 of this document and Appendices A.1 - A.3 of [JWS] ๐Ÿฆ‹

A.1. Example Encrypted JWT ๐Ÿ”

This one takes the same claims we used in Section 3.1 and encrypts them to the recipient using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256. Lowkey iconic ๐Ÿ’…

The JOSE Header below tells you that:

  • The Content Encryption Key is encrypted to the recipient using the RSAES-PKCS1-v1_5 algorithm to produce the JWE Encrypted Key.
  • Authenticated encryption is performed on the plaintext using the AES_128_CBC_HMAC_SHA_256 algorithm to produce the JWE Ciphertext and the JWE Authentication Tag.
{"alg":"RSA1_5","enc":"A128CBC-HS256"}

Other than using the octets of the UTF-8 representation of the JWT Claims Set from Section 3.1 as the plaintext value, the computation of this JWT is identical to the computation of the JWE in Appendix A.2 of [JWE], including the keys used. So it's basically the same recipe, just with a different plaintext ๐Ÿ“

The final result in this example (with line breaks for display purposes only) is:

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.
QR1Owv2ug2WyPBnbQrRARTeEk9kDO2w8qDcjiHnSJflSdv1iNqhWXaKH4MqAkQtM
oNfABIPJaZm0HaA415sv3aeuBWnD8J-Ui7Ah6cWafs3ZwwFKDFUUsWHSK-IPKxLG
TkND09XyjORj_CHAgOPJ-Sd8ONQRnJvWn_hXV1BNMHzUjPyYwEsRhDhzjAD26ima
sOTsgruobpYGoQcXUwFDn7moXPRfDE8-NoQX7N7ZYMmpUDkR-Cx9obNGwJQ3nM52
YCitxoQVPzjbl7WBuB7AohdBoZOdZ24WlN1lVIeh8v1K4krB8xgKvRU8kgFrEn_a
1rZgN5TiysnmzTROF869lQ.
AxY8DCtDaGlsbGljb3RoZQ.
MKOle7UQrG6nSxTLX6Mqwt0orbHvAKeWnDYvpIAeZ72deHxz3roJDXQyhxx0wKaM
HDjUEOKIwrtkHthpqEanSBNYHZgmNOV7sln1Eu9g3J8.
fiK51VwhsxJ-siBMR-YFiA

A.2. Example Nested JWT ๐Ÿช†

This one is a JWT nested inside a JWE, so the layers go: sign it, then encrypt it. Nested JWTs are ICONIC ๐Ÿ‘‘

The inner signed JWT is identical to the example in Appendix A.2 of [JWS], so there's no point repeating its computation here. This example then encrypts that inner JWT to the recipient using RSAES-PKCS1-v1_5 and AES_128_CBC_HMAC_SHA_256 โœจ

The JOSE Header below tells you that:

  • The Content Encryption Key is encrypted to the recipient using the RSAES-PKCS1-v1_5 algorithm to produce the JWE Encrypted Key.
  • Authenticated encryption is performed on the plaintext using the AES_128_CBC_HMAC_SHA_256 algorithm to produce the JWE Ciphertext and the JWE Authentication Tag.
  • The plaintext is itself a JWT.
{"alg":"RSA1_5","enc":"A128CBC-HS256","cty":"JWT"}

Base64url encoding the octets of the UTF-8 representation of the JOSE Header gives you this encoded JOSE Header value:

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiY3R5IjoiSldUIn0

The computation of this JWT is identical to the computation of the JWE in Appendix A.2 of [JWE], other than that a different JOSE Header, plaintext, JWE Initialization Vector, and Content Encryption Key values are used. (The RSA key used is the same, so that part is giving consistency ๐Ÿฅน)

The plaintext used is the octets of the ASCII [RFC20] representation of the JWT at the end of Appendix A.2.1 of [JWS] (with all whitespace and line breaks removed), which is a sequence of 458 octets. That's a lot of octets, periodt ๐Ÿ”ข

The JWE Initialization Vector value used (using JSON array notation) is:

[82, 101, 100, 109, 111, 110, 100, 32, 87, 65, 32, 57, 56, 48, 53,
50]

This example uses the Content Encryption Key represented by the base64url-encoded value below:

GawgguFyGrWKav7AX4VKUg

The final result for this Nested JWT (with line breaks for display purposes only) is:

eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiY3R5IjoiSldU
In0.
g_hEwksO1Ax8Qn7HoN-BVeBoa8FXe0kpyk_XdcSmxvcM5_P296JXXtoHISr_DD_M
qewaQSH4dZOQHoUgKLeFly-9RI11TG-_Ge1bZFazBPwKC5lJ6OLANLMd0QSL4fYE
b9ERe-epKYE3xb2jfY1AltHqBO-PM6j23Guj2yDKnFv6WO72tteVzm_2n17SBFvh
DuR9a2nHTE67pe0XGBUS_TK7ecA-iVq5COeVdJR4U4VZGGlxRGPLRHvolVLEHx6D
YyLpw30Ay9R6d68YCLi9FYTq3hIXPK_-dmPlOUlKvPr1GgJzRoeC9G5qCvdcHWsq
JGTO_z3Wfo5zsqwkxruxwA.
UmVkbW9uZCBXQSA5ODA1Mg.
VwHERHPvCNcHHpTjkoigx3_ExK0Qc71RMEParpatm0X_qpg-w8kozSjfNIPPXiTB
BLXR65CIPkFqz4l1Ae9w_uowKiwyi9acgVztAi-pSL8GQSXnaamh9kX1mdh3M_TT
-FZGQFQsFhu0Z72gJKGdfGE-OE7hS1zuBD5oEUfk0Dmb0VzWEzpxxiSSBbBAzP10
l56pPfAtrjEYw-7ygeMkwBl6Z_mLS6w6xUgKlvW6ULmkV-uLC4FUiyKECK4e3WZY
Kw1bpgIqGYsw2v_grHjszJZ-_I5uM-9RA8ycX9KqPRp9gc6pXmoU_-27ATs9XCvr
ZXUtK2902AUzqpeEUJYjWWxSNsS-r1TJ1I-FMJ4XyAiGrfmo9hQPcNBYxPz3GQb2
8Y5CLSQfNgKSGt0A4isp1hBUXBHAndgtcslt7ZoQJaKe_nNJgNliWtWpJ_ebuOpE
l8jdhehdccnRMIwAmU1n7SPkmhIl1HlSOpvcvDfhUN5wuqU955vOBvfkBOh5A11U
zBuo2WlgZ6hYi9-e3w29bR0C2-pp3jbqxEDw3iWaf2dc5b-LnR0FEYXvI_tYk5rd
_J9N0mg0tQ6RbpxNEMNoA9QWk5lgdPvbh9BaO195abQ.
AVO9iT5AV4CzvDJCdhSFlQ

Appendix B. Relationship of JWTs to SAML Assertions โœจ

bestie, okay so SAML 2.0 [OASIS.saml-core-2.0-os] is basically the fancy, feature-packed token standard. It can do way more stuff than JWTs and has more security options ๐Ÿ’…. BUT that power comes with a price: it's big and it's complicated ๐Ÿ˜ญ. SAML leans on XML [W3C.CR-xml11-20060816] and XML Digital Signature (DSIG) [RFC3275], which makes its assertions chunky, and the use of XML plus especially XML Canonicalization [W3C.REC-xml-c14n-20010315] adds a whole lot of complexity ๐Ÿ™ˆ.

Now JWTs have a different vibe ๐Ÿฆ‹. They're meant to be a simple security token format that's small enough to fit inside HTTP headers and query arguments in URIs ๐ŸŽ€. They get there by using a much simpler token model than SAML and by using the JSON [RFC7159] object encoding syntax. They also support securing tokens with Message Authentication Codes (MACs) and digital signatures, using a smaller and less flexible format than XML DSIG. Lowkey iconic ๐ŸŒธ.

So, is a JWT a full replacement for SAML? Nope, not at all ๐Ÿ™…โ€โ™€๏ธ. JWTs can do some of the things SAML Assertions do, but they're meant for situations where ease of implementation or compactness are the priority โœจ. Use the right tool, periodt ๐Ÿ’œ.

Last thing: SAML Assertions are always statements an entity makes about a subject. JWTs are often used the same way, where the entity making the statements is represented by the "iss" (issuer) claim and the subject is represented by the "sub" (subject) claim ๐Ÿซถ. But since those claims are optional, other uses of the JWT format are allowed too ๐ŸŒˆ.

Appendix C. Relationship of JWTs to Simple Web Tokens (SWTs) ๐Ÿงš

Okay this one is giving sibling energy ๐Ÿ‘ฏโ€โ™€๏ธ. Both JWTs and SWTs [SWT] basically let sets of claims get passed between applications ๐Ÿ’–. The difference is SWTs only use strings for both claim names and claim values, whereas for JWTs the claim names are strings but the claim values can be any JSON type ๐Ÿ“. For cryptographic protection, SWTs use HMAC SHA-256, while JWTs can choose from a bunch of algorithms, including signature, MAC, and encryption algorithms ๐Ÿ”ฅ.

Acknowledgements ๐Ÿ‘‘

The authors want to shout out that the design of JWTs was intentionally influenced by the design and simplicity of SWTs [SWT], plus ideas for JSON tokens that Dick Hardt discussed within the OpenID community ๐ŸŽ€.

Solutions for signing JSON content were explored earlier by Magic Signatures [MagicSignatures], JSON Simple Sign [JSS], and Canvas Applications [CanvasApp], and all of them influenced this document ๐Ÿฆ‹.

This specification is the work of the OAuth working group, which has dozens of active and dedicated participants ๐ŸŒธ. In particular, the following individuals contributed ideas, feedback, and wording that shaped this specification:

Dirk Balfanz, Richard Barnes, Brian Campbell, Alissa Cooper, Breno de Medeiros, Stephen Farrell, Yaron Y. Goland, Dick Hardt, Joe Hildebrand, Jeff Hodges, Edmund Jay, Warren Kumari, Ben Laurie, Barry Leiba, Ted Lemon, James Manger, Prateek Mishra, Kathleen Moriarty, Tony Nadalin, Axel Nennker, John Panzer, Emmanuel Raviart, David Recordon, Eric Rescorla, Jim Schaad, Paul Tarjan, Hannes Tschofenig, Sean Turner, and Tom Yu ๐Ÿ’œ.

Hannes Tschofenig and Derek Atkins chaired the OAuth working group, and Sean Turner, Stephen Farrell, and Kathleen Moriarty were the Security Area Directors while this specification was being created ๐Ÿ‘‘.

Authors' Addresses ๐Ÿ“ฌ

Michael B. Jones Microsoft

EMail: mbj@microsoft.com URI: http://self-issued.info/

John Bradley Ping Identity

EMail: ve7jtb@ve7jtb.com URI: http://www.thread-safe.com/

Nat Sakimura Nomura Research Institute

EMail: n-sakimura@nri.co.jp URI: http://nat.sakimura.org/

๐Ÿ“ฆ where this page comes from