Skip to content

Security Model

IDToken’s security model is designed to resist the most common attack vectors against authentication systems while providing strong identity assurance through cryptographic and biometric verification.

ThreatMitigation
OTP phishingOTP is presented by the service — fake services cannot generate a matching OTP without the server HKDF master secret
Replay attackSingle-use sessions; timestamp checked within ±30s; session deleted after resolution
Brute force OTPMax 3 verify attempts per session; session invalidated after 3 failures
Stolen mobile deviceid3 face verification prevents unauthorized use (thief’s face won’t match VDS photo); tokenId revoked on loss report
Fake IDToken VDSECDSA P-256 signature + full PKI chain verification (VDSIC Governance to CA)
Compromised issuance stationStations never call BioSeal directly — the IDToken server verifies ICAO SOD + Active Auth proof before forwarding to BioSeal; BioSeal credentials held only by the server. See Issuance Integrity.
Expired credentialexp field checked on every enroll and auth; CRL checked at enrollment
Man-in-the-middleTLS mandatory; FCM data channel E2E encrypted; mutual authentication via OTP
Server response forgeryHMAC-SHA256 hash over response data (X.1280 §3.3 anti-forgery); relying party verifies hash and random nonce
JWT forgeryECDSA P-256 signed; relying services verify with server public key via JWKS
OTP on lock screenFCM uses data field only — OTP never rendered as a system notification
Private key extractioniOS Secure Enclave / Android Keystore — hardware-bound, non-exportable
Revoked VDSVDS fingerprint checked against VRL (VDS Revocation List) from Trust Service List
Scope inflationGranted scopes cryptographically bound to ECDSA signature — cannot be modified after user approval
PurposeAlgorithmKey Size
VDS signaturesECDSA P-256 (raw r|s)256-bit
JWT signingES256 (ECDSA P-256)256-bit
OTP derivationHKDF-SHA256 + HMAC-SHA256256-bit
Response verificationHMAC-SHA256256-bit
Mobile device keyECDSA P-256 (Secure Enclave / Keystore)256-bit
SAML assertion signingRSA-SHA256 or ECDSA-SHA2562048-bit / 256-bit
SAML encryptionAES-256-CBC + RSA-OAEP256-bit / 2048-bit
VDS payload encodingMessagePack
VDS hashSHA-256256-bit

The OTP is session-scoped (not a global TOTP) to prevent phishing and replay:

1. Derive session key:
session_key = HKDF-SHA256(
ikm = master_secret,
salt = tokenId,
info = sessionId
)
2. Generate OTP:
window = floor(now / 30_000) // 30-second window
raw = HMAC-SHA256(session_key, window + sessionId)
otp = (parseInt(raw[0:8], "hex") % 10^6).padStart(6, "0")
3. Verification accepts window ±1 (±30s clock skew)

The mobile app signs: sessionId|otp|timestamp|grantedScopes

The server verifies using the public key stored at enrollment. The granted scopes are part of the signed message, so they cannot be modified after biometric approval.

These rules apply across all components — server, mobile app, and BioSeal issuance:

  • OTP is never stored in plaintext — only SHA-256(otp) is persisted
  • OTP is never included in audit log details
  • Server private key is never logged or returned in any API response
  • App private key never leaves the secure element
  • Sessions are invalidated immediately after first resolution
  • POST /revoke requires a valid admin-scoped JWT
  • All API traffic uses HTTPS / TLS 1.2+ in production
  • Push notifications are delivered as silent data messages — never shown on lock screen
  • CORS restricted to allowlisted origins
  • Security headers enforced: CSP, HSTS, X-Frame-Options
  • WebSocket connections authenticated via wsToken (HMAC-SHA256)
EndpointLimitWindowScope
POST /auth/initiate101 minutePer IP
POST /enroll51 hourPer IP
POST /auth/verify3Per sessionPer sessionId

All security-relevant events are logged to an immutable audit table in PostgreSQL:

  • INSERT-only (UPDATE/DELETE blocked by PostgreSQL rules)
  • Indexed on token_id, event_type, occurred_at
  • OTP values never stored in plaintext
  • Client IP and user agent captured per event
  • Events include: ENROLL, AUTH_INITIATE, AUTH_APPROVE, AUTH_REJECT, REVOKE, VDS_VERIFY_OK/FAIL, SAML events, consent decisions, admin actions
LayerMechanism
EdgeReverse proxy with TLS termination, DDoS protection, and WebSocket proxying
TransportTLS 1.3 (HTTPS + WSS)
SecretsPrivate keys and master secrets injected at runtime — never baked into images
Key rotationOTP master secret supports dual-active secrets during transition
LoggingStructured JSON logs piped to a log aggregator
MonitoringHealth endpoint polled by orchestrator and external uptime monitor