Skip to content

3. Identity Domains & Access Control

3.1 Trust Boundaries

Actor Link trusts them to...
Integrator Correctly identify their users before enrollment (when providing own user_id)
Link Device Capture authentic palm templates
Verification Server Securely store templates and match accurately
Product Backends Honor the platform's authorize decision and run their own business logic (charge wallet, grant access) — §10
Google/Apple Provide valid ID tokens for social login
KYC Providers Verify user identity (Nafath, Onfido, etc.)

3.2 Identity Domains

The platform has two distinct identity domains. These are separate systems with separate storage — they never overlap.

Domain Who Auth Storage Accesses
Console users (manage the platform) Platform Admin, Tenant Admin, Tenant Operator Email/password + MFA, console session console_users table Web Console only
Managed identities (managed BY the platform) End Users OTP/password/social → User JWT users table Auth endpoints only (login, password change, token revoke). All other operations go through the integrator's backend.

Additionally, two non-human actors interact with the platform:

Actor Auth Storage Accesses
Integrator Backend OAuth client_credentials oauth_clients table All tenant-scoped REST APIs (user CRUD, KYC, enrollment, verification, consent)
Device (personal scanner / pos / gate / kiosk) mTLS / device certificate devices table Challenge polling (personal scanner) or device-initiated transactions / signup / enroll (pos/gate/kiosk) — §9, §10

Key principle: End users never access the Web Console or call management APIs directly. They interact with their integrator's application (mobile app, kiosk, POS), which calls the Identity Platform on their behalf using client_credentials. The only endpoints an end user calls directly are the auth endpoints for login, password change, and token revocation.

3.3 Console Roles

The platform separates authentication (who you are — Section 6) from authorization (what you can do). This section defines the role-based access control (RBAC) model that governs who can manage platform resources, tenant configuration, and user data.

Role Scope Description
Platform Admin All tenants Link operations team. Creates/suspends tenants, manages platform configuration, views cross-tenant metrics.
Tenant Admin Single tenant Integrator's administrator. Full control within their tenant: settings, OAuth clients, devices, users, audit logs.
Tenant Operator Single tenant Day-to-day support staff. Views users, KYC pipeline, audit logs, dashboard. Cannot modify tenant configuration or manage OAuth clients. Read-heavy role.

Why Tenant Operator? Saudi regulated industries (SAMA requirements) mandate least-privilege access. Support staff need to view user data for troubleshooting without the ability to change configuration. Audit trails can distinguish "who changed settings" from "who viewed data."

3.4 Console Permission Matrix

Permission Platform Admin Tenant Admin Tenant Operator
Create / suspend / delete tenants Yes
View all tenants Yes
Configure tenant settings Yes Own tenant
Manage OAuth clients Yes Own tenant
Manage devices / scanners Yes Own tenant View
Manage platform SSL certs (server cert + platform CA, incl. first-run setup) Yes
Configure device cert policy Yes
Configure webhooks Yes Own tenant
View users Yes Own tenant Own tenant
Manage users (suspend / delete) Yes Own tenant
View audit logs Yes Own tenant Own tenant
View KYC pipeline Yes Own tenant Own tenant
View consent records Yes Own tenant Own tenant
View dashboard / analytics Yes Own tenant Own tenant

Notes: - "Own tenant" means within the tenant the admin/operator belongs to. - Platform Admin operates through a platform-level console or superadmin mode, not through a tenant-scoped view.

3.5 End User Access

End users authenticate directly with the Identity Platform for login only. All other operations go through their integrator's backend. End users cannot access the Web Console, management APIs, or any endpoint requiring client_credentials. See Section 14.1 for the complete endpoint reference.

3.6 Role Assignment

Role How Assigned Authentication Storage
Platform Admin Assigned internally by Link ops Web Console (email/password + MFA) console_users table with role: "platform_admin"
Tenant Admin Created during tenant provisioning (see Section 4) Web Console (email/password + MFA) console_users table with tenant_id + role: "tenant_admin"
Tenant Operator Created by Tenant Admin via Web Console Web Console (email/password) console_users table with tenant_id + role: "tenant_operator"
Integrator Backend Represented by OAuth clients (see Section 6.4) client_credentials grant oauth_clients table with tenant_id
End User Created via signup or POST /v1/users OTP / password / social → User JWT users table with tenant_id

First Platform Admin (initial deploy). On a fresh install with no platform_admin row in console_users, the backend seeds one from two env vars on first boot:

  • PLATFORM_ADMIN_EMAIL — the admin's email address (required)
  • PLATFORM_ADMIN_INITIAL_PASSWORD — the admin's initial password (optional; if absent, the backend generates a random one and prints it to stdout once)

The seeded admin is created with must_change_password=true and is forced to set a new password on first login. The env vars are read only when no Platform Admin exists — subsequent boots ignore them, so they may safely remain in the deployment config or be removed entirely after first run. This is the standard self-hosted-vendor pattern (compare GitLab's GITLAB_ROOT_PASSWORD, Grafana's GF_SECURITY_ADMIN_PASSWORD). There is no separate "bootstrap" admin role.

3.7 API Authorization

How the platform determines the caller's identity and enforces access:

Auth Mechanism Role Determined Tenant Scope
OAuth client_credentials token Integrator Backend tenant_id from client registry
User JWT (access token) End User user_id + tenant_id from token claims
Web Console session Platform Admin, Tenant Admin, or Tenant Operator role + tenant_id from session
mTLS device certificate Device (not a role — see Section 9) device_id + tenant_id from certificate

3.8 Verification Semantics

The platform confirms:

"The palm scanned matches the palm enrolled for user_id X at timestamp T"

It returns metadata (confidence score, timestamp) — not a signed proof. The platform does not make identity claims; for identity proofing, KYC verification is required.

3.9 Security Model

Attack Vector Mitigation
Token stolen Short-lived access tokens (24h), refresh tokens revocable
Man-in-middle TLS for all communication
Template theft Templates stored in Verification Server, not exposed via API
Presentation attack Palm vein technology inherently requires live blood flow
Password breach bcrypt hashing, breach detection
KYC fraud Government-issued ID verification via trusted providers
Scanner identity spoofing Per-device mTLS client cert with private key bound to Android StrongBox (non-exportable). Cert SAN URI carries device_id/tenant_id and is verified on every request — see §9.2.1.
Stolen device cert Revoke via DELETE /v1/devices/{id} → fingerprint goes into denylist; TLS handshake rejects on next connection. Device must re-pair from scratch.
Platform CA private key compromise Regenerate CA via POST /v1/admin/ssl/ca-cert/regenerate (destructive). All device certs invalidated; scanners must re-pair. Audit event platform_ca_regenerated is high-severity.
Replay / impersonation during pairing 9-char pairing code (~47 bits entropy), 5-min TTL, single-use via atomic SQL, rate-limited per source IP. CSR proof-of-possession ensures only the key holder can use the code (§9.2.1).
Cross-tenant access via stolen cert SAN URI binds the cert to a specific tenant_id; middleware uses this for tenant scope. A device cert from tenant A cannot access tenant B endpoints.