JWKS (JSON Web Key Set) Overview

What is JWKS?

JSON Web Key Set (JWKS) is a standard format for sharing public keys. It enables secure communication by allowing third parties to verify the authenticity of JSON Web Tokens (JWTs) signed by our system.

How it works in inTandem

In our inTandem platform, partner applications are embedded as iframes within our system. When these embedded apps need to send requests, they communicate with the platform using the getAuth method from the inTandem SDK.

Key Steps in the Flow:

  1. Token request via SDK:

    • The app uses the inTandem SDK to call the getAuth method.
    • The platform processes this request and generates an authentication token (JWT) for the current user.
  2. Token usage by the app:

    • The app receives the JWT and includes it in its API requests to its backend.
    • The app's backend retrieves an array of available public keys from the JWKS URL (https://api.vcita.biz/v3/apps/.well-known/jwks.json):
    {
      "keys": [
        {
          "kty": "RSA",
          "n": "wHSBMHlg4BdlCulSMChQgKd0NUTTlUqocEFPvavVvtHK7TxX5zFuMK6mXghhRSfj8lfygJvXQZfrm5QpM7ZuhCZR4BfWNkHOwhIQ6JYR4zuPI63shu7t11l6kzZebrR8AYJURnDXEjqmqd0UXIWQmscYN4b_tPcJR9Y0xXZRWig_n08ktd9ojUfq08LyhsPNhHjBJUB0VC53OVDVDTg1nWZ4idwgVPZRHeq4aqc5J-Fl2ZtnBIhsl3RgdV_2OwQbPVxYFHh4kksTJRZ9xWPatWimNyBGNhaB1SUAN05fPaB0yl7A0uiQG3tYHCS5AKSahJRtYFP22CODQ-jKLCFhjQ",
          "e": "AQAB",
          "use": "sig",
          "kid": "ab60a3bb-6b50-4dd0-bdfd-3799cf65a817",
          "alg": "RS256"
        },
        {
          "kty": "RSA",
          "n": "sI6WtMIGh2ElGwH8LKRoTYxqrTp2-eCHn_N3IhbR1fGgyiDUBoFN5hFcQ4ggjsAIGcp8_ng-nSfZXPl02lDhhB3KCQ62NYatzITkBD8Q7xak1o6RVH8Ttz8WB0zOI7RhAHnvga43OvzmzD4CH8VMhn1Gtro3hPAU2am0XOO2DkYfA5jiupuGV4ipyg0tessUYknW9X_BlVoRIbkSqhlU3tG6Grc0HQO-19ycI1OvB5O0x-BfBATeRYU3gQ7ZE5muZhVIBVfIlOl727D2TWCoPAORK-LepQvRCYI8DayhzfWPFbbdE_XBGT3nBv1tTEe2IrszwQzx2REjwJ5oCGQR3w",
          "e": "AQAB",
          "use": "sig",
          "kid": "535bce9a-ce95-4a48-80e8-a0460b4c4c56",
          "alg": "RS256"
        },
        {
          "kty": "RSA",
          "n": "t7thhiuY1lhrbzKpn4rMXrh2mNqVxWBAxFJ4-SkzX-DmHLFayilwFzi-0oYnZDl51Ua1x5pGucjrLVZjNMlDB-gw5af88p7dtcw1auXB-nbCsL41-3x314tNbVes90yALHbbnvN5v4K22fDNPsyc_35GPefH_L4FQK1HkStZkvLQ-jfXKOEEJoFtymRohCFI1JhppwcxDUJ_YoKP6wjQGbFLvd58cwbPqWH76JqYenjag_YLdUKqlbCaRbuyUDIY1_1WK0xuyPEaD-6peGPTwHVkonWvHV5_bbr-2DgLgK_-JI4DsFW_WG_ddEiLR3FKf6ihaGIbpgvZ4yA5DmJoxw",
          "e": "AQAB",
          "use": "sig",
          "kid": "c9452140-8399-49b5-8ca6-c9a9c967ca50",
          "alg": "RS256"
        }
      ]
    }
    

  3. User validation and security:
    To clarify the JWKS (JSON Web Key Set) authentication process, here's how each step works:

    1. Check the kid property of the token:

      • The kid (key ID) is part of the JWT header. Your backend will check this kid to find the corresponding public key in the JWKS. This ensures you're using the correct public key to verify the token's signature.
    2. Validate the signature:

      • Once the correct public key is identified, your backend uses it to verify that the incoming token was signed by the corresponding private key. This ensures the token hasn't been tampered with and is authentic.
    3. Check the aud (audience) property:

      • The app's backend checks the aud claim in the token to confirm that it is meant for your specific application. This ensures that the token is intended for the right audience (i.e., your app).
    4. Check the sub (subject) property:

      • The backend also verifies the sub claim to ensure the token is meant for the specific user or staff member it represents. This confirms that the token is associated with the correct individual.
        By following these steps, you ensure that the token is authentic, valid for the correct audience, and represents the intended user, maintaining the security of your application.

Security measures:

  • Key rotation: Public and private keys are rotated periodically to minimize the risk in case of key leakage.
  • Short-lived tokens: Authentication tokens have a short lifespan and can be revoked to enhance security.

Implementation notes

  • Public keys are updated every month. It is recommended you cache the call for public keys.
  • If validation fails due to a mismatch kid, just re-fetch the public keys from the inTandem authentication service.

Why use JWKS?

  • No private key sharing: The private key remains secure within our system, while only the public key is shared.
  • Token integrity: Ensures the token hasn’t been altered or tampered with.
  • Ease of integration: Third-party systems can easily fetch and use our public key from the JWKS URL.

By using JWKS, inTandem ensures secure and reliable communication between our platform and third-party systems, maintaining a robust security model and streamlined developer experience.

Relevant reference documentation

Code sample

import { decodeJwt, jwtVerify } from 'jose';
import axios from 'axios';

async verify(token: string): Promise<JWTPayload> {
  const response = await axios.get('https://api.vcita.biz/v3/apps/.well-known/jwks.json');
  const { keys } = response.data;
  const decodedJwt = decodeJwt(token);
  if (!decodedJwt.kid) {
    throw new Error('No kid in token header');
  }

  const matchingKey = keys.find((key) => key.kid === decodedJwt.kid);
  if (!matchingKey) {
    throw new Error('No matching key found');
  }

  const verifyResult = await jwtVerify(token, matchingKey);
  return verifyResult.payload;
}

More information and reads

A great resource to read more about JWKS and related concepts is the RFC 7517, which provides an in-depth explanation of the JSON Web Key (JWK) standard.

Additionally, you can explore the following resources:

Auth0 Blog - JSON Web Keys (JWKs): https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets - A developer-friendly guide that explains how JWKS is used with JWTs.
Okta Developer Docs: https://developer.okta.com/docs/concepts/jwks/ - A practical breakdown of JWKS implementation and its importance in API security.
JWT.io: https://jwt.io/ - This interactive tool helps you inspect, decode, and learn more about JWTs, often used with JWKS.
These references should provide you with both foundational knowledge and real-world use cases. Let me know if you'd like a deeper dive into any of these concepts!