Skip to content

SSO Integration

SDK - SSO Integration Instructions

When Hubble’s SDK is invoked, we create a proxy user in our system and all API calls happen against the session generated for that user. SSO is how you pass the logged-in user’s identity to Hubble.

JWT SSO

The partner signs a short-lived JWT on their backend. The partner frontend passes that JWT to the SDK, and Hubble verifies it locally using the partner’s pre-registered public key. No inbound /sso endpoint is required on the partner side.

Flow

  1. The partner backend creates a short-lived JWT for the logged-in user.
  2. The partner frontend passes that JWT as the token field when initialising the SDK.
  3. Hubble reads iss to identify the partner, verifies the JWT signature, validates claims, and creates the user/session.

Security Model

Hubble uses an asymmetric key approach, the partner signs tokens with a private key that never leaves their infrastructure, and Hubble verifies them using the partner’s public key registered during onboarding.

Who holds itWhat it does
Private KeyPartner’s backend onlySigns the JWT, must never be shared or exposed
Public KeyShared with Hubble onceUsed by Hubble to verify the JWT signature

A few things the partner should always ensure:

  • The private key lives only on the partner’s backend server, it must never be checked into version control, logged, or transmitted anywhere
  • Tokens are signed using RS256 (RSA Signature with SHA-256), no other algorithm is accepted
  • Every token must be generated fresh on each request with an expiry of exactly 60 seconds (exp = iat + 60)

⏱️ Why 60 seconds? Each token is single-use for the SDK handshake. A short expiry window ensures that even if a token is intercepted, it cannot be replayed. The partner must never cache or reuse tokens, always generate a new one each time a user opens Hubble.

One-time Setup: Generate a Key Pair

The partner needs two keys: a private key (stays on the partner’s server forever) and a public key (shared with Hubble once during onboarding). Use openssl to generate a 2048-bit RSA key pair:

Terminal window
# Step 1 — Generate the private key
openssl genrsa -out private_key.pem 2048
# Step 2 — Extract the public key from it
openssl rsa -in private_key.pem -pubout -out public_key.pem

What goes inside the JWT?

Every JWT the partner generates must include these fields:

FieldWhat to put here
subThe partner’s internal user ID
issThe partner’s Hubble clientId (provided during onboarding)
iatCurrent timestamp (Unix)
expExpiry timestamp — always iat + 60 seconds
phoneNumberUser’s phone number with country code

The partner can also include these optional fields to enrich the user’s profile in Hubble:

FieldWhat it’s for
nameUser’s display name
emailUser’s email address
cohortsGroups the user belongs to, used for offers/eligibility (e.g. ["premium", "beta"])

Example JWT Payload

{
"sub": "user_123",
"iss": "partner-client-id",
"iat": 1711929600,
"exp": 1711929660,
"name": "John Doe",
"email": "john@example.com",
"phoneNumber": "919999912345",
"cohorts": ["premium", "beta"]
}

Signing Examples

# pip install PyJWT cryptography
import datetime
import jwt
with open("private_key.pem", "rb") as f:
private_key = f.read()
now = datetime.datetime.now(datetime.timezone.utc)
payload = {
"sub": "user_123",
"iss": "partner-client-id",
"iat": now,
"exp": now + datetime.timedelta(seconds=60),
"name": "John Doe",
"email": "john@example.com",
"phoneNumber": "919999912345",
"cohorts": ["premium", "beta"],
}
token = jwt.encode(payload, private_key, algorithm="RS256")
print(token)

Onboarding

  • Generate an RSA key pair using the openssl commands above
  • Receive the clientId from Hubble via the Integration Portal to use as the iss claim in your tokens.
  • Submit the contents of public_key.pem on the Integration Portal
  • Once configured, the partner can start issuing tokens immediately

Classic SSO (Legacy)

When Hubble’s SDK is invoked, we need to create a proxy user in our system. All our API calls would be happening against the session id we generate for this proxy user.

To create this proxy user, we require our partners to expose an API through which we can get user’s details.

Some of the mandatory user fields we require are

  1. User’s id
  2. Name
  3. Phone number

These are mandatory because we need to pass this to some of the services that power Hubble.

In the frontend, your application can pass to our SDK some code or token that uniquely identifies the user.

When the SDK is initialised,

  1. Our backend will get the token
  2. Make a call to the above requested API to get the user details
  3. Create user and session and return the session id for our SDK to start voucher workflows.

API Request/Response

Request

POST /sso

Headers:

  • X-Hubble-Secret (string, required) — Pre-shared secret provided during onboarding

Body:

  • token (string, required) — SSO token generated by the partner system. Token validation logic is fully owned by the partner.
{
"token": "<your-token>"
}

Response (200 OK):

{
"userId": "test-user-123",
"email": "testuser@example.com",
"firstName": "Test",
"lastName": "User",
"phoneNumber": "1234567890",
"cohorts": ["premium", "beta"]
}

Response Fields:

  • userId (string, nullable) — Partner’s unique user identifier. Must be present for a valid token.
  • email (string, optional)
  • firstName (string, optional)
  • lastName (string, optional)
  • phoneNumber (string, optional)
  • cohorts (array of strings, optional) — Logical user groups used for segmentation, eligibility, or feature access.

Invalid Token Response (401 or 400):

If the token is invalid or expired, return:

{
"userId": null
}

Returning userId = null indicates authentication failure.

Example:

Terminal window
curl -X POST "https://partner-api.example.com/sso" \
-H "X-Hubble-Secret: your-secret-key" \
-H "Content-Type: application/json" \
--data '{"token": "sso-token"}'

Note: The partner is expected to implement this interface and share the base URL with our team. Our system will invoke the /sso API endpoint using the provided base URL.

Sequence Diagram

SSO sequence diagram