Mobile installation using signed metadata with JWT

Last Updated:

Note: This functionality must be enabled by a Pendo representative. Contact Pendo Support to request access.

With a typical mobile application installation, the mobile device passes metadata directly to the Pendo servers as a JSON object. All data exchanged between your application and Pendo is encrypted and transferred using Security Sockets Layer (SSL) protocol. Some industries require additional reassurance that metadata was not tampered with in-flight. Signed metadata is used to add a JSON web token (JWT) to your metadata and validate that it was not altered and did not originate from a source other than your specific mobile device.

Note: This is optional and not necessary for most installations. It adds additional complexity and may result in data loss if implemented incorrectly.

When using signed metadata in conjunction with the mobile installation, metadata passed to the Pendo servers must be contained in a signed token used to verify the integrity of the claims contained within it. This will not hide the claims from other parties. This is addressed with standard data encryption, but the signature is used to verify that the message wasn’t changed along the way.

This is not encryption. Think of it as a hotel key. You register at the front desk and they give you a plastic electronic key (or token) with which you can access your room, the pool, and the garage. But you can't open other people's rooms or go into the manager's office. You can only access your rooms using your key and nobody else can access your rooms without your key. And, like a hotel key, when your stay has ended, you're simply left with a useless piece of plastic. The token doesn't do anything after it has expired.


  • Active signed metadata access
  • Subscription admin access
  • An engineer who can modify the mobile application containing the Pendo SDK
  • An engineer who can generate JSON web tokens (JWT) and send them to devices containing the mobile application

Configuring your application to accept signed metadata

Signed metadata must be active for your subscription for Advanced Security settings to be visible. Contact your Pendo representative if Advanced Security isn't available. You must enable Use signed metadata for your subscription to accept data with JWT. If this setting is not enabled and you attempt to send signed metadata, it will be dropped.

  1. Navigate to Settings > Subscription Settings.

  2. Open the Applications tab.

  3. Find and open the relevant app from your Applications list.

  4. Open the Install Settings tab.
  5. Select Enable next to Use signed metadata

  1. Update your mobile installation to transmit signed metadata. Don't complete the following steps until you are sending signed metadata:
    • If Use signed metadata is enabled, we will accept either metadata with or without JWT.  
    • If Only allow signed metadata is enabled, we will only process events that have a verified signed JWT.
    • If Use signed metadata is disabled, we will not accept events with JWT. 
  2. When your mobile installation is updated and successfully transmitting signed metadata, enable Only allow signed metadata.

  1. Confirm that you want to only allow signed metadata. This drops all events without signed metadata, as intended. Dropped data cannot be recovered.


 Generate Key

This key is used to sign your metadata. You can create up to five active keys per application. When set up is complete, your application only accepts data that's transmitted with one of your five active keys.

  1. Navigate to the Active Keys table in Install Settings and select Generate Key.

  2. Enter a description to help you identify your keys later. Select Create to add a new key.

  3. The key is now available in the Active Keys table. Keys are hidden by default. Select Show to see the key.


 Pendo mobile installation

Pendo signed metadata requires the use of JSON Web Tokens (JWT). JWT is an open, industry standard method (RFC 7519) for representing claims securely between two parties. There are many libraries out there that can be used to generate and sign JWTs.

There are a couple requirements to keep in mind when generating the JWT.

  • A "nonce" property must be included in the claims. The nonce is a string randomly generated by the client and must be at the top level in the JSON, as a sibling property to "visitor" or "account", not contained within one of those sections. The value isn't explicitly validated, but a value is required. Including a random nonce helps ensure that tokens always appear different even if they contain the same claims.
  • The HMAC SHA-256 algorithm should be used when signing the JWT. If the JWT isn't signed with this algorithm, Pendo won't be able to verify the signature and the events won't be processed.

Example of a JWT generation on your server side:

jwt = JWT.sign({

        id:             'VISITOR-UNIQUE-ID' // Required field, must be a string
      // email:       // Recommended if using Pendo Feedback, or NPS Email
       // full_name:   // Recommended if using Pendo Feedback
      // role:        // Optional
      // You can add any additional visitor level key-values here,
      // as long as it's not one of the above reserved names.

 account: {
      id:           'ACCOUNT-UNIQUE-ID' // Required field, must be a string
      // name:         // Optional
      // is_paying:    // Recommended if using Pendo Feedback
      // monthly_value:// Recommended if using Pendo Feedback
      // planLevel:    // Optional
      // planPrice:    // Optional
      // creationDate: // Optional
      // You can add any additional account level key-values here,
      // as long as it's not one of the above reserved names.

   nonce: 'randomly generated value'  // It should be different every time it is used
'JWT-SECRET-KEY' // Generated key


To send signed metadata, the mobile application must obtain the JWT and key ID from your server side. The JWT containing the metadata must be signed with the generated key corresponding to the key ID. Once the signed JWT is generated and obtained by the mobile device, the JWT and the key ID are sent to Pendo’s servers instead of sending the metadata as a raw JSON body. Pendo verifies that the JWT hasn't been tampered with and doesn't process any events that are sent with an invalid JWT. You can send the JWT and key ID in your mobile application by passing them to the Pendo.jwt.startSession call as the jwt and signingKeyName argument properties. The call to Pendo.jwt.startSession should be called after calling Pendo.setup.

Example of an android mobile device sending the JWT to Pendo (Java):

Pendo.setup(this, pendoAppKey, null, null);

String jwt = “JWT-SIGNED-TOKEN”; // obtained from your server

String signingKeyName = “SECRET-KEY-ID” // obtained from your server
Pendo.jwt.startSession(jwt, signingKeyName);

Example of an iOS mobile device sending the JWT to Pendo (Swift):

PendoManager.shared().setup(pendoAppKey, nil);

let jwt = “JWT-SIGNED-TOKEN”; // obtained from your server
let signingKeyName = “SECRET-KEY-ID” // obtained from your server
PendoManager.shared().jwt.startSession(jwt, signingKeyName);


Exchange and revoke the JWT secret key

To revoke a previously used JWT secret key, a new key must be generated on the Install Settings page. Once the new key is properly inserted, the previous key is revoked.

Warning: If an active key is revoked before the snippet is updated with the new key, data is not processed until the JWT sent to Pendo is signed with the new key.

To revoke a key, select the Revoke Key icon when hovering over the key, then accept the confirmation to revoke the key permanently. This cannot be undone.

You can find a log of all Revoked Keys underneath the Active Keys section.



Additional configurations

Can I use signed metadata and track anonymous visitors?

Anonymous visitors are automatically assigned a random string as a visitor ID when Pendo.jwt.startSession is called with an empty string assigned to the visitor ID as part of the metadata. This method of generating anonymous visitor IDs is the same for a conventional or signed metadata Pendo installation. Anonymous visitors should still use JWT when they pass event data to Pendo.

Example of an anonymous visitor JWT generated on your server side:

const jwt = JWT.sign({
    nonce: "abcdefg78910xyz",

    visitor: {
        existingVisitorField: "some value"

   account: {
  id: "",
       otherAccountField: "some other value"

Identifying anonymous visitors

If you identify visitors with their unique visitor ID after initializing with an anonymous ID, call Pendo.jwt.startSession again with a JWT containing the updated visitor ID and metadata as needed. This function works the same as a conventional Pendo installation.

Can I updates visitor data during a session?

Visitor data can be accumulated / updated during the session by calling Pendo.setVisitorData and / or Pendo.setAccountData. When using these calls pass a JWT and key ID similarly to the Pendo.startSession. However, the JWT payload with these calls must meet the following criteria: 

  • The payload must contain either a visitor property or an account property but not both.
  • The ID value supplied for either the visitor or account must be identical to the ID value used in the JWT passed when calling the Pendo.jwt.startSession.

Example of an a JWT generated to update the visitor data:

const jwt = JWT.sign({
  nonce: "abcdefg78910xyz",

    visitor: {
  newVisitorField: "new value",
        existingVisitorField: "updated value"

Example of an a JWT generated to update the account data:

const jwt = JWT.sign({
    nonce: "abcdefg78910xyz",

   account: {
  newAccountField: "new value",
        existingAccountField: "updated value"


Does signed metadata help prevent replay attacks?

Pendo drops any duplicate events it receives, preventing malicious users from replaying the same event over and over. Signed metadata using JWT does not support the “jti” claim, commonly known as a way to prevent replay attacks. A signed metadata JWT remains valid as long as the signature is valid. Revoking and exchanging tokens on a regular basis is the best way to prevent long lived JWT tokens from being exploited if compromised. 

Was this article helpful?
0 out of 0 found this helpful