Let's talk about JWT

Hi, It's Dino-at-Google here.

The JWT format is important and is getting widespread adoption in systems everywhere. It's easy to understand, it's easy to use, and it's supported widely. And that means more and more Apigee Edge customers are using JWT, and asking about JWT.

With the interest I've seen recently in the JWT policies within Apigee Edge, it's time for an article reviewing some of the capabilities.

First, Some background. How Does JWT work?

JWT is a token format. It's a way to wrap up a bunch of claims (or "assertions" if you like) into a signed payload. Any application (client or server) can generate a JWT. A generator system can produce a JSON payload like this:

{
  "iss": "3r6bjRdkqnwG8v9Kb0KSOCjpnj",
  "sub": "somebody@example.com",
  "aud": "urn://www.apigee.com/apitechforum/token",
  "iat": 1526919625,
  "uid": "example1",
  "email": "fabricator@example.com"
}

...and then sign that, and then wrap it up, and the result is a JWT. The "claims" are the property name/value pairs in that JSON payload. "iss" denotes "Issuer" and the issuer in this case is an random-looking string of characters. "sub" denotes "Subject" and is the subject of the claims. "aud" denotes "Audience" and is an identifier indicating the expected party that will read and rely upon the information in the JWT.

iss, aud, sub, iat - These are all examples of "well known" claim names. There are more such claims. You can read about them in detail in the JWT spec. But JWT is extensible, and a valid JWT need not include any of those so-called "standard" claims. Furthermore, any generator can include one or more of any other claim, of any type, into the payload. "Shoesize" and "Favorite flavor of ice cream" are valid claim names. More relevant for an ID token might be claims like "group", "role", or "accountType".

An actual JWT, once "wrapped up", is a string of characters, for example:

eyJhbGciOiJSUzI1NiIsImtpZCI6IjVhNjhmYzhhM2VjMGMzMGUwYmU5NWFhMDhkYjk5YTY4YTcyNTQ2N2YifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhdWQiOiI5NjEzNDkzMzkwMy12M20xNm1nM3FlcjRhNGV0a2cwdDd2dWlqMWJqM25hOC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwMTg2NjU1MDk2OTQ2MzUyNzA4MyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhenAiOiI5NjEzNDkzMzkwMy12M20xNm1nM3FlcjRhNGV0a2cwdDd2dWlqMWJqM25hOC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsIm5vbmNlIjoiMTA5MTAxMDEiLCJlbWFpbCI6ImRwY2hpZXNhQGhvdG1haWwuY29tIiwiaWF0IjoxNDUyNjYyMzE5LCJleHAiOjE0NTI2NjU5MTksIm5hbWUiOiJEaW5vIENoaWVzYSIsInBpY3R1cmUiOiJodHRwczovL2xoNS5nb29nbGV1c2VyY29udGVudC5jb20vLWVMMXdkd0hwYU5ZL0FBQUFBQUFBQUFJL0FBQUFBQUFBQWNRL1lqOVpoUGU4VmRBL3M5Ni1jL3Bob3RvLmpwZyIsImdpdmVuX25hbWUiOiJEaW5vIiwiZmFtaWx5X25hbWUiOiJDaGllc2EiLCJsb2NhbGUiOiJlbiJ9.wM8Z0ERBR8ALWLrF6qk40_lOT6seo-w-CSRHXiA1l07ALt6Rz1Yy-z8cxkorQe0BnaSm5-lTf5u7YTarn-QKzHqyWCnX15-NvgeVxbePBdgIQGXOUmgFoE2INq90TjXofvNcl1VtdPOQ97R7izxc_TgA3E_PP70zG_l8MJp0Mt-HnbAhDxjwRPIIORrlzLJlO-gzBnlfzrZ6fgZEvYosclRmQGBIRJygxgACYRwsnegJVCDGNBwLYKankF38V4kOKsq3IvCfpt4sAwc2h4dPZy4k1NWEKEPx-oJr0qUj7h_YrxStWe26VbRn4C5dVNZVm0XC2g2KeVMqz1JPLdICUA

But it's not random; there is structure to it. Look closely and you'll see that it is actually a sequence of 3 strings, concatenated with a dot.

8360-screenshot-20190322-084210.png

Each string is a base64-encoded value of something. In order, they are:

  • Header - a json blob
  • Payload - a json blob
  • Signature - a byte array

So that loooong string is Base64(header) . Base64(payload) . Base64(signature)

Since a JWT is just a sequence of encoded then concatenated strings, JWT can be decoded by any application. You don't need the verification key to read a JWT. In fact, you can decode the above JWT by clicking this JWT.io link. (spoiler alert: that is an old JWT issued and signed by Google, containing claims about ME).

If any party can decode and read a JWT, what good is signature? Just as with any other digital signature, the signature on a JWT insures the origin and integrity of the payload. In more detail, verifying a signature insures (1) that the JWT was signed by the holder of the signing key, and (2) that the data contained within the JWT has not been modified since it was signed by the signer.

When the JWT is signed via RSA, a successful verification checks that the signature was produced by the party holding the private key that matches the public key. (This is the same principle upon which TLS is based). When the JWT is signed with an HMAC algorithm, the verification checks that the signature was produced by a party that possesses the same secret key (aka passphrase) held by the verifier.

There are some implications here:

  • because any signed JWT can be decoded, organizations should take care when embedding information that is ostensibly secret into JWT that will be passed over the network. Also, Organizations should take care to not log JWT if they contain PII.
  • When verifying JWT, organizations should be sure to verify the algorithm used to sign, the key strength, and other important claims. It's not enough to just "Read" the JWT - it's critical that a receiving system verify the signature before relying on the information contained in the JWT.

JWT in Apigee Edge

Using built-in policies, Apigee Edge can decode, or securely verify or generate JWT.

6898-jwt-policies.png

  • DecodeJWT - splits the dot-concatenated string, then base64-decodes the results, and makes the information available to other policies and conditions in the flow, via context variables.
  • VerifyJWT - does the same as the above, but ALSO verifies the signature on the JWT.
  • GenerateJWT - generates a signed JWT, using either RSA or HMAC algorithms. (ECDSA coming soon). If you use RSA, then your signing key can be encrypted or not, your choice.

With these policies, it means that if you have an external system that generates a JWT - like Google Signin, or Azure AD, or Ping Identity - you can use Apigee Edge policies to verify the JWT.

Or, if you need your API proxies to interact with a system that requires a signed JWT - like googleapis, or many other modern systems - you can use Apigee Edge to generate the appropriate JWT.

Also, if you like, you could implement things like OpenID Connect or RFC 7523, using Apigee Edge and its ability to generate or verify arbitrary JWT.

For more on all of this, check out the helpful documentation on these policies. Or, you can watch my youtube overview and demonstration of these policies. If you have questions on using JWT within Apigee Edge, post a new question here on Community and one of the Apigeeks will try to help!

Comments
dubeyrahul
Bronze 2
Bronze 2

HI Dino

When can we expect support for JWE? Right now there is no out of the boxt JWT policy that support encryption. We have to write JAVA callout to support our JWE requirements.

dchiesa1
Staff

Hi Rahul, can you send me a direct message? dchiesa@google.com

Version history
Last update:
‎05-21-2018 03:30 PM
Updated by: