# JWT Enrichment

{% hint style="info" %}
JWT Enrichment is commonly used to support use cases for which a backend application needs information stored about the Subscriber's subscription in Revenium to determine which information how to reply to a subscriber query. For example, you could use JWT enrichment to enhance a Subscriber's API call with their company name or email address to allow a backend application to match the call to a subscriber license and determine which fields to return in the API call (i.e. fields tied to a 'premium' subscription versus a 'standard' subscription'
{% endhint %}

By incorporating a custom JWT claim into metered API requests, Revenium propagates the following metadata to backend API implementations:

| Field                   | Description                                                                |
| ----------------------- | -------------------------------------------------------------------------- |
| organization            | The organization the invoked API / product belongs to.                     |
| consumingOrganization   | The organization of the API subscriber                                     |
| subscriber              | The email address of the API subscriber                                    |
| product                 | The name of the product the API belongs to                                 |
| productTags             | The tags associated with the product                                       |
| subscriptionTags        | The tags associated with the subscription                                  |
| productVersion          | The version of the product the API belongs to                              |
| sources                 | The other sources associated with the product the API belongs to           |
| expiration              | The expiration date of the subscription associated with the API subscriber |
| totalQuota              | The quota associated with the product being invoked                        |
| consumedQuota           | The amount of quota being subscribed.                                      |
| subscriptionStart       | The start of the subscription                                              |
| subscriptionPeriodStart | The start of the current subscription period                               |
| subscriptionPeriodEnd   | The end of the current subscription period                                 |

The JWT claim is propagated in the "X-HYPERCURRENT-CLAIM" header which can be parsed by the backend API implementation using any standard [JWT Library](https://jwt.io/).

Here is an example of a decoded Revenium JWT claim:

```json
{
  "consumedQuota": 0,
  "product": "An API Product",
  "productTags" [
    "tag1",
    "tag2"
  ],
  "productVersion": "1.0.0",
  "assets": [
    "TA01"
  ],
  "organization": "Test Organization",
  "iss": "Revenium",
  "expiration": null,
  "totalQuota": 5000,
  "consumedQuota": 200,
  "consumingOrganization": "Test Organization",
  "consumer": "gerry@hypercurrent.io",
  "subscriptionStart": 1700168904000,
  "subscriptionPeriodStart": 1700168804000,
  "subscriptionPeriodEnd": 1700168904000
}
```

{% hint style="info" %}
Here is Revenium's public key for JWT decoding:

```clike
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmXwrndxL7l1a3ULqTUCQ
/4uM3MjJE2RgEYlStBz4mqjgCmfFF4AMXqZSkNewiB0XlcpRlqmLYsyMok87Y6Du
Fco5isZn5ndrE2lOK3vveyEPqEMJW5yVot29IGWAn1yRXAXwI/LpZ7G6gYHerNOS
LWj3utEzuWKcTIGMjwNWTAK9nmZJLuzz3+I9D6HwVq6IAQKrLiA8GzABqVgKMPgu
nGtJhQ1iAc4WSuHl0f/xFdwZLi3FiAETayl2lGptCpLu+UOawQGo+r5metwczR1Q
RFr7mmbUqQ1HSrDax9KmHtNIhGzP6FOmH3DeEIf3ATEz0K+iXz/fencXix4PRrRP
TwIDAQAB
-----END PUBLIC KEY-----
```

{% endhint %}

### JWT Parsing Example (Java)

The following code snippet uses the [Auth0 JWT library](https://github.com/auth0/java-jwt) to decode and parse a JWT:

```java
String base64PublicKey = publicKey
        .replace("-----BEGIN PUBLIC KEY-----", "")
        .replace("-----END PUBLIC KEY-----", "")
        .replaceAll("\\s", "");

byte[] publicKeyDER = Base64.getDecoder().decode(base64PublicKey);

X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyDER);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKey publicKeyInstance = (RSAPublicKey) keyFactory.generatePublic(keySpec);

// Construct the JWT verifier
Algorithm algorithm = Algorithm.RSA256(publicKeyInstance, null);
JWTVerifier verifier = JWT.require(algorithm)
        .withIssuer("HyperCurrent")
        .build();

// Decode the JWT
DecodedJWT jwt = verifier.verify(token);

// Extract claims
jwt.getClaim("organization").asString();
jwt.getClaim("consumingOrganization").asString();
...
```
