Constructing JWTs

Overview of JWTs

In bearer token authentication, the caller presents a JSON Web Token (JWT). The JWT contains a set of claims. Each claim is a key/value pair that represents information that "the bearer of the token claims to be true". For example, a JWT could contain the following claim, which asserts the identity of the bearer of the token (in the sub claim, which identifies the "subject"):
[
  "sub": "rnewton@email.com",
 ...
]

Cloud API uses information in the JWT to determine the authorization to grant to the caller. This typically involves two types of information:

  • Some information in the JWT identifies the API roles to assign to the caller. This determines the level of endpoint access the caller has.

  • Some information in the JWT identifies the caller's resource access IDs. This determines the level of resource access the caller has. (In other words, this determines which specific resources that caller can access.)

For example, suppose Ray Newton is an insured making a request to ClaimCenter. The JWT includes the following.
[
  "sub": "rnewton@email.com",
  "groups": [
    "gwa.prod.cc.Insured"
  ],
  "cc_policyNumbers": [
    "PA-123456"
  ],
 ...
]

Cloud API grants authorization in this way:

  • Based on the groups claim, the caller is given endpoint access as defined in the Insured API role.

  • Based on the cc_policyNumbers claim, the caller is given resource access to resources associated with any claim whose policy has a number of PA-123456.

The structure and contents of a JWT vary based on the type of caller. But, for every type of caller using bearer token authentication, the JWT either contains the caller's API roles and resource access IDs, or it contains information used to determine the caller's API roles and resource access IDs.

Authorization information can come from one of three sources:

  • Populating JWTS with information from the IdP

  • Populating JWTS with information from the caller application

  • Retrieving information with the IExpandTokenPlugin

Populating JWTs with information from the IdP

Authorization information can come from the identity provider application (IdP). When the caller is a user (as opposed to a service), the caller application sends the caller's username and password to the IdP so that it can authenticate the user. The IdP provides a SAML response indicating whether the user has been authenticated. The IdP can also provide information about the user's authorization, such as:

  • Which API roles ought to be granted to the user

  • The resource access IDs for the user

Guidewire Hub adds any authorization information it receives from the IdP into the JWT.

For example, suppose Guidewire Hub requests authentication for Ray Newton. The IdP could respond with the following information:

  • The caller is authenticated. (The provided password matches the provided username.)

  • The caller's API roles are: gwa.prod.cc.Insured

  • The caller's resource access IDs are: PA-123456

Guidewire Hub would construct a JWT that includes the following claims:
  ...
  "groups": [
    "gwa.prod.cc.Insured"
  ],
  "cc_policyNumbers": [
    "PA-123456"
  ],
 ...

This provides the caller with endpoint access as defined in the Insured API role, and resource access to resources associated with any claim whose policy has a number of PA-123456.

Populating JWTs with information from the caller application

Authorization information can come from the caller application itself. When the caller is a service (as opposed to a user), the caller application sends a scope to Guidewire Hub. This scope identifies the API role to grant to the caller. If the application has registered that scope with Guidewire Hub, Guidewire Hub adds this information to the JWT. (Services are not authenticated by IdPs, and services do not need to provide resource access IDs as they use of a resource access strategy that has open access to all resources.)

For example, suppose Guidewire Hub receives a request from the ACME FNOL Reporter service with the following information:

  • The caller's scope is scp.cc.acme_fnolreporter.

Guidewire Hub would construct a JWT that includes the following claim:
  ...
  "scp": [
    "scp.cc.acme_fnolreporter"
  ],
  ...

This provides the caller with endpoint access as defined in the acme_fnolreporter API role. Because the caller is a service, it is not bound by resource access.

Retrieving information through the IExpandTokenPlugin

Authorization information can come from the IExpandTokenPlugin plugin. This plugin is called after the JWT has been received from the caller but before authorization has been determined. Cloud API extracts the information from the JWT into a "token map". It then calls the plugin, which can make a call to an external system and then add information from the external system to the token map. This map is then used to determine the caller's authorization.

