Revision History¶
| Version | Date | Changes |
|---|---|---|
| 8.0 | June 2026 | Full reorganization for a feature-builder — 21-section layout grouped into six Parts (Orientation / Platform Foundations / Capabilities / Interfaces & Reference / Build & Operate / Appendix). No capability content was dropped; the only intentional removal is the KYC integration detail (below). New consolidated sections: • §5 Data Model — single canonical home for every entity schema (users, tenant, console_users, oauth_clients, refresh_tokens, webhook_endpoints, devices, challenges, device_transactions, linked_services, consent_records, audit_log, kyc_data hooks, platform_secrets) plus the data-separation diagram and palm namespace/model notes. Absorbs the old §5 User Model and §16 Data Architecture. Entities the prior spec never schematized (e.g. refresh_tokens fields) are flagged ⚠ Open Question rather than invented.• §10 Linked Services & Device Transactions (Broker) — merges the old §4.9 registry and the old §11.8 broker into one feature section. • §15 Error Reference — merges platform HTTP errors (old §13.4), palm-vendor codes (old §19.7), Nafath status (old §19.8), and previously-inline codes ( tenant_suspended, consent_required, palm_type_restricted).• §16 Event Reference — unifies the audit catalog (old §10.3.2) and the webhook catalog (old §11.5) into one table mapping each business event to its audit + webhook names. Moves: old §11 Outbound Integrations split into §10 (broker) and §12 Webhooks; webhook signing-secret lifecycle relocated from old §6.5 to §12.3; user lifecycle moved to §13.5; product context folded from the old appendix into §1 (capabilities → §1.5, out-of-scope → §1.4); palm/Nafath error codes moved out of the appendix into §15. Added a terminology-disambiguation note to §2. KYC reduced to a [POST-MVP] stub (§7). Removed the un-architected detail (port interface, session/result schemas, provider config, KYC APIs, Nafath flow, the §20 KYCProvider/Nafath code examples, and the detailed KYC Data Schema). Retained all live hooks: kyc_* settings (§4.5), kyc_status/kyc_data (§5.5), enrollment gating (§13.2), KYC audit/webhook events (§16), and the /v1/kyc/* endpoints (§14.1, tagged [POST-MVP]).Cross-references: every live in-document § reference was remapped to the new numbering and the Table of Contents + anchors regenerated. The revision-history entries below are unchanged — their section numbers are point-in-time records of the layout at each version. Companion diagram cross-references to PRD sections were updated separately; the diagrams file was not reordered, and the KYC sequence (diagrams §3) is left for a follow-up.Post-restructure reconciliation: added id to linked_services (§5.4); generalized device_certs_bulk_revoked to also cover tenant-scoped forced rotation (§16 / §9.2); cataloged review_case with a ⚠ schema flag (§5); made §8.13 the canonical palm-model definition; tagged KYC [POST-MVP] in §1.2 / §1.3. Subsequent passes improved readability of the densest sections (§8.13, §9.2.1, §9.2.2, §4.6, §4.7, §5.2, §8.3) and moved inline version-history into this changelog — removed the §9.1 "Changed in v7.0" callout, de-tagged §4.7 and the companion diagrams' "New in vX" notes; the body now reads present-tense. |
| 7.2 | June 2026 | Palm model (small vs large) + small→large migration. Documented that X-Telcom BioWave ships as two deployment-wide palm models and the existing /KZ/* flows are the large model only.§8.13 Palm Model (Small vs Large): small model = device client SDK matches at the verification server directly and the platform records a device-trusted boolean ( user_id + pass/fail), platform outside the matching path; large model = server-to-server /KZ/* with palm_match_policy. Added a feature-applicability table (marks §8.4 score model, §8.10 duplicate detection, §8.11 restrictions, §8.12.2 thresholds large-model-only) and made the platform-side behavioral switch explicit — the active model selects how every device-facing palm endpoint (/v1/device/transactions, /v1/device/enroll, challenge /v1/verify + /v1/enroll + /complete) is handled (results vs scans).§8.14 Small→Large Migration: platform-orchestrated, one-way; a configured verification-server endpoint lets the platform run the vendor-supplied migration script against the verification server (reprocesses stored RGB+IR — no re-enrollment), then atomically switches the deployment's model. §13.2: added GET /v1/admin/palm/model, GET/PUT /v1/admin/palm/verification-server, POST /v1/admin/palm/migrate. §13.1: noted device-facing palm endpoints differ by model. §11.8: small-model broker branch (device brings matched user_id; platform skips its own identify). §10.3.2: added palm_model_changed, palm_model_migration_started/completed/failed; qualified identification / verification_complete with source. §16/§17: deployment = platform + paired verification server; model + verification-server endpoint stored deployment-level. Qualified §8.4 / §8.9 blanket statements with "large model".Companion diagrams bumped to v2.9: added §4.5 (small-model device transaction — SDK-direct match, platform records + authorizes) and §9.3 (small→large migration); disambiguated §4.3 / §4.4 as large-model paths; fixed §9.2 threshold-diagram drift (10→4, pre-existing from the v7.0 10→4 score-model change). |
| 7.1 | June 2026 | Removed automatic OAuth client creation at tenant provisioning. §4.4: dropped the step that auto-minted the first OAuth client (client_id + client_secret); renumbered. §13.2: POST /v1/admin/tenants no longer returns a "first OAuth client" (only tenant_id + first Tenant Admin credentials). Clients continue to be created via the existing POST /v1/clients endpoint (§6.4; §13.1) — API or Web Console. |
| 7.0 | June 2026 | Device-initiated palm flows + Linked-Service Broker — major: reverses device ownership and removes the public /v1/identify endpoint.Device ownership reversed (§9): POS/gate/kiosk devices are now Identity-managed (same pairing/mTLS/revocation lifecycle as personal scanners), not vertical-managed. Added device_class and §9.3 Device → Product Binding (bound_product/bound_action). Rewrote §9.1; generalized §9.2 from "Personal Scanner" to all device classes.§11 renamed Webhooks → Outbound Integrations: added §11.8 Linked-Service Broker — synchronous device→Identity→product authorize call returning an in-band allow/deny; identity_assertion JWT (JWKS-verified, no stored secret); timeout / circuit-breaker / fail_mode (default closed); idempotency + jti replay. Demoted identification.complete to audit-only; added device.transaction.completed.§13 API: added POST /v1/device/transactions, /v1/device/signup, /signup/verify, /consent, /enroll (all mTLS), /v1/linked-services CRUD, and PUT /v1/devices/{id} binding. Removed public /v1/identify (now an internal broker step). §13.4 swapped the identify response for the device-transaction response (no user_id returned to the device).Tenancy (§4): Link Wallet + Link Access are now products within one Link Holdings tenant (shared user + palm namespace — "enroll once, used everywhere"); §4.6/§4.7 reconciled; resolved the §4.7 open question on vendor-namespace isolation via per-tenant namespace prefix. Added §4.9 Linked Services registry. Account/palm split (§5, §12): account keyed by mobile, palm_enrolled surfaced cross-surface; added POS signup mode; rewrote §12.2 enrollment paths (consent device/app-direct) and §12.3 transaction flow (device-direct broker). Pinned verify (1:1) vs identify (1:N) in §8.§16 Data: added linked_services and device_transactions tables; extended devices.Companion diagrams bumped to v2.8: removed legacy §4.1/§4.2 (old kiosk-enroll / POS-identify, superseded); added device-initiated broker transaction (§4.3) + device enrollment (§4.4); §4 renumbered; all palm sequences rewritten to the BioWave /KZ/* API.Palm vendor swap: removed Link-HF-Verification / HF Security (and the Suprema/Fujitsu alternatives); X-Telcom BioWave Pass is now the sole palm vendor. §8.4 score model 10→4 elements (IR/RGB × large/small); §8.5/8.6 examples updated; §19.7 error table replaced with the X-Telcom set (no-match is now platform-side); §8.10 duplicate detection re-based on /KZ/query (no similarity_search); palm_provider default → biowave; §16/§17/§18 vendor references collapsed to one. All palm diagrams (§1.3, §4.1–4.4, §6.1, health) rewritten to the BioWave /KZ/* API. |
| 6.7 | May 2026 | Cert expiry alerting — because the platform does not auto-acquire certs (Pattern B: admin uploads from any source — Let's Encrypt, public CA, corporate CA), proactive alerts are required so an expiring cert is never missed. §9.2.2 SSL Configuration Management — "Expiry alerts" paragraph expanded into three subsections: • Three delivery channels: admin console UI banners (existing), email to every user with role='platform_admin' (new), and webhook events on platform-scoped endpoints (new).• Threshold schedule table — server cert at 30/14/7/1/0 days, platform CA at 60/30/14/7/1/0 days (CA gets a 60-day notice because rotation forces every device to re-pair). • Idempotency: a daily background job tracks last_alert_threshold_days per cert in platform_secrets so re-uploading the same cert mid-window does not re-spam recipients.§11.5 Webhook Event Types — new "Platform" section: • platform.server_cert.expiring, platform.server_cert.expired, platform.platform_ca.expiring, platform.platform_ca.expired — fields: kind, fingerprint, expires_at, days_remaining, threshold_days.§11.6 Webhook Configuration: • Added scope field to webhook endpoints — tenant (default, existing) or platform (Platform Admin only, receives platform.* events). Platform-scoped endpoints are not visible to tenant admins.§10.3.2 Audit Events: • New cert_expiry_alert_sent event per alert delivery ({kind, channel, threshold_days, fingerprint, recipient_count}).• Tidied server_cert_deleted description (no longer references self-signed-throwaway state, removed in v6.6). |
| 6.6 | May 2026 | First-run SSL simplification — dropped the self-signed throwaway HTTPS cert at first boot; the backend now serves plain HTTP until an admin uploads a cert. Matches the conventions of GitLab, Grafana, Mattermost, Sentry self-hosted. §9.2.2 SSL Configuration Management — "First-run SSL setup" paragraph rewritten: • On a fresh install with empty platform_secrets, the backend listens on plain HTTP. No self-signed throwaway cert.• The Platform Admin (env-seeded; see §3.6) signs in over HTTP, is forced to change the initial password, and uploads the server TLS cert via the SSL Settings page. • PUT /v1/admin/ssl/server-cert persists the cert and returns 200 OK with restart_scheduled: true when transitioning from HTTP. The backend exits the process after the response flushes; the orchestrator (systemd, Docker restart: always, k8s) restarts it. The second boot reads platform_secrets and launches uvicorn in HTTPS mode.• Steady-state cert rotations (HTTPS → HTTPS) are unchanged — they use SIGHUP for zero-downtime reload.• Dropped the browser-untrusted-cert-warning click-through note. Companion diagrams bumped to v2.7: • §5.4.1 First-Run SSL Setup mermaid rewritten with an explicit "Orchestrator" participant and a process-restart step between the upload response and the HTTPS reload step. Browser-warning language removed. |
| 6.5 | May 2026 | Bootstrap-flow simplification — dropped the "bootstrap admin" / "bootstrap mode" concept; aligned with the standard self-hosted-vendor pattern (GitLab, Grafana, Mattermost): the regular Platform Admin is env-seeded on first boot, logs in via the normal flow, and uploads SSL through the SSL Settings page. §3.6 Role Assignment: • Added "First Platform Admin (initial deploy)" paragraph documenting env-var seeding ( PLATFORM_ADMIN_EMAIL, PLATFORM_ADMIN_INITIAL_PASSWORD) with must_change_password=true; env vars read only when no Platform Admin exists.§9.2.2 SSL Configuration Management: • Replaced "Bootstrap status endpoint" + "Bootstrap mode" paragraphs with a single "First-run SSL setup" paragraph: backend serves self-signed throwaway cert at startup; admin logs in via the normal /v1/auth/login; SSL Settings page renders inline setup wizard when setup_complete=false. Console functionality is fully available during setup — only scanner mTLS endpoints are blocked.§13.2 Console API: • Renamed /v1/admin/ssl/bootstrap-status → /v1/admin/ssl/status. Response shape changed from {bootstrap_required, steps_remaining} to {server_cert_configured, platform_ca_configured, setup_complete}.• Auth changed from "Bootstrap auth" to plain Console session (Platform Admin) — no special auth path. §13.4 Response Metadata: • Removed bootstrap_required 503 row; replaced with mtls_not_configured (503 only for scanner routes when platform CA is missing — admin endpoints stay reachable).§3.4 Console Permission Matrix: • Collapsed "Run bootstrap setup" row into "Manage platform SSL certs" row. §2 Glossary: • Removed "Bootstrap mode" entry (concept no longer exists). Removed from the spec entirely: • /v1/auth/bootstrap/login endpoint• "Bootstrap admin" as a distinct role • "Bootstrap mode" as a distinct operational mode Companion diagrams bumped to v2.6: • §5.4.1 renamed "Bootstrap Mode (First Run)" → "First-Run SSL Setup". Rewrote the mermaid flow: seeds Platform Admin from env, admin logs in via normal /v1/auth/login, forced password change, SSL Settings page renders inline setup wizard until setup_complete=true. No separate bootstrap login path. Same 4 participants kept (Admin, Console, Backend, DB). |
| 6.4 | May 2026 | Consistency sweep — full-document audit closed gaps between §9.2 mTLS / SSL spec, the API spec (§13), audit events (§10.3.2), and supporting sections. §13.2 Console API: • Added new "Platform SSL / Certificate Management" sub-table with 10 endpoints: server-cert (GET/PUT/DELETE), ca-cert (GET/PUT) + generate/regenerate (POST), device-policy (GET/PUT), and bootstrap-status (GET). §13.1 Integrator API: • /v1/devices/pair row now documents the request body shape (pairing_code, csr, device_info with hardware_id) and response (device_id, certificate, ca_chain, expires_at, status).• /v1/devices/renew row now documents the request body (csr) and response shape; notes that the old cert fingerprint goes to the denylist on success.§13.4 Response Metadata: • Added a new "Common Error Responses" table covering cert-related error codes: pairing_code_invalid, pairing_rate_limited, csr_invalid_algorithm, csr_invalid_extensions, csr_signature_invalid, device_revoked, pem_invalid, cert_key_mismatch, regenerate_confirm_required, and bootstrap_required (503 during bootstrap mode).§9.2.2 SSL Configuration Management: • Added "Bootstrap status endpoint" paragraph documenting GET /v1/admin/ssl/bootstrap-status (used by the admin console's bootstrap wizard).§10.3.2 Audit Events: • Added 5 SSL-config audit events ( server_cert_uploaded, server_cert_deleted, platform_ca_generated, platform_ca_regenerated, device_policy_changed).• Added 3 high-severity events the frontend already references but the PRD did not define: device_certs_bulk_revoked, platform_admin_added, tenant_deleted.§3.4 Console Permission Matrix: • Added 3 rows: "Manage platform SSL certs", "Configure device cert policy", "Run bootstrap setup" — all Platform Admin only. §3.9 Security Model: • Added 5 mTLS-era attack rows: scanner identity spoofing, stolen device cert, platform CA private key compromise, pairing replay/impersonation, cross-tenant access via stolen cert. §2 Glossary: • Added 6 entries: PKI, Platform CA, CSR, SAN URI, StrongBox, Bootstrap mode.§16 Data Architecture: • Added platform_secrets to the Link Identity backend's data stack diagram with a follow-up paragraph describing the table's role (singleton-by-kind rows for server cert + platform CA; DB-engine encryption-at-rest is the security boundary). |
| 6.3 | May 2026 | Documentation restructure — diagrams file is now mermaid-only; all reference and prose content lives in the PRD. Expanded §9.2.1 (mTLS Server Config): • Added "Handshake mechanics on authenticated endpoints" paragraph describing the full TLS layer → middleware chain ( ssl_cert_reqs=CERT_OPTIONAL, CertificateRequest/CertificateVerify, denylist validation, app-layer status check).• Added "Key design properties of the mTLS layer" bullets — identity-in-cert (no session table), TLS layer as auth boundary, per-request devices.status check as defense-in-depth, implicit tenant isolation via SAN URI.New PRD appendix sections: • §19.6 — Scanner Client Implementation Reference (Android): hardware-backed keypair generation ( KeyPairGenerator + KeyGenParameterSpec, StrongBox requirement, alias naming), CSR construction via Bouncy Castle with ContentSigner wired to StrongBox-held key, cert storage via OkHttp SSLSocketFactory, renewal lifecycle with alias rotation, loss-of-key recovery semantics.• §19.7 — X-Telcom BioWave Pass Error Codes (migrated from diagrams Appendix B; cross-refs updated to PRD §8.11 for set_query_type restrictions).• §19.8 — Nafath Status Codes (migrated from diagrams Appendix C). • §19.9 — Tenant Config Checks in Flows (migrated from diagrams Appendix D). Companion diagrams bumped to v2.3: • Removed prose intro and "Key properties" list from §5.1.3 — content merged into PRD §9.2.1. • Removed "Scanner-side implementation reference" prose block from §5.1 — content migrated to PRD §19.6, with a one-line pointer left behind. • Removed §5.4 intro paragraph (redundant with PRD §9.2.2). • Removed Appendix A "Audit Events Summary" (redundant with PRD §10.3.2 — authoritative copy). • Removed Appendices B, C, D (migrated to PRD §19.7–19.9). • Removed "End of Diagrams Document" footer. |
| 6.2 | May 2026 | Added §9.2.1 — Certificate Authority and CSR Signing: • Two-PKI model (server TLS PKI + platform CA PKI). • Platform CA stored in platform_secrets DB table.• Cert profile: ECDSA P-256, 90-day validity, SAN URI urn:link:tenant:{tenant_id}:device:{device_id}.• CSR validation rules. • Server config: CERT_OPTIONAL + route whitelist for /v1/devices/pair.• Revocation via fingerprint denylist. • Recovery paths: half-pairing, hardware key loss, clock drift. • NTP requirement. Added §9.2.2 — SSL Configuration Management: • Admin endpoints under /v1/admin/ssl/* for server cert upload, platform CA generate/upload/regenerate, device cert policy.• Bootstrap mode for first-run setup. Updated §9.2 preamble to make TLS termination at the application layer explicit and cross-reference the new subsections. • Added hardware_id to the /v1/devices/pair payload (§9.2 step 4).Companion diagrams bumped to v2.2: • Fixed pairing-code spec drift (9 alphanumeric chars, ~47 bits entropy; example updated; pairing_code_hash terminology aligned with PRD).• Expanded §5.1 (Pairing) — explicit rate-limit step, 4 separate CSR validation steps (PoP, algorithm, strip DN, reject privileged extensions), explicit canonical cert template construction. • Expanded §5.1.1 (Renewal) — explicit mTLS handshake at start, SAN URI extraction, atomic BEGIN/COMMIT for cert rotation + denylist insert. • Expanded §5.1.2 (Revocation) — atomic transaction shown, TLS-layer rejection mechanism (handshake aborts before app), in-flight connection caveat. • Added new §5.1.3 (mTLS Handshake on Authenticated Endpoints) — TLS layer → middleware → DB status check → handler, including the "Key properties" rationale for why identity-in-cert + per-request status check defends against denylist propagation lag. • Added scanner-side implementation reference (Android) after §5.1 mermaid — covers KeyPairGenerator + KeyGenParameterSpec (StrongBox-backed P-256), Bouncy Castle JcaPKCS10CertificationRequestBuilder with a ContentSigner wired to the StrongBox key, cert storage via OkHttp SSLSocketFactory, alias rotation on renewal, and loss-of-key recovery. |
| 6.1 | Apr 2026 | Aligned palm verification with the palm vendor's cloud API: • Renamed the palm vendor adapter. • Added §8.4 Score Model (10-element scores/thresholds with palm_match_policy per tenant).• Replaced single confidence float with scores arrays in §8.5/8.6.• Added §8.10 Pre-Enrollment Duplicate Detection (similarity check, configurable reject/flag). • Added §8.11 Palm Type Restrictions ( set_query_type per user with admin endpoint).• Added §8.12 Operational (vendor health monitoring, threshold configuration). • Added challenge-based personal scanner enrollment to §9.2 (parallel to kiosk path). • Added §4.7 open question on tenant isolation for global vendor namespace. • Added 7 new audit events to §10.3.2 ( palm_enrollment_failed, palm_duplicate_detected, palm_restriction_set, palm_thresholds_updated, palm_vendor_unhealthy, palm_vendor_unauthorized, palm_vendor_version_change).• Added admin endpoints /v1/admin/palm/thresholds, /v1/admin/palm/health, and /v1/users/{id}/palm-restriction to §13.• Added new tenant settings: palm_match_policy, palm_duplicate_check_enabled, palm_duplicate_action. |
| 6.0 | Mar 2026 | Full restructure: • Merged Trust/Actors with Roles (§3). • Merged Multi-Tenancy with Configuration (§4). • Moved Compliance before Webhooks (§10–11). • Moved User Journeys after all capabilities (§12). • Labeled KYC (§7), SMS, SSO as post-MVP. • Absorbed Core Capabilities into Appendix. • Dropped redundant §3.2 Actors table. • All content preserved, no deletions. |
| 5.5 | Mar 2026 | Added Console API: • §14.2 (MVP) with tenant config CRUD, platform admin tenant management, user list/search/suspend/reactivate, audit log query, dashboard stats. • §14.3 (Post-MVP) for KYC sessions, SMS config, archive search, consent records. • Renamed §14.1 to "Integrator API". • Clarified webhook delivery is direct HTTP with retries (no queue). |
| 5.4 | Mar 2026 | Expanded §16 (Webhooks) with full specification: • Delivery contract, payload structure with passthrough metadata. • HMAC-SHA256 signing security, retry policy. • 14 event types (added user.suspended, user.reactivated, verification.failed).• Per-endpoint configuration, webhook management API. • Added §6.5 (Webhook Signing Secrets). • Added /v1/webhooks endpoints to §14.1.• Renumbered §6.6–6.13. |
| 5.3 | Mar 2026 | Restructured §4 (Roles & Access Control): • Added §4.1 Identity Domains separating console users from managed identities. • Split permission matrix into §4.3 Console, §4.4 API, §4.5 End User Endpoints. • Clarified end users only access auth endpoints directly — all other operations go through integrator backends. • Fixed §5.2 deletion wording, §12.2 consent wording. • Added audit events: client_auth_failed, challenge_created, token_refresh_failed to §15.3.2. |
| 5.2 | Mar 2026 | • Added OAuth Client Management (§6.4) with client entity, secret model (1 secret, shown once, bcrypt-hashed), tenant-scoped equal-permission clients, lifecycle (create/regenerate/revoke). • Added /v1/clients API endpoints to §14.1.• Added client audit events to §15.3.2. • Renumbered §6.5–6.12. |
| 5.1 | Mar 2026 | • Added Roles & Access Control (§4) with 5-role RBAC model and permission matrix. • Added Multi-Tenancy Architecture (§11) with isolation model, tenant lifecycle, provisioning, and cross-tenant rules. • Renumbered to 22 sections. |
| 5.0 | Mar 2026 | Full restructure: 20-section layout. • Merged stubs (Actors, Initiation Patterns, Android Scanner). • Consolidated compliance (Consent + Audit + Retention). • Moved Glossary to front. • Fixed tenant type contradiction. • Standardized event types. |
| 4.3 | Feb 2026 | Verification enforcement, consent management |
| 4.0 | Feb 2026 | Unified tenant model, compliance features |
| 3.7 | Feb 2026 | Palm verification ports & adapters, pluggable vendors |
| 3.6 | Feb 2026 | KYC integration, repo structure |
| 3.5 | Feb 2026 | Refresh tokens, social login |