Skip to content

Auth Service

The IDToken Auth Service is the central server that orchestrates the entire X.1280 passwordless authentication protocol. It connects browsers, mobile apps, and relying parties through a trust chain anchored in government-issued VDS credentials.

The Auth Service is the only component that communicates with every other part of the ecosystem:

InteractionChannelDescription
Browser → ServerHTTPS + WebSocketReceives auth requests, pushes real-time session status (OTP ready, approved, rejected)
Server → MobileFCM push notificationDelivers the OTP and session context to the user’s authenticator app
Mobile → ServerHTTPSReceives the signed auth response from the mobile app
Server → Relying PartyJWT / SAML assertionReturns verified identity claims to the requesting service
Server → Trust InfraHTTPSFetches governance lists, trust service lists, and CA certificates for VDS verification

The service registers a user’s VDS credential and device public key. When the mobile app calls POST /enroll, the server:

  1. Verifies the VDS signature by walking the PKI trust chain
  2. Extracts identity claims from the VDS payload
  3. Stores the enrollment: tokenId → device public key + FCM token
  4. Returns a confirmation to the app

No user database is created — the enrollment is simply a binding between the VDS token identifier and the device’s ECDSA public key.

The core X.1280 mutual out-of-band flow:

  1. Browser calls POST /auth/initiate with the user’s token identifier
  2. Server generates a cryptographic OTP (HMAC-based, from master secret + session context)
  3. Server pushes the OTP to the mobile app via FCM
  4. Server sends the same OTP to the browser over WebSocket
  5. User compares codes on both screens, approves on mobile with biometric verification
  6. Mobile app signs the response and calls POST /auth/verify
  7. Server validates the ECDSA signature against the enrolled public key
  8. Server issues a JWT with scope-filtered claims and delivers it to the browser via WebSocket

The one-time password is server-generated and deterministic — not TOTP or HOTP. It is derived from:

InputPurpose
OTP_SECRET_MASTERServer-side master secret (never leaves the server)
sessionIdBinds the OTP to a specific auth session
tokenIdBinds the OTP to a specific user enrollment
timestampTime-limits validity

The OTP is a 6-digit numeric code with a configurable TTL (default: 120 seconds).

Before trusting any VDS credential, the server walks the full PKI chain:

Governance List → Scheme List → TSL → CA Certificate → VDS Signing Certificate

The verification checks:

  • ECDSA P-256 signature over the VDS payload (raw r|s format)
  • Certificate chain validity and expiry
  • Certificate UsageList includes the required usage type
  • VDS revocation status against the VDS Revocation List (VRL)

See Trust Architecture for the full verification process.

After successful authentication, the server issues a signed JWT (ES256) containing:

  • Standard claims: iss, sub (tokenId), aud (serviceId), exp, iat, jti
  • VDS identity claims filtered by the scopes the user granted
  • Derived claims computed from VDS data (e.g., age_over_18, age_over_21)

Relying parties verify tokens using the server’s public key, published at GET /jwks.

The Auth Service can act as a SAML 2.0 IdP for enterprise integrations:

  • Publishes IdP metadata at GET /saml/metadata
  • Handles SSO via GET /saml/sso (HTTP-Redirect binding)
  • Signs SAML assertions with the server’s ECDSA key
  • Maps VDS claims to SAML attributes based on the SP’s attribute mapping configuration
  • Supports Single Logout (SLO)

See SAML 2.0 IdP for integration details.

FeatureImplementation
Rate limitingPer-IP and per-tokenId limits on auth and enrollment endpoints
Helmet headersStrict CSP, HSTS, X-Frame-Options via @fastify/helmet
CORSConfigurable allowed origins
Immutable audit logAll security events logged to an append-only table (UPDATE/DELETE blocked at DB level)
Session expiryRedis TTL enforces automatic session cleanup
Key rotationServer signing keys can be rotated; JWKS endpoint publishes all active keys
Input validationZod schemas on every endpoint; malformed requests rejected before processing

The Auth Service runs behind Cloudflare (TLS termination, DDoS protection, WebSocket proxying) and is containerized for production via Docker Compose.

ResourceConfiguration
Server signing keyECDSA P-256 PEM file (SERVER_PRIVATE_KEY_PATH)
PostgreSQLPersistent volume, automated migrations on startup
RedisUsed for sessions and pub/sub; data is ephemeral (rebuilds from DB on restart)
FCMFirebase service account credentials (FCM_SERVICE_ACCOUNT_PATH)
Health checkGET /health returns server status, DB connectivity, Redis connectivity, trust cache freshness