For example, suppose an insurer wants to provide access to insureds, but they do not want to store API role information for insureds in the IdP. This insurer could configure the IExpandTokenPlugin plugin to do the following:

  • Extract the value of the sub (subject) claim from the token map.

  • Send the value to the appropriate external system, which responds with a list of API roles that define endpoint access for the insured

  • Add the API roles to the token map's groups claim.

The JWT received from Guidewire Hub would look like this:
  ...
  "sub": "rnewton@email.com",
  "groups": [
  ],
  ...
After the IExpandTokenPlugin plugin makes it call, the token map would look like this:
  ...
  "sub": "rnewton@email.com",
  "groups": [
    "gwa.prod.cc.Insured"
  ],
  ...

As another example, suppose an insurer wants to provide access for producers. Resource access for producers is determined by producer codes. Each producer can have up to several hundred producer codes, and the amount of data may exceed what can be stored in a JWT. This insurer could configure the IExpandTokenPlugin plugin to do the following:

  • Extract the value of the sub (subject) claim.

  • Send this value to the appropriate external system, which responds with a list of producer codes that define resource access for the producer

  • Add the producer codes to the token map's cc_producerCodes claim.

The JWT received from Guidewire Hub would look like this:
  ...
  "sub": "kegerston@allrisk.com",
  "producerCodes": [
  ],
  ...
After the IExpandTokenPlugin plugin makes its call, the token map would look like this:
  ...
  "sub": "kegerston@allrisk.com",
  "producerCodes": [
    "100-002541",
    "100-002542",
    "100-002543",
    ...
  ],
  ...
Note: The IExpandTokenPlugin plugin does not modify the JWT itself. It modifies only the map that contains information extracted from the JWT. If the JWT is passed on to some other system after the IExpandTokenPlugin plugin has been called, the JWT will be in its original form. It will not contain information retrieved by the plugin.

For more information on configuring the IExpandTokenPlugin, see Configuring the IExpandTokenPlugin plugin.

Summary of JWT flow

The following diagram summarizes the way in which information is added to the JWT and then used.


Flow of JWT information
  1. The caller application (which could be a browser-based application supporting users or a service) requests a JWT from Guidewire Hub. If the caller application is a service, this request includes the service's API roles.

  2. For user callers, Guidewire Hub requests authentication from the IdP. (For services, authentication is performed by Guidewire Hub.)

  3. For user callers, the IdP authenticates the user.

  4. For user callers, the IdP provides a SAML response. This response must include verification that the user has been authenticated. It must also include information about the user's API roles and resource access IDs, or any lookup values needed by the IExpandTokenPlugin plugin to retrieve API roles and resource IDs.

  5. Guidewire Hub constructs the JWT.

  6. Guidewire Hub returns the JWT to the caller application.

  7. The caller application submits the API request to the InsuranceSuite application. The JWT is included in the request header.

  8. Cloud API extracts information from the JWT and puts it into a token map. If necessary, the IExpandTokenPlugin plugin calls an external auth provider to retrieve any additional auth information and add it to the token map.

  9. The caller's authorization is determined using the token map, which contains information from the original JWT and optionally information added by the IExpandTokenPlugin plugin.

  10. The InsuranceSuite application processes the request and sends the response to the caller application.

Configuration requirements for JWTs

For user callers, the token map must ultimately contain the API roles and resource access IDs that define the user's authorization. These values must either:

  • Be included in the SAML response from the IdP, or

  • Be retrieved from an external system using a lookup value that is in the JWT constructed by Guidewire Hub

For most types of callers, use of the IExpandTokenPlugin plugin is optional. However, Guidewire does specifically recommend its use in the case where producers are accessing ClaimCenter. The access strategy for producers relies on producer codes. Producers often have large numbers of producer codes, and the number may exceed the maximum of what can be sent in a JWT. Therefore, Guidewire recommends that if you have producers accessing ClaimCenter, you always add the producer codes to the JWT through the IExpandTokenPlugin plugin.

For more information on configuring the IdP, see Configuring the IdP.

For more information on registering the caller application with Guidewire Hub, see Registering the caller application with Guidewire Hub.

For information on configuring the IExpandTokenPlugin plugin, see Configuring the IExpandTokenPlugin plugin.