Skip to content

Last1 ID Architecture Bible

Single source of truth for everything built. Update this file when adding schema, endpoints, or architectural decisions.


1. Domain and Product Model

Rule Value
Canonical domain https://last1.id
Last1 ID vs last1.app Independent; last1.app is a client
Users create in MVP Identities, credentials, consent — not apps
Integration point Last1 ID is the identity authority for the ecosystem

Client Apps

  • last1.app — separate product; integrates with Last1 ID
  • RadioCheck
  • MATR iOS
  • MATR Biz
  • RealOutcomes

2. DID Architecture

Method

did:web — resolves to HTTPS URLs on last1.id. No blockchain. Pragmatic standard for organizations hosting their own identifiers.

DID Formats

Principal Format Example
Identity (user) did:web:last1.id:identities:<uuid> did:web:last1.id:identities:a1b2c3d4-...
Issuer did:web:last1.id:issuers:<uuid> did:web:last1.id:issuers:e5f6g7h8-...
App client did:web:last1.id:apps:<app_id> did:web:last1.id:apps:last1

DID Resolution (did:web spec)

DID Resolves to
did:web:last1.id GET https://last1.id/.well-known/did.json
did:web:last1.id:issuers:<uuid> GET https://last1.id/issuers/<uuid>/did.json
did:web:last1.id:identities:<uuid> GET https://last1.id/identities/<uuid>/did.json

DID Document Structure (Issuers)

{
  "@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/jwk/v1"],
  "id": "did:web:last1.id:issuers:<uuid>",
  "verificationMethod": [{
    "id": "did:web:last1.id:issuers:<uuid>#key-1",
    "type": "JsonWebKey",
    "controller": "did:web:last1.id:issuers:<uuid>",
    "publicKeyJwk": { "kty": "OKP", "crv": "Ed25519", "x": "..." }
  }],
  "assertionMethod": ["did:web:last1.id:issuers:<uuid>#key-1"],
  "authentication": ["did:web:last1.id:issuers:<uuid>#key-1"]
}

3. Verifiable Credentials

VC Data Model (W3C 2.0-aligned)

  • @context: https://www.w3.org/ns/credentials/v2
  • type: ["VerifiableCredential", "<CredentialType>"]
  • id: urn:uuid:<credential-id>
  • issuer: issuer DID
  • validFrom: issued_at
  • validUntil: expires_at (optional)
  • credentialSubject.id: subject DID
  • proof: DataIntegrityProof (eddsa-jcs-2022)

Credential Types

Internal Type VC Type
email_verified EmailVerificationCredential
phone_verified PhoneVerificationCredential
human_verified HumanVerificationCredential
identity_profile_completed IdentityProfileCredential
veteran_verified VeteranVerificationCredential
matr_cohort_member MatrCohortMemberCredential
matr_trust_program_completed MatrTrustProgramCredential
matr_facilitator_confirmed MatrFacilitatorCredential
radiocheck_participant RadioCheckParticipantCredential
beneficiary_enrolled BeneficiaryEnrolledCredential
provider_verified ProviderVerifiedCredential

Signing

  • Algorithm: Ed25519
  • Proof type: DataIntegrityProof, cryptosuite eddsa-jcs-2022
  • Canonicalization: Sorted-key JSON
  • Private keys: Encrypted at rest (AES-256-GCM) with CREDENTIAL_SIGNING_KEY

Credential Status

  • active — valid and usable
  • revoked — status column or revoked_at set
  • expired — expires_at in the past
  • suspended — status column

4. Schema

Core Tables

Table Purpose
identities User identity records; includes did
linked_auth_providers External auth (Google, Microsoft, IdMe, email)
app_clients OAuth app clients; includes did
consent_grants User consent for app access
credential_issuers Issuers; includes did, allowed_credential_types, trust_level
credentials User credentials; includes signature, credential_vc
issuer_keys Ed25519 key pairs per issuer (public_key, private_key_encrypted)
trust_events Append-only trust-building events
reputation_snapshots Portable trust summaries
identity_app_links Links identities to app-specific user records
oauth_authorization_codes OAuth2 authorization codes

Key Columns

Table Column Type Notes
identities did TEXT UNIQUE did:web:last1.id:identities:<id>
credential_issuers did TEXT UNIQUE did:web:last1.id:issuers:<id>
app_clients did TEXT UNIQUE did:web:last1.id:apps:<app_id>
credentials signature TEXT Legacy base64 Ed25519 signature
credentials credential_vc JSONB Full W3C VC envelope with proof
issuer_keys public_key TEXT PEM-encoded Ed25519
issuer_keys private_key_encrypted TEXT AES-256-GCM encrypted

5. API Endpoints

DID Resolution (public, no auth)

Method Path Returns
GET /.well-known/did.json Root DID document
GET /issuers/:id/did.json Issuer DID document with verification methods
GET /identities/:id/did.json Identity DID document

Credentials

Method Path Auth Purpose
POST /api/credentials/issue App (credentials:issue) Issue credential; signs with issuer key
GET /api/credentials/verify/:id Public (if profile_public + allowlist) / Owner / App Returns credential + VC + signature + public key
GET /api/credentials/status/:id Public Returns credential status (active/revoked/expired/suspended)
GET /api/issuers/:issuerId/public-key Public Returns issuer public key

Verification (presentation layer)

Method Path Auth Purpose
POST /api/verify/credential None Stateless VC verification; accepts signed VC + optional public key

Identity

Method Path Auth Purpose
GET /api/identity/public/:idOrUsername Public (if profile_public) Public profile
GET /api/identity/me User Current identity + linked providers
GET /api/identity/signals User Trust signals (no score)
GET /api/identity/credentials User List credentials
GET /api/identity/credentials/export User Export v3: identity, credentials with VCs, issuers keyed by DID
POST /api/identity/credentials/verify-human User + Turnstile Issue human_verified
POST /api/identity/credentials/request-phone-verify User Send OTP
POST /api/identity/credentials/verify-phone User Verify OTP, issue phone_verified
PATCH /api/identity/profile User Update profile_public, username
GET /api/identity/app-links User Connected apps
GET /api/identity/consent User Consent grants
GET /api/identity/trust-events User Trust events
GET /api/identity/reputation/snapshots User Reputation snapshots

OAuth

Method Path Auth Purpose
GET /api/oauth/authorize/validate None Validate client_id, redirect_uri, scope
POST /api/oauth/authorize/approve User Create auth code
POST /oauth/token App (Basic) Exchange code for access token

Trust Events

Method Path Auth Purpose
POST /api/trust-events App (Bearer + X-App-Id or Basic) Ingest trust events

6. Trust Model

Principles

Rule Implementation
App-agnostic trust_events use generic event_type
Portable Credentials use DIDs; export includes VCs
Proof-based Signals from credentials and trust_events
No centralized score Identity Strength shows checkmarks only
Trusted issuers only Issuance requires valid credential_issuers row
Trust events append-only Insert only; no update/delete

Credential Issuance Rules

  1. App has credentials:issue or credentials:write scope
  2. Identity granted consent to the app
  3. credential_type in issuer's allowed_credential_types
  4. Credential references registered issuer

7. Centralized vs Decentralized

Aspect Status
Credential verification Decentralized — DID doc + proof = offline-verifiable
DID resolution Decentralized — did:web via HTTPS
Credential portability Decentralized — VC export
Issuer discovery Decentralized — DID documents
Identity creation Centralized — platform-managed
Private key storage Centralized — encrypted in Supabase
Credential issuance trigger Centralized — via Last1 ID API
Status checks Centralized — hit Last1 ID for revocation
DID document hosting Centralized — last1.id serves them

8. Environment Variables

Variable Required Purpose
SUPABASE_URL Yes Supabase project URL
SUPABASE_SERVICE_ROLE_KEY Yes Server-side Supabase access
VITE_SUPABASE_URL Yes Client Supabase URL
VITE_SUPABASE_ANON_KEY Yes Client Supabase anon key
CREDENTIAL_SIGNING_KEY Yes 32+ chars; encrypts issuer private keys
TURNSTILE_SECRET_KEY Optional human_verified credential
VITE_TURNSTILE_SITE_KEY Optional Client Turnstile
TWILIO_ACCOUNT_SID Optional phone_verified credential
TWILIO_AUTH_TOKEN Optional phone_verified credential
TWILIO_VERIFY_SERVICE_SID Optional Must start with VA
SITE_URL Production CSRF origin validation
RADIOCHECK_APP_SECRET Per-app Trust event ingestion
MATR_IOS_APP_SECRET Per-app Trust event ingestion
LAST1_APP_SECRET Per-app Trust event ingestion

9. File Map

Server Lib

File Purpose
did.ts DID generation, document building, VC construction
credentialSigning.ts Key gen, encrypt/decrypt, sign/verify, VC signing
credentialStatus.ts resolveCredentialStatus()
credentials.ts System credential issuance (issueCredentialIfMissing)
identity.ts getOrCreateIdentityForUser, upsertLinkedAuthProvider
identitySignalsService.ts Trust signals computation
auth.ts Supabase auth user resolution
appClientAuth.ts App client auth (Bearer, Basic)
oauth.ts OAuth token logic
reputation.ts Reputation snapshot generation

Server Routes

File Purpose
did.ts DID document serving
verify.ts Credential presentation/verification
credentials.ts Credential issuance, verify, status, public-key
identity.ts Identity, profile, credentials, export, consent
oauth.ts OAuth authorize + token
trustEvents.ts Trust event ingestion
appClients.ts App client registration
admin.ts Admin gateway

10. Migrations (Chronological)

  1. identities, linked_auth_providers, app_clients, consent_grants
  2. credential_issuers, credentials, trust_events, reputation_snapshots
  3. identity_app_links, seed_app_clients
  4. auth_and_onboarding (auth_user_id, onboarding_completed_at)
  5. phone_verification
  6. app_client_registration
  7. radiocheck_redirect_uris
  8. identity_platform_additions (last_used_at, system issuer)
  9. internal_app_redirect_uris
  10. tune_redirect_uris
  11. matr_b2b_rename_to_matr_biz
  12. identity_public_profile (username, profile_public)
  13. credential_issuer_allowed_types
  14. oauth_authorization_codes
  15. credential_issuers_trust_level
  16. issuer_keys
  17. credentials_signature
  18. did_and_vc (did columns, credential_vc)

11. Next Steps (Roadmap)

  1. User-controlled DIDs — Allow users to bring did:key or did:ion
  2. OpenID4VCI — Standards-based credential issuance
  3. OpenID4VP — Presentation request/response flow
  4. Bitstring Status List — Publish status bitstrings
  5. External wallet support — CHAPI or OID4VP export
  6. DID method migration — did:dht or did:tdw for self-sovereign identifiers

12. Internal System Admin Control Plane

Domain and Purpose

  • Internal portal domain: admin.last1.enterprises
  • Scope: ecosystem-level operations for last1.id, last1.app, radiocheck.app, realoutcomes.app
  • Not an org/customer admin console

Roles

  • super_admin
  • platform_admin
  • security_admin
  • support_admin
  • read_only_auditor

Security and Privacy Posture

  • Gateway-authenticated admin routes with signed headers
  • Membership + role enforcement from system_admin_memberships
  • Capability-gated mutations (identity/issuer/policy/app client/key/service operations)
  • Append-only admin audit logging in admin_audit_logs
  • No private-key exposure in admin APIs or UI
  • DID/VC trust model remains proof-based and portable; no reputation score added