Skip to content

Integration Guide

IDToken can be integrated into any web application or service. This guide covers the integration options and how to consume IDToken identity assertions.

MethodProtocolBest For
OpenID ConnectOIDC (Authorization Code Flow)Cloud services, SaaS platforms, standard SSO
JWT (direct)REST API + WebSocketCustom web apps, SPAs, mobile backends
SAML 2.0SAML assertionsEnterprise SSO, legacy systems, government portals
Verifiable CredentialsW3C VC (JWT-VC)Digital wallets, eIDAS 2.0, offline verification
JWKS verificationPublic key fetchAny service that receives IDToken JWTs

For cloud services and standard SSO (Google Workspace, Microsoft 365, Slack, etc.), use OpenID Connect — it requires zero custom code on the client side. For custom applications that need real-time session updates (WebSocket), use the direct JWT integration below.

Register your service with the IDToken operator to receive a serviceId and configure:

  • Allowed scopes — which identity data your service can request
  • Default scopes — scopes used when none are specified
  • Service name & logo — displayed to users on the mobile consent screen
  • Privacy policy URL — linked from the consent screen
  • Consent requirement — whether users must explicitly approve

You will also receive a Service VDS — a cryptographically signed credential identifying your service. Using the Service VDS for authentication provides stronger security than a plain serviceId. See Mutual Service Identity for the full benefits.

When a user wants to log in, your frontend calls the IDToken auth server. You can identify your service using either a Service VDS (recommended) or a serviceId (legacy):

// Recommended: initiate auth with Service VDS
const response = await fetch('https://auth.idtoken.example.com/auth/initiate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
tokenId: userTokenId,
serviceVds: SERVICE_VDS_BASE45, // Your Service VDS credential
scopes: ['identity:name', 'identity:age_over_18']
})
});
const { sessionId, autoPassword, wsToken, random } = await response.json();
// Display the OTP to the user
displayOTP(autoPassword);

Connect to the WebSocket to receive the authentication result:

const ws = new WebSocket(
`wss://auth.idtoken.example.com/ws/session/${sessionId}?token=${wsToken}`
);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'approved') {
// User authenticated — verify and use the JWT
const jwt = data.jwt;
verifyAndLogin(jwt, data.hash, data.random);
} else if (data.type === 'rejected') {
showError(data.reason);
}
};

Fetch the server’s public key from the JWKS endpoint and verify the JWT:

// Fetch JWKS (cache this — it changes infrequently)
const jwks = await fetch('https://auth.idtoken.example.com/.well-known/jwks.json')
.then(r => r.json());
// Verify JWT signature (ES256 / ECDSA P-256)
const payload = verifyJWT(jwt, jwks);
// Use identity claims
console.log(payload.idtoken.givenName); // "Jean"
console.log(payload.idtoken.ageOver18); // true

For X.1280 anti-forgery protection, verify the response hash:

expected_hash = HMAC-SHA256(shared_secret, jwt + "|" + sessionId + "|" + random)

The random must match the value from /auth/initiate. If either check fails, the response may be forged.

The JWT idtoken claim contains only the data matching the granted scopes:

{
"iss": "https://idtoken.example.com",
"aud": "https://services.example.com",
"sub": "vds-token-id",
"iat": 1705312800,
"exp": 1705316400,
"scope": "identity:name identity:age_over_18",
"idtoken": {
"tokenId": "vds-token-id",
"givenName": "Jean",
"familyName": "Dupont",
"ageOver18": true,
"trustLevel": 3
}
}

Services should request only the scopes they need — this is both a GDPR data minimization requirement and a better user experience.

Use CaseScopes to RequestUser Sees
Age verification (bar)identity:age_over_18”Over 18: yes/no”
Loyalty programidentity:name”Name: Jean Dupont”
Age-restricted contentidentity:age_over_18, identity:name_initial”Over 18 + J. D.”
Government portalidentity:fullFull identity data
KYC verificationidentity:full_with_photoFull data + photo

These provide a yes/no answer without revealing the underlying data:

ScopeReturnsUnderlying Data NOT Shared
identity:age_over_18true / falseDate of birth
identity:age_rangeBracket (e.g., “26-35”)Date of birth
identity:is_eu_citizentrue / falseNationality code
identity:name_initial”J. D.”Full name

For enterprise environments using SAML-based SSO, IDToken acts as a SAML Identity Provider. See the SAML 2.0 IdP page for full details.

Quick setup:

  1. Obtain the IDToken IdP metadata: GET /saml/metadata
  2. Import the metadata into your SAML Service Provider
  3. Register your SP with the IDToken operator (entity ID, ACS URL, signing cert)
  4. Users authenticate via the standard X.1280 flow; the result is delivered as a SAML assertion

Services should handle token revocation gracefully:

  • IDToken JWTs have a configurable expiry (default: 1 hour)
  • For long sessions, periodically re-authenticate
  • The tokenId is the stable user identifier — if an enrollment is revoked and re-issued, the user gets a new tokenId
  • Services do not need to take action on revocation — the auth server blocks authentication for revoked tokens automatically