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.
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.
Each string is a base64-encoded value of something. In order, they are:
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:
Using built-in policies, Apigee Edge can decode, or securely verify or generate JWT.
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!
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.
Hi Rahul, can you send me a direct message? dchiesa@google.com