diff --git a/Custom IAM Architecture Analysis v2.md b/Custom IAM Architecture Analysis v2.md new file mode 100644 index 0000000..f40b8a4 --- /dev/null +++ b/Custom IAM Architecture Analysis v2.md @@ -0,0 +1,455 @@ +# Custom IAM Architecture Analysis v2.md + +# Architectural Blueprint & Enterprise Implementation Roadmap: Decoupled Zero-Trust Identity Fabric + +## 1. Executive Summary & Paradigm Evolution + +The **Auth-Yes** Identity Fabric represents an ultra-low-friction, zero-trust +Identity and Access Management (IAM) system tailored for a high-velocity +microservice ecosystem. By rejecting the protocol bloat, redirect friction, and +configuration overhead of traditional OIDC/OAuth2 monoliths (e.g., Keycloak, +Authentik, Okta), Auth-Yes delivers microsecond-level stateful session +verification, phishing-proof WebAuthn passkey authentication, and cryptographic +workload identity. + +### Key Refinements in v2 Architecture: + +1. **Parent-Domain WebAuthn Scoping (`RP_ID=atyg.org`):** + - Eliminates the runtime complexity of Related Origin Requests (ROR) for the + primary domain ecosystem. All subdomains across `*.atyg.org` natively share + passkeys and session verification. +2. **Three-Tier Defense-in-Depth Model:** + - **Tier 1 (Global Edge Default):** Universal Traefik ForwardAuth perimeter + fallback protecting untagged/pre-release services. + - **Tier 2 (Edge Proxy Override):** ForwardAuth cookie validation for + legacy/third-party applications (Portainer, Grafana, admin consoles). + - **Tier 3 (Application Zero-Trust):** In-app Deno App SDK communicating over + high-throughput ConnectRPC / gRPC with SPIFFE/SPIRE mTLS identity and + granular application RBAC. +3. **Structured Token Provisioning Taxonomy:** + - Formalized 3-tier invite token architecture (Global Admin, Site-Scoped, and + Open/Pending) alongside Out-of-Band Account Recovery. +4. **Complete Administrative Console Roadmap:** + - Finalized UI specifications for Application Registration (`/admin/apps`), + Multi-Type Invite Provisioning (`/admin/invites`), and Granular User RBAC + Grant Management (`/admin/users/:id`). + +--- + +## 2. Core Security Architecture & Defense-in-Depth Layering + +Auth-Yes implements a strict multi-layered defense model ensuring that neither +network locality nor perimeter isolation is treated as an implicit proxy for +trust. + +``` + [ Public Internet / Client Browser ] + │ + ▼ + ═══════════════════════════════════════════════════ + TIER 1 & 2: Traefik Reverse Proxy & ForwardAuth Edge + ═══════════════════════════════════════════════════ + │ │ +(Legacy/3rd-Party Apps) (Native Microservices) +[ Portainer / Web UIs ] [ ed-droid Web Edge ] + │ │ + ▼ ▼ +ForwardAuth Interception Traefik TLS Ingress +GET /api/forward-auth PassTLSClientCert +(Valkey Cache Lookup) │ + │ ▼ + └──────────────────────────────► ═══════════════════════════ + TIER 3: Zero-Trust App Mesh + ConnectRPC + SPIFFE / mTLS + ═══════════════════════════ + │ + ▼ + [ Auth-Yes Core Gateway ] + - Valkey Cache (L1/L2) + - PostgreSQL Store + - Default-Deny RBAC +``` + +### 2.1. Tier 1 — Global Edge Perimeter (Traefik ForwardAuth Default Fallback) + +- **Objective:** Ensure zero accidental exposure of internal or pre-release + services. +- **Mechanism:** Traefik entrypoints (e.g., `websecure`) are configured with a + default ForwardAuth middleware. Any newly created container or untagged + service deployed on the internal network is protected by default. +- **Behavior:** Unauthenticated HTTP requests without a valid session cookie are + automatically redirected to `https://auth.atyg.org/login`. + +### 2.2. Tier 2 — Edge Proxy Override (Third-Party & Legacy Applications) + +- **Objective:** Secure off-the-shelf and legacy software (e.g., Portainer, + Grafana, PgAdmin) without requiring code modifications or custom SDK + integration. +- **Mechanism:** Traefik routers for these services explicitly route + authentication checks to `https://auth.atyg.org/api/forward-auth`. +- **Validation Flow:** + 1. Client sends request with `session_id` cookie scoped to `.atyg.org`. + 2. Traefik queries `auth-api:8000/api/forward-auth`. + 3. Auth API checks Valkey in microseconds. If valid and account is active, + returns HTTP `200 OK` and injects upstream identity headers: + - `X-Forwarded-User: ` + - `X-Forwarded-User-Id: ` + 4. If invalid or missing, returns HTTP `401 Unauthorized` or redirects to + login. + +### 2.3. Tier 3 — Application-Level Zero-Trust (Deno App SDK + ConnectRPC + SPIFFE/mTLS) + +- **Objective:** Provide high-throughput, microsecond-latency identity + validation with granular Role-Based Access Control (RBAC) for native + microservices. +- **Mechanism:** + - Subsidiary services import the logic-pure `@ed-droid/auth-yes/sdk` + middleware. + - The SDK intercepts requests, extracts the session token, and validates it + against the Auth Hub using **ConnectRPC / gRPC** over HTTP/2 multiplexed + connections. + - **Workload Cryptographic Attestation:** Workload identity is authenticated + via **SPIFFE/SPIRE x509 SVID certificates**. The Auth Hub validates the + calling application's SPIFFE ID (e.g., + `spiffe://system.local/ed-droid-backend`) against the `apps` table. + - **Default-Deny Authorization:** Authentication (who the user is) is + decoupled from authorization (what app they can access). The Auth Hub + verifies that an explicit active record exists in the `grants` table + matching `(user_id, app_id)`. + +--- + +## 3. WebAuthn Scope Mechanics: Parent Domain vs. Related Origin Requests (ROR) + +### 3.1. Parent Domain Scoping (`RP_ID=atyg.org`) + +In the W3C WebAuthn specification, a credential is bound to a Relying Party +Identifier (`RP_ID`). + +- Under WebAuthn origin validation rules, an `RP_ID` can be set to any + **registrable domain suffix (eTLD+1)** of the origin. +- By setting: + ```env + RP_ID=atyg.org + ORIGIN=https://auth.atyg.org + ``` +- **Result:** Any passkey created under `RP_ID=atyg.org` is cryptographically + valid and authenticatable across **all** subdomains under `*.atyg.org` (e.g., + `auth.atyg.org`, `ed-droid.atyg.org`, `nas.atyg.org`). +- **Browser Compliance:** Supported natively across 100% of modern WebAuthn + implementations (Apple Safari/iOS, Google Chrome/Android, Windows Hello, + 1Password, YubiKeys). + +### 3.2. Session Cookie Cross-Subdomain Sharing + +To support edge proxy interception (ForwardAuth Tier 1 & 2), the Auth Hub sets +the session cookie with domain wildcard scoping: + +```ts +setCookie(c, "session_id", sessionId, { + domain: ".atyg.org", + httpOnly: true, + secure: true, + sameSite: "Lax", + expires: expiresAt, +}); +``` + +This ensures the browser transmits the session cookie seamlessly to all +subdomains under `*.atyg.org`. + +### 3.3. Future Scope: Related Origin Requests (ROR) + +Dynamic Related Origin Requests via `https://auth.atyg.org/.well-known/webauthn` +are officially archived for **Phase 3 (Cross-TLD Expansion)**. ROR will only be +required when federating authentication across completely distinct root domains +(e.g., bridging `atyg.org` with `ed-droid.io` or `independent-domain.com`). + +--- + +## 4. Identity Lifecycle & Token Provisioning Taxonomy + +Auth-Yes implements a strict 3-tier invite provisioning architecture ensuring +mathematical control over user onboarding and access grants. + +``` + ┌────────────────────────────────────────┐ + │ Admin Onboarding Generator │ + └───────────────────┬────────────────────┘ + │ + ┌───────────────────────────────┼──────────────────────────────┐ + ▼ ▼ ▼ +┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ +│ Type 1: Global │ │ Type 2: Site │ │ Type 3: General │ +│ Admin Invite │ │ Scoped Invite │ │ Open / Pending │ +├──────────────────┤ ├──────────────────┤ ├──────────────────┤ +│ app_id: NULL │ │ app_id: UUID │ │ app_id: NULL │ +│ role: 'admin' │ │ role: 'user/adm' │ │ role: 'user' │ +│ status: 'active' │ │ status: 'active' │ │ status: 'pending'│ +└──────────────────┘ └──────────────────┘ └──────────────────┘ +``` + +### 4.1. Type 1: Global Admin Onboarding Token + +- **Purpose:** Initial system bootstrapping and administrative team onboarding. +- **Characteristics:** `app_id` is unbound (`NULL` or Management Console), + `role = 'admin'`. +- **Lifecycle:** User registers passkey $\rightarrow$ Account is set to `active` + $\rightarrow$ User is granted global administrative privileges across Auth-Yes + and all internal systems. + +### 4.2. Type 2: Site-Scoped Onboarding Token + +- **Purpose:** Controlled user onboarding for a specific subsidiary application + (e.g., `ed-droid`). +- **Characteristics:** `app_id` is locked to a specific application UUID, + `role = 'user'` (or application admin). +- **Lifecycle:** User registers passkey $\rightarrow$ Account is set to `active` + $\rightarrow$ System automatically inserts a grant record into + `grants (user_id, app_id, role)`. User can access the designated application + immediately, but is denied access to all other apps. + +### 4.3. Type 3: General Open / Pending Registration Token + +- **Purpose:** Broad community or team registration requiring manual + verification. +- **Characteristics:** `app_id: NULL`, `role = 'user'`, initial + `account_status = 'pending'`. +- **Lifecycle:** User registers passkey $\rightarrow$ Account is created in + `pending` state $\rightarrow$ User cannot log in until a Global Admin accesses + `/admin/users` and activates the account, optionally assigning specific + application grants. + +### 4.4. Out-of-Band Single-Use Account Recovery Token + +- **Purpose:** Lockout recovery when a user loses all registered hardware + passkeys. +- **Characteristics:** 24-hour time-limited cryptographic token linked to + existing `user_id`. +- **Lifecycle:** Admin generates recovery link in `/admin/users/:id` + $\rightarrow$ Transmitted out-of-band $\rightarrow$ User accesses + `/recovery?code=...` $\rightarrow$ User binds new hardware passkey + $\rightarrow$ Previous passkeys invalidated, existing UUID and application + grants preserved. + +### 4.5. The RBAC Grant Lifecycle: Default-Deny, Assignment Matrix & RPC Payload + +The identity fabric enforces strict decoupled authorization governed by three +continuous states: + +1. **The Baseline (Default-Deny Zero-Trust):** + - When a user registers a passkey or when an admin provisions an account, the + user possesses **zero application access by default**. + - If an unassigned user attempts to authenticate to `ed-droid.atyg.org`, the + calling application SDK queries the central `AuthService.validateSession` + endpoint over ConnectRPC. + - The Auth Hub queries + `SELECT role FROM grants WHERE user_id = $1 AND app_id = $2`. Finding no + matching grant record, the server returns + `{ valid: false, uuid: "", scopes: [], error: "Validation failed" }`, + resulting in an instant `403 Forbidden: No explicitly granted roles`. + +2. **The Assignment Matrix (Admin Console):** + - In `https://auth.atyg.org/admin`: + - Under **Applications** (`/admin/apps`), apps are registered (e.g. + `ed-droid`, SPIFFE ID `spiffe://system.local/ed-droid-backend`). + - Under **User Profile** (`/admin/users/:id`), the administrator views the + user's active permissions matrix. + - To grant access to a user (e.g., your nephew), the administrator selects + `ed-droid` from the app selector, selects a role (`viewer`, `operator`, + `editor`, `admin`), and clicks **Grant Access** (or checks the matrix + toggle). + - An atomic row is written to `grants (user_id, app_id, role)`. + +3. **The Payload & Runtime Authorization:** + - The next time the user makes a request to `ed-droid`, the Deno App SDK + intercepts the session token and validates it via ConnectRPC over internal + mTLS. + - The Auth Hub validates the session in Valkey, retrieves the active grant + for `ed-droid`, and returns the cryptographic payload: + ```json + { + "valid": true, + "uuid": "edfa8a54-66c5-4444-9e38-becfc5aa6463", + "scopes": ["viewer"] + } + ``` + - The Deno App SDK middleware injects + `c.set("user", { uuid, scopes: ["viewer"] })` into the application context, + allowing `ed-droid` to render the exact UI views and API actions permitted + for a `viewer`. + +--- + +## 5. PostgreSQL Central Identity Schema Reference + +```sql +-- Central Users Table +CREATE TABLE IF NOT EXISTS users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + username TEXT UNIQUE NOT NULL, + display_name TEXT, + account_status TEXT DEFAULT 'pending' CHECK (account_status IN ('active', 'pending', 'suspended')), + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Registered Applications / Sites Table +CREATE TABLE IF NOT EXISTS apps ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name TEXT NOT NULL, + spiffe_id TEXT UNIQUE NOT NULL, + description TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Granular Application RBAC Grants Table +CREATE TABLE IF NOT EXISTS grants ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + app_id UUID NOT NULL REFERENCES apps(id) ON DELETE CASCADE, + role TEXT NOT NULL DEFAULT 'user', + created_at TIMESTAMPTZ DEFAULT NOW(), + UNIQUE(user_id, app_id) +); + +-- Onboarding & Invitation Tokens Table +CREATE TABLE IF NOT EXISTS invites ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + code TEXT UNIQUE NOT NULL, + app_id UUID REFERENCES apps(id) ON DELETE CASCADE, + role TEXT NOT NULL DEFAULT 'user', + used_by UUID REFERENCES users(id) ON DELETE SET NULL, + expires_at TIMESTAMPTZ NOT NULL, + created_at TIMESTAMPTZ DEFAULT NOW(), + used_at TIMESTAMPTZ +); + +-- Hardware Passkeys Table +CREATE TABLE IF NOT EXISTS passkeys ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + credential_id TEXT UNIQUE NOT NULL, + public_key TEXT NOT NULL, + counter BIGINT NOT NULL DEFAULT 0, + aaguid TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Active User Sessions Table +CREATE TABLE IF NOT EXISTS sessions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + created_at TIMESTAMPTZ DEFAULT NOW(), + expires_at TIMESTAMPTZ NOT NULL +); + +-- Security Audit Records Table +CREATE TABLE IF NOT EXISTS audit_records ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID REFERENCES users(id) ON DELETE SET NULL, + action TEXT NOT NULL, + resource TEXT, + details JSONB, + ip_address TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Enterprise Hardware AAGUID Allowlist Table +CREATE TABLE IF NOT EXISTS aaguid_allowlist ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + aaguid TEXT UNIQUE NOT NULL, + description TEXT NOT NULL, + created_at TIMESTAMPTZ DEFAULT NOW() +); +``` + +--- + +## 6. Administrative UI Implementation Specifications + +The Auth-Yes Admin Console is built using server-rendered Deno Hono JSX +components executing direct database queries with zero intermediate loopback +latency. + +### 6.1. Navigation Architecture (`AuthenticatedLayout.tsx` & `AdminLayout.tsx`) + +``` +[ Identity Provider Navbar ] + ├── User Dashboard (/dashboard) + ├── Active Sessions (/dashboard/sessions) + ├── Registered Passkeys (/dashboard/passkeys) + └── [ ADMIN CONSOLE ] (Rendered if isAdmin = true) + ├── User Directory (/admin/users) + ├── Application Registry (/admin/apps) + ├── Invite Tokens (/admin/invites) + ├── AAGUID Allow-List (/admin/aaguid) + └── Security Audit Logs (/admin/audit-logs) +``` + +### 6.2. Page Specifications & Actions + +#### 1. User Directory (`/admin/users`) + +- **Features:** + - Tabular list of all registered users (`username`, `display_name`, + `account_status`, `created_at`, `grant_count`). + - Status mutation buttons: _Activate_, _Suspend_, _Re-Activate_. + - Link to detailed User Management profile (`/admin/users/:id`). + +#### 2. User Profile & RBAC Grant Manager (`/admin/users/:id`) + +- **Features:** + - **Account Recovery:** Single-click _Generate 24h Out-of-Band Recovery Link_. + - **Active Sessions:** List active sessions with individual and _Revoke All_ + actions. + - **Registered Hardware Tokens:** List registered passkeys (`credential_id`, + `counter`, `created_at`) with _Delete Device_ action. + - **Application Access Grants (New in v2):** + - Matrix of currently assigned application access (`App Name`, `Role`, + `Granted At`). + - _Grant Access_ dropdown selector (`App`, `Role: user | admin`) to attach + new app permissions. + - _Revoke Access_ button to remove application-specific access. + +#### 3. Application Registry (`/admin/apps`) + +- **Features:** + - Table of all registered internal applications (`name`, `spiffe_id`, + `description`, `active_users_count`). + - _Register New Application_ form: + - `App Name` (e.g., "Elite Dangerous Streaming Hub") + - `SPIFFE ID` (e.g., `spiffe://system.local/ed-droid-backend`) + - `Description` + - _Delete Application_ action (with confirmation modal preventing accidental + lockout). + +#### 4. Invite & Onboarding Token Manager (`/admin/invites`) + +- **Features:** + - **Token Generation Modal/Form:** + - **Token Type Selector:** + 1. _Global Admin Token_ (Pre-configures `role: 'admin'`, `app: NULL`) + 2. _Site-Scoped Token_ (Displays App dropdown selector + Role selector) + 3. _Open/Pending User Token_ (Pre-configures `role: 'user'`, `app: NULL`, + creates pending user) + - **Expiration Bounds:** 1 to 30 days (default: 7 days). + - **Custom Invite Code (Optional):** Auto-generates cryptographically random + code if left blank. + - **Live Invites Ledger:** + - Table displaying `Code`, `Type / Scope`, `Target App`, `Role`, + `Expires At`, `Status (Active / Used / Expired)`. + - Single-click _Copy Registration URL_ button + (`https://auth.atyg.org/register?code=...`). + - _Revoke Invite_ action. + +--- + +## 7. Implementation Roadmap & Execution Checklist + +| Phase | Milestone | Scope / Deliverables | Status | +| :---------- | :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------ | +| **Phase 1** | **Core Identity & Passkey Engine** | - WebAuthn challenge & verification engine
- PostgreSQL schema auto-initialization
- Valkey session cache & instant revocation
- Direct SSR database rendering (zero-loopback)
- Hybrid hardware/software passkey support | **COMPLETED** | +| **Phase 2** | **Zero-Trust App Mesh (Backend)** | - ConnectRPC / gRPC transport
- SPIFFE/SPIRE mTLS client certificate validation
- Default-deny RBAC grant verification
- ForwardAuth `/api/forward-auth` endpoint | **COMPLETED** | +| **Phase 3** | **Admin Console UI Views (Current)** | - `/admin/apps` Application Registry UI
- `/admin/invites` Multi-Type Token Provisioning UI
- `/admin/users/:id` App RBAC Grant Manager UI
- Domain wildcard cookie (`.atyg.org`) deployment | **READY FOR BUILD** | +| **Phase 4** | **Edge Hardening & Future Scoping** | - Traefik Tier 1 global ForwardAuth fallback configuration
- Traefik Tier 2 ForwardAuth container routing
- Related Origin Requests (`/.well-known/webauthn`) for external TLDs | **FUTURE** | diff --git a/Custom IAM Architecture Analysis.md b/Custom IAM Architecture Analysis.md new file mode 100644 index 0000000..c98fea4 --- /dev/null +++ b/Custom IAM Architecture Analysis.md @@ -0,0 +1,616 @@ +# **Architectural Blueprint and Hardening Analysis of a Decoupled, Zero-Trust Identity Provider Utilizing Deno, Valkey, and WebAuthn** + +## **1\. The Paradigm Shift in Enterprise Identity Architectures** + +Historically, enterprise Identity and Access Management (IAM) has been dominated +by massive, monolithic platforms designed to broker trust across disparate +networks via heavy, standardized protocols. Solutions such as Keycloak, +Authentik, and Okta rely primarily on OpenID Connect (OIDC), OAuth2 redirection +flows, and stateless JSON Web Tokens (JWTs) to authenticate users and authorize +applications1. While these frameworks provide broad interoperability, they +impose immense configuration friction on software engineering teams. Integrating +a new internal application typically requires registering client secrets, +defining redirect URIs, configuring complex scopes, and implementing OAuth2 +authorization code flows—a barrier to rapid iteration.\ +Simultaneously, global industry leaders have increasingly adopted Zero Trust +security architectures, heavily influenced by frameworks like Google's +BeyondCorp and Cloudflare Access, which assert that network locality is no +longer a proxy for trust2. In these advanced models, every request must be +cryptographically authenticated, authorized, and continuously validated, +regardless of whether the traffic originates from the public internet or an +internal Docker network.\ +The proposed custom Identity Provider (IdP) architecture represents a radical, +highly efficient departure from traditional monolithic IdP patterns. By +utilizing a centralized Deno-based API Gateway, a PostgreSQL identity store, and +a high-throughput Valkey session cache, this system aims to deliver +frictionless, zero-trust authentication tailored specifically for a +high-velocity application ecosystem. The architecture explicitly rejects +standard OIDC redirect flows and stateless JWTs. Instead, it relies on a +logic-pure Deno Software Development Kit (SDK) imported directly by subsidiary +applications, which validates stateful session tokens via internal network +routes. Furthermore, the system mandates WebAuthn (passkeys) backed by strict +hardware attestation, mathematically eliminating shared secrets and rendering +traditional credential stuffing and phishing attacks obsolete.\ +This exhaustive analysis evaluates the proposed architecture against modern +enterprise IAM standards, exploring the operational workflows, cryptographic +validation mechanisms, inherent network vulnerabilities, and the advanced +architectural hardening required to elevate this system into an infinitely +scalable enterprise identity fabric. + +## **2\. Core Architectural Components and Perimeter Isolation** + +The structural foundation of the proposed IdP relies on a strict separation of +concerns, decoupling the permanent identity data store from the subsidiary +business applications while maintaining centralized, authoritative control over +session states. + +### **2.1. The API Gateway (Auth Hub)** + +The API Gateway functions as the singular authority for all cryptographic +verifications, WebAuthn challenge generation, and central database transactions. +Operating as an isolated microservice, it exposes REST and gRPC endpoints +exclusively to the internal Docker network. By encapsulating all identity logic +within this central service, subsidiary applications are entirely relieved of +the burden of cryptographic parsing, database connection pooling, and credential +lifecycle management. This establishes a robust zero-trust boundary; if a +subsidiary application is compromised via remote code execution (RCE), the +attacker cannot directly query the central PostgreSQL database or extract public +key materials2. + +### **2.2. The Deno Shared App SDK** + +Instead of forcing each new application to implement complex OIDC redirect +callbacks, developers import a lightweight, logic-pure Deno client library. This +SDK operates as middleware—often implemented via the "onion model" in frameworks +like Oak or Fresh—intercepting incoming HTTP requests to the subsidiary app, +extracting the session token, and transmitting it via a secure internal route to +the Auth API4.\ +Because Deno is secure by default, the execution of this SDK operates within a +strict permissions sandbox. Network access must be explicitly granted via flags +such as \--allow-net, meaning the SDK is structurally constrained and prevented +from leaking session tokens to unauthorized external endpoints, even in the +event of a supply chain compromise7. This drop-in SDK model virtually eliminates +the barrier to implementation for new applications, allowing developers to +secure endpoints with minimal configuration overhead9. + +### **2.3. PostgreSQL Central Identity Store** + +Permanent identity storage, application metadata, and public passkey coordinates +are maintained in a central PostgreSQL relational database. This schema design +guarantees a unified user identity—represented universally by a central +UUID—across the entire application ecosystem. Subsidiary applications maintain +completely independent PostgreSQL databases mapped strictly to this UUID, +preventing schema contamination and data bleeding. This localized mapping is +highly advantageous; if a subsidiary application requires specialized user +profile fields (e.g., localized user preferences or game states), it handles +that mapping internally without requiring schema alterations to the central +IdP11. + +### **2.4. Valkey Session Cache and In-Memory Statefulness** + +The most critical architectural divergence from modern microservice standards is +the reliance on Valkey—an open-source, high-performance key-value store based on +Redis—for session state validation13. When a user successfully authenticates via +WebAuthn, the Auth API issues an opaque session token and stores the +corresponding active state in Valkey. Every subsequent request made to a +subsidiary application forces the App SDK to validate this token against Valkey +via the Auth API. This ensures microsecond-level stateful validation, combining +the speed of in-memory caching with the security of instantaneous session +revocation13. + +### **Table 1: Core System Component Topology** + +| Component | Technology Stack | Primary Function | Security Posture | +| :------------------- | :---------------- | :------------------------------------------------------------------------- | :------------------------------------------------------------------------------ | +| **Auth API Gateway** | Deno (REST/gRPC) | Cryptographic challenge generation, database writes, cache management. | Isolated on internal network; sole component with central DB credentials. | +| **App SDK** | Deno (TypeScript) | Request interception, cookie extraction, RPC routing to Auth API. | Sandboxed via Deno CLI flags (--allow-net=auth-api.internal). | +| **Central Database** | PostgreSQL | Persistent storage of UUIDs, public passkeys, audit logs, and RBAC tables. | Protected behind the Auth API; rejects direct connections from subsidiary apps. | +| **Session Cache** | Valkey | Microsecond validation of opaque stateful session tokens. | In-memory only; cleared upon manual revocation or automated TTL expiry. | + +## **3\. Operational Use Case Flows and Identity Lifecycle** + +The provided operational flows illustrate a highly modular and automated +identity lifecycle, demonstrating how the system handles user provisioning, +credential administration, and session telemetry. + +### **3.1. Provisioning, Invites, and the Authorization Coupling** + +The onboarding flows (Use Cases 1, 2, and 3\) highlight the system's flexibility +in managing user entry. In an open account application (Use Case 1), the App SDK +requests a WebAuthn challenge, the device generates a unique key pair, and the +Auth API creates a UUID, registering the public key and issuing a session.\ +More sophisticated is Use Case 2, which allows users to bypass legacy email +verification via cryptographically secure signup tokens. When a user submits an +invite code, the API provisions the UUID and instantly inserts an authorization +record into the RBAC tables. This tightly couples authentication (verifying who +the user is) with authorization (verifying what the user can do). Because an +authenticated identity does not automatically inherit authorization for all +networked applications, the system maintains the principle of least privilege. +Furthermore, Use Case 3 introduces a manual state machine; the database can +enforce a default "pending" status upon passkey creation, requiring an +administrator to access the central Auth UI and manually toggle the user to +"active" before a session token can be issued. + +### **3.2. Credential Redundancy and Strict Account Recovery** + +Because the system strictly relies on WebAuthn and mathematically rejects shared +secrets, traditional password resets are impossible. If an authenticator is +lost, the user risks permanent account lockout. The architecture addresses this +through redundancy and strict administrative oversight.\ +Use Case 4 highly recommends enrolling multiple passkeys (e.g., a platform +authenticator like a MacBook TouchID and a roaming authenticator like a +YubiKey). When a user with an active session initiates a "Register Device" +action, a new challenge is issued and bound to the existing UUID. If a passkey +is compromised or lost, Use Case 6 dictates that the user or administrator can +select the device nickname for removal. The Auth API executes a SQL DELETE +operation, wiping the public key and credential ID from PostgreSQL, permanently +invalidating the authenticator.\ +If all devices are lost (Use Case 12), the architecture mandates strict +out-of-band administrative intervention. Without static recovery codes, an +administrator must manually execute a database override via the Auth UI to bind +a newly generated WebAuthn challenge to the existing user UUID, ensuring that +social engineering attacks against automated recovery flows are neutralized. + +### **3.3. Multi-Tenant Accounts and Localized Data Mapping** + +Use Case 5 demonstrates the system's capability to support multi-tenant or +multi-persona configurations. The system validates uniqueness based on the +username string, not human identity. If a user registers an alternate username, +the system triggers a new WebAuthn challenge, resulting in a completely distinct +UUID and an independent passkey record. This segregation prevents privilege +escalation bleed, allowing a single human employee to maintain a highly +privileged "Admin" UUID and a restricted "Standard" UUID, fully separated at the +database level.\ +Similarly, Use Case 8 outlines the handling of user profile metadata. A +display\_name exists centrally in the Auth database, modifiable via an Auth API +PATCH endpoint. However, if a subsidiary application requires localized +usernames or domain-specific avatars, it maintains a distinct column in its own +localized PostgreSQL database, mapped back to the central UUID. This enforces +the decoupled nature of the architecture11. + +### **3.4. Infrastructure Topologies and Telemetry** + +The entire environment is orchestrated via Docker Compose (Use Case 9), running +the Valkey, PostgreSQL, Auth API, and Auth UI services. Crucially, Use Case 10 +specifies that all containers share an isolated internal Docker network. +Subsidiary applications deployed on the same server environment attach to this +internal network, allowing the App SDK to resolve the internal endpoint +(auth-api.internal:8000) without exposing the Auth API ports to the public +internet.\ +To maintain security telemetry, Use Case 7 details the session review +architecture. The App SDK can query the Auth API for records associated with a +user's UUID. The API aggregates active session tokens directly from the Valkey +cache alongside historical connection logs (timestamps and IP addresses) stored +in the PostgreSQL audit tables, providing the user with a comprehensive, +formatted list of account activity for proactive security monitoring. + +## **4\. Comparative Analysis: Decoupled API-Backed Sessions vs. Monolithic/Stateless Paradigms** + +To objectively evaluate the efficacy of the proposed SDK-to-API and Valkey +architecture, it must be contrasted against the industry-standard deployments of +monolithic IAM solutions and stateless JWT implementations. + +### **4.1. The Friction of Monolithic IAMs (Keycloak, Authentik, Okta)** + +Standard enterprise solutions are immensely feature-rich but notoriously +complex1. They require the extensive configuration of realms, client IDs, +audiences, scopes, and OIDC mappers. Furthermore, integrating a new application +requires application developers to build or import complex OAuth2 middleware to +handle authorization code flows, token exchanges, and callback URIs.\ +The proposed decoupled architecture bypasses this friction entirely. By +utilizing an internal App SDK that communicates directly with the Auth API over +internal gRPC/REST routes, the system eliminates browser redirects. The +authentication flow is hyper-streamlined: the user authenticates directly via +the central UI, and the resulting opaque session cookie is automatically +transmitted with subsequent requests and processed by the SDK. This drastically +reduces the cognitive load on subsidiary application developers, who simply wrap +their routes in the Deno SDK middleware4. + +### **4.2. Stateful Valkey Sessions vs. Stateless JWT OIDC** + +Modern microservices heavily favor stateless authentication via JSON Web Tokens +(JWTs) because they scale infinitely. Since the JWT contains all necessary user +claims, scopes, and expiration data, and is cryptographically signed by the +IdP's private key, the receiving subsidiary application can validate the token +locally without querying a central server6.\ +However, stateless JWTs suffer from two fatal operational flaws: token bloat and +the inability to be revoked instantly. As RBAC roles and granular claims are +added to a user's profile, the JWT payload increases, degrading HTTP request +performance16. More critically, if a user's device is compromised, a valid JWT +remains active until its expiration timestamp17. To mitigate this, standard +implementations are forced to introduce "blacklists" or centralized revocation +caches, which ironically destroys the stateless nature of the JWT and +reintroduces stateful architectural complexity17.\ +The proposed architecture embraces statefulness via Valkey. Because every +request is validated against the central cache by the SDK, an administrator can +revoke a compromised session, and that revocation propagates globally in +microseconds17. While stateful microservices typically suffer from scalability +bottlenecks and require complex load-balancing configurations like "sticky +sessions," the utilization of an external, high-throughput Valkey cache +decouples the session state from the application instances18. This allows the +Auth API to scale horizontally behind a load balancer; any Auth API instance can +query Valkey to validate the opaque token, ensuring high fault tolerance18. + +### **Table 2: Authentication Architecture Comparison** + +| Feature Category | Monolithic IAM (OIDC / OAuth2) | Stateless JWT Microservices | Proposed Deno \+ Valkey IdP | +| :----------------------- | :------------------------------------------------------------------ | :-------------------------------------------------------------------- | :--------------------------------------------------------------- | +| **Integration Friction** | High (Requires redirect URIs, client scopes, token exchange logic). | Medium (Requires local JWT library, public key distribution). | Low (Import pure-logic Deno SDK, provide Application Secret). | +| **Session Revocation** | Delayed (Relies on short-lived access tokens and refresh flows). | Impossible / Highly Complex (Requires distributed blacklist caches). | Instantaneous (Microsecond deletion from Valkey cache). | +| **Token Payload Size** | Large (Bloated with claims, roles, and audience data). | Large (Prone to header/payload token bloat). | Minimal (Opaque string representing a key in Valkey). | +| **Scalability Limiters** | Database read bottlenecks during token generation/refresh. | Cryptographic CPU overhead for constant local signature verification. | Network I/O latency between subsidiary SDK and Central Auth API. | +| **Phishing Resistance** | Optional (Can support FIDO2, but often falls back to passwords). | N/A (JWTs are post-authentication artifacts). | Enforced (Strict hardware-bound WebAuthn requirements). | + +## **5\. Deep Dive: Cryptographic Security and Advanced WebAuthn Mechanics** + +The proposed architecture achieves a zero-trust posture not merely through +internal network isolation, but by strictly enforcing modern cryptographic +authentication standards. By completely excising passwords and SMS-based +multi-factor authentication, the system immunizes itself against the vast +majority of identity-based attacks. + +### **5.1. Phishing Resistance and Asymmetric Cryptography** + +Traditional authentication relies on shared secrets. If an attacker breaches a +server, hashed secrets can be cracked offline. If an attacker hosts a replica +phishing website, the user unwittingly transmits the secret. The proposed +architecture eliminates this via WebAuthn passkeys19.\ +During registration, the user's authenticator device (e.g., a YubiKey or a TPM +module) generates an asymmetric key pair using an elliptic curve algorithm +(e.g., ES256). The private key never leaves the secure hardware boundary of the +device. The Auth API receives and stores only the public key. During +authentication, the API issues a random cryptographic challenge, and the device +signs this challenge using the private key20. Because there is no secret +transmitted over the wire, credential stuffing, password spraying, and database +leak exploitation are mathematically impossible20. + +### **5.2. Cryptographic Origin Binding and Cross-Domain Passkeys** + +Passkeys are structurally bound to the Relying Party ID (the domain string). If +a user registers a passkey on auth.internal.corp, the browser will +cryptographically refuse to assert that passkey on a lookalike phishing site +like auth-internal.corp19. The signature changes with the origin, ensuring the +credential cannot be hijacked.\ +However, enterprise architectures frequently utilize multiple domains and +subdomains. A company with app1.corp and app2.corp ideally wants a single +passkey to authenticate across both, without requiring the user to register a +new credential for every subsidiary application. Under the original WebAuthn +specification, this was impossible19.\ +To solve this, the architecture must implement **Related Origin Requests +(ROR)**21. ROR allows a Relying Party to specify a list of authorized origins +that can utilize its passkeys21. The Auth API must host a JSON document at the +WebAuthn well-known path (/.well-known/webauthn) on the primary domain21.\ +For example, if the central IDP is auth.corp, the document hosted at +https://auth.corp/.well-known/webauthn would contain: + +JSON\ +{\ +"origins": \[\ +"https://app1.corp",\ +"https://app2.corp"\ +\]\ +} + +During a WebAuthn ceremony on app1.corp, if the Relying Party ID is declared as +auth.corp, the browser will query the central well-known URL. The browser +processes the origin list and re-evaluates the binding, permitting the passkey +assertion to proceed21. The App SDK facilitates this parameter negotiation, +ensuring a seamless Single Sign-On (SSO) experience across the enterprise +ecosystem without breaking strict cryptographic origin binding21. + +### **5.3. Hardware Attestation Strictness and FIDO MDS3 Verification** + +A pivotal feature of this architecture is the configuration toggle to forcefully +reject software-based passkeys (e.g., Bitwarden, iCloud Keychain, Windows Hello) +in favor of certified hardware credentials (e.g., YubiKey 5 Series). Software +passkeys can be copied, synced across devices, and exfiltrated, breaking the +non-repudiation guarantees required by high-security environments24. Restricting +authentication to device-bound hardware is achieved through Authenticator +Attestation25.\ +During the WebAuthn registration ceremony, an authenticator can provide an +attestation statement containing an Authenticator Attestation GUID (AAGUID). The +AAGUID is a 128-bit UUID (e.g., xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) that +uniquely designates the specific hardware model, manufacturer, and firmware +version26. Furthermore, the attestation object includes an x5c certificate chain +generated by an intermediate certificate authority (CA) and imported by the +manufacturer during production25.\ +To enforce strict hardware compliance, the Auth API Gateway must integrate +deeply with the **FIDO Alliance Metadata Service (MDS3)**29. The MDS3 BLOB is a +cryptographically signed JSON web token (JWT) containing a catalog of trusted +AAGUIDs, biometric status reports, and their corresponding root certificates29.\ +The API Gateway must perform the following cryptographic sequence during user +onboarding: + +> 1. **Extract the AAGUID:** Parse the CBOR-encoded attestationObject from the +> user's registration payload to extract the 16-byte AAGUID26. +> 2. **Verify the MDS3 BLOB Signature:** Ensure the locally cached FIDO MDS3 +> BLOB has a valid signature chaining to the FIDO root trust anchor29. +> 3. **Build the Certificate Chain:** Extract the x5c leaf certificate from the +> user's attestation response, append the intermediate certificates, and +> terminate the chain at the specific root certificate mapped to the AAGUID +> inside the MDS3 BLOB33. +> 4. **Check Revocation:** Verify that the AAGUID is not listed in the +> statusReports as compromised, revoked, or possessing outdated firmware31. + +If the device self-attests (as software passkeys do, providing no x5c chain), if +the signature fails to verify, or if the AAGUID is not present on the enterprise +allow-list, the API immediately aborts the registration and returns a 403 +Forbidden24. + +### **Table 3: Hardware Attestation Cryptographic Verification Flow** + +| Component | Cryptographic Function | Security Implication | +| :----------------- | :--------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- | +| **AAGUID** | 128-bit identifier embedded in the WebAuthn authData. Probability of collision is ![][image1]. | Maps the credential to a specific hardware model, allowing policies to block unapproved or vulnerable devices26. | +| **x5c Chain** | Digital certificate chain appended to the attestation object during registration. | Proves the provenance of the hardware; mathematically prevents attackers from spoofing AAGUIDs using custom software authenticators25. | +| **FIDO MDS3 BLOB** | Signed repository of trusted authenticator metadata statements published by the FIDO Alliance. | Provides the trust anchors (Root CAs) required to cryptographically validate the x5c chain during user onboarding29. | + +## **6\. Vulnerability Assessment and Scaling Limitations** + +While the architecture brilliantly resolves the severe flaws of monolithic IAMs +and stateless JWTs, funneling hundreds of internal applications through a +central API utilizing stateful session validation introduces unique attack +vectors and structural vulnerabilities that must be addressed. + +### **6.1. Network Bottlenecks and Chatty Architecture Latency** + +The most critical structural vulnerability of this system is network latency +induced by a "chatty" architecture. If 100 subsidiary applications each receive +1,000 HTTP requests per second, the App SDK must fire 100,000 synchronous +internal API requests per second to the API Gateway to validate the stateful +session cookies18. Even though the Valkey database operates in microseconds, the +sheer volume of TCP connection handshakes, HTTP overhead, and payload parsing +traversing the internal Docker network will eventually saturate the network +interface, resulting in cascading timeout failures18. Without mitigation, this +creates a massive internal distributed denial-of-service (DDoS) risk under +normal high-load operating conditions. + +### **6.2. Internal Network Sniffing and Lateral Movement** + +The documentation outlines that all containers share an isolated internal Docker +network, effectively creating a perimeter (Use Case 10). While this prevents +ingress from the public internet, it relies on a perimeter defense model, +assuming a zero-trust fallacy _inside_ the network. If a single subsidiary +application is compromised via a vulnerability, the attacker gains a foothold +inside the Docker network. If the SDK-to-API communication occurs over +unencrypted HTTP, the attacker can use packet sniffing tools (e.g., tcpdump) to +intercept active, stateful session cookies traversing the network. Because the +cookies are opaque bearer tokens, the attacker can replay them to impersonate +administrators across other internal applications, enabling devastating lateral +movement. + +### **6.3. Cache Exhaustion and Valkey Denial of Service (DoS)** + +Valkey, functioning as an in-memory datastore, is fundamentally constrained by +available RAM13. If an attacker discovers an unprotected endpoint on a +subsidiary application that generates a new session token (e.g., rapidly calling +the login or invite provision endpoint), they can flood the Auth API with +fraudulent authentication requests. The API will continually write new session +records into Valkey. Once the host machine's RAM is exhausted, Valkey will crash +or begin aggressively evicting active user sessions, leading to an Out-Of-Memory +(OOM) failure and a system-wide catastrophic outage for all authenticated users. + +### **6.4. SDK Subversion and Supply Chain Risks** + +Because the SDK is distributed to subsidiary applications, a malicious developer +or a compromised third-party dependency in a subsidiary app could theoretically +subvert the SDK's execution environment. In a standard Node.js environment, +third-party dependencies have unfettered access to the file system, network, and +environment variables. If a malicious NPM package is imported alongside the SDK, +it could extract the Application Secret used to authenticate the SDK to the API, +allowing the attacker to spoof validation requests or exfiltrate session data to +an external server. + +## **7\. Architectural Improvements and Enterprise Hardening** + +To transform this system into a highly resilient, enterprise-grade IAM fabric +capable of rivaling global tech leaders, specific architectural mechanisms must +be implemented to harden the network and mitigate the identified +vulnerabilities. + +### **7.1. Valkey Client-Side Caching with RESP3 Invalidation** + +To solve the "chatty architecture" bottleneck, the system must abandon the +paradigm of querying the central Auth API on every single HTTP request. Instead, +the Auth API and the Deno SDK should implement **Valkey Client-Side Caching** +utilizing the RESP3 protocol and Pub/Sub mechanics14.\ +When the Deno App SDK requests session validation from the API Gateway, the SDK +should cache the valid result (including RBAC scopes) in its local, in-memory +heap for a short duration15. Simultaneously, the Auth API utilizes Valkey's +CLIENT TRACKING feature with the OPTIN configuration15. If an administrator +revokes a user's session, the Auth API deletes the key in Valkey. Valkey +immediately broadcasts an invalidation message over a Pub/Sub channel to the +Auth API14. The API Gateway then pushes a gRPC stream update to the connected +App SDKs, instructing them to instantly drop the specific local cache entry14.\ +This architecture yields a monumental performance gain: 99% of requests are +validated in nanoseconds locally within the SDK (rivaling the speed of stateless +JWTs), while preserving the instantaneous, microsecond-revocation capability of +a centralized stateful system. + +### **7.2. gRPC with HTTP/2 Multiplexing** + +The SDK-to-API communication must strictly enforce the use of gRPC rather than +REST. REST relies on HTTP/1.1, which traditionally requires establishing a new +TCP connection for requests or dealing with head-of-line blocking. gRPC utilizes +HTTP/2, which supports multiplexing—allowing hundreds of concurrent session +validation requests to be streamed asynchronously over a single persistent TCP +connection35. Furthermore, gRPC uses Protocol Buffers (Protobuf) for binary +serialization, drastically reducing the payload size compared to standard JSON +text transmission35. This will effectively eliminate the internal network +congestion caused by high-throughput subsidiary applications. + +### **7.3. Strict Deno Sandboxing and Execution Constraints** + +The decision to utilize Deno provides a massive security advantage over Node.js, +provided its security sandbox is strictly enforced. The subsidiary applications +running the SDK must never be executed with the \-A or \--allow-all flag, which +completely disables the sandbox7.\ +The execution environment must be tightly constrained using granular CLI flags: + +- \--allow-net=auth-api.internal:8000: This explicitly restricts the SDK to only + communicate with the central Auth API8. Even if the application is compromised + by malware, the malware cannot exfiltrate the Application Secret or session + tokens to an external command-and-control server, because the Deno runtime + will intercept and block the outbound connection at the system level38. +- \--deny-read and \--deny-env: These flags explicitly restrict file system and + environment access. By denying access to /etc/ or .env files, the system + ensures that only explicitly defined variables (like the SDK configuration) + can be loaded into memory, neutralizing supply chain attacks attempting to + scrape disk credentials39. +- \--allow-ffi: Must be strictly avoided or heavily audited, as loading dynamic + C/C++ libraries bypasses the JavaScript sandbox entirely, allowing native code + to issue system calls directly to the OS7. + +### **Table 4: Recommended Deno Runtime Sandbox Configurations** + +| Deno CLI Flag | Operational Purpose | Threat Mitigation | +| :----------------------------- | :------------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | +| \--allow-net=auth-api.internal | Permits communication exclusively to the Auth API gateway39. | Prevents malware from exfiltrating session tokens to public internet endpoints8. | +| \--deny-read=/app/secrets | Blocks read access to specific directories or files7. | Prevents third-party dependencies from scraping disk for application configuration secrets. | +| \--allow-env=AUTH\_URL | Restricts access to a whitelist of required environment variables37. | Blocks malware from dumping the entire environment tree containing DB passwords or API keys. | +| \--allow-all / \-A | **Strictly Prohibited.** Disables the sandbox entirely7. | Ensures the runtime retains its security advantages over traditional Node.js environments8. | + +### **7.4. Internal mTLS via SPIFFE/SPIRE for Zero-Trust Networking** + +To neutralize the threat of internal network sniffing and lateral movement, +Docker network isolation is insufficient. The architecture must implement mutual +Transport Layer Security (mTLS) for all communications between the Deno SDK and +the API Gateway3.\ +By deploying a framework like SPIFFE/SPIRE, localized cryptographic certificates +are distributed to the subsidiary containers. When the SDK initiates a gRPC +connection, the API Gateway cryptographically verifies the identity of the +calling application before processing the request, and the traffic is heavily +encrypted3. This achieves true zero-trust; an attacker sitting on the internal +Docker network capturing packets will only intercept unintelligible ciphertext, +rendering session hijacking and API spoofing impossible. + +### **7.5. Network Rate Limiting and Edge Protection** + +To prevent Valkey cache exhaustion and Out-Of-Memory failures, the Auth API must +implement rigorous, multi-layered rate limiting. Valkey itself should be +utilized to track authentication attempts and issue exponential backoffs13. Rate +limits must be applied dynamically at the IP level, the user UUID level, and the +App SDK level. By establishing a maximum threshold of session generation +requests per minute, the system mathematically bounds the maximum RAM footprint +that can be consumed in a given window, protecting the in-memory cache from +intentional exhaustion. + +## **8\. Conclusion** + +The proposed decoupled Identity Provider architecture represents a highly +sophisticated, developer-friendly approach to enterprise authentication. By +fundamentally rejecting the legacy complexities of OpenID Connect and the +critical security flaws of stateless JWTs, the system achieves a rare +equilibrium between high usability and stringent security. The strict +enforcement of WebAuthn and AAGUID hardware attestation ensures a +cryptographically pristine, phishing-proof boundary against external threats, +mathematically eliminating the vulnerabilities associated with shared secrets.\ +However, the architectural transition to a centralized, stateful session model +shifts the burden of performance directly onto the internal network and the +Valkey cache. To realize the ambitious goal of an authentication system that +scales beyond current industry gold standards with a fraction of the complexity, +the architecture must implement advanced network optimizations. By adopting +Valkey RESP3 client-side caching to eliminate repetitive network I/O, enforcing +gRPC multiplexing for high-throughput communication, deploying strict Deno +runtime permissions to neutralize supply chain attacks, and blanketing the +internal network in mTLS, this architecture will transcend its theoretical +potential. It will yield a system that offers the infinite horizontal +scalability of a stateless architecture, the instantaneous revocation +capabilities of a stateful monolith, and an impenetrable zero-trust security +posture. + +#### **Works cited** + +> 1. Authentik vs Keycloak: where identity providers stop short, +> [https://nhimg.org/community/nhi-best-practices/authentik-vs-keycloak-where-identity-providers-stop-short/](https://nhimg.org/community/nhi-best-practices/authentik-vs-keycloak-where-identity-providers-stop-short/) +> 2. Zero Trust Security | What's a Zero Trust Network? \- Cloudflare, +> [https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/](https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/) +> 3. Modernizing Database Authentication: CockroachDB Embraces Zero Trust with +> SPIFFE and SPIRE Support, +> [https://www.cockroachlabs.com/blog/zero-trust-database-authentication-spiffe-spire/](https://www.cockroachlabs.com/blog/zero-trust-database-authentication-spiffe-spire/) +> 4. How to Implement Middleware in Deno \- OneUptime, +> [https://oneuptime.com/blog/post/2026-01-31-deno-middleware/view](https://oneuptime.com/blog/post/2026-01-31-deno-middleware/view) +> 5. How to Setup Auth with Fresh | Deno, +> [https://deno.com/blog/setup-auth-with-fresh](https://deno.com/blog/setup-auth-with-fresh) +> 6. How to Implement JWT Authentication for CRUD APIs in Deno \- LoginRadius, +> [https://www.loginradius.com/blog/engineering/guest-post/how-to-implement-jwt-authentication-in-deno](https://www.loginradius.com/blog/engineering/guest-post/how-to-implement-jwt-authentication-in-deno) +> 7. Security and permissions | Deno Docs, +> [https://docs.deno.com/runtime/fundamentals/security/](https://docs.deno.com/runtime/fundamentals/security/) +> 8. How Deno protects against npm exploits, +> [https://deno.com/blog/deno-protects-npm-exploits](https://deno.com/blog/deno-protects-npm-exploits) +> 9. Custom Oak middleware in Deno | Tech Tonic \- Medium, +> [https://medium.com/deno-the-complete-reference/custom-oak-middleware-in-deno-8b2b3289b40e](https://medium.com/deno-the-complete-reference/custom-oak-middleware-in-deno-8b2b3289b40e) +> 10. How to Implement JWT Authentication in Deno \- OneUptime, +> [https://oneuptime.com/blog/post/2026-01-31-deno-jwt-authentication/view](https://oneuptime.com/blog/post/2026-01-31-deno-jwt-authentication/view) +> 11. Stateless vs. Stateful Architecture: A Comprehensive Comparison | AutoMQ +> Blog, +> [https://www.automq.com/blog/stateless-vs-stateful-architecture-a-comprehensive-comparison](https://www.automq.com/blog/stateless-vs-stateful-architecture-a-comprehensive-comparison) +> 12. Securing Web Applications: Stateful vs. Stateless Systems, Authentication, +> and Authorization in Node.js \- DEV Community, +> [https://dev.to/imsushant12/securing-web-applications-stateful-vs-stateless-systems-authentication-and-authorization-in-nodejs-b1m](https://dev.to/imsushant12/securing-web-applications-stateful-vs-stateless-systems-authentication-and-authorization-in-nodejs-b1m) +> 13. From caching to real-time analytics: Essential use cases for Amazon +> ElastiCache for Valkey, +> [https://aws.amazon.com/blogs/database/from-caching-to-real-time-analytics-essential-use-cases-for-amazon-elasticache-for-valkey/](https://aws.amazon.com/blogs/database/from-caching-to-real-time-analytics-essential-use-cases-for-amazon-elasticache-for-valkey/) +> 14. Spring Boot Caching With Valkey or Redis: A Complete @Cacheable Guide, +> [https://redisson.pro/blog/spring-boot-caching-with-valkey-redis-a-complete-cacheable-guide.html](https://redisson.pro/blog/spring-boot-caching-with-valkey-redis-a-complete-cacheable-guide.html) +> 15. Documentation: Client-side caching \- Valkey, +> [https://valkey.io/topics/client-side-caching/](https://valkey.io/topics/client-side-caching/) +> 16. Stateless Authentication: Understanding Token-Based Auth \- Descope, +> [https://www.descope.com/learn/post/stateless-authentication](https://www.descope.com/learn/post/stateless-authentication) +> 17. Stateful vs Stateless Authentication Explained Clearly \- Medium, +> [https://medium.com/@captain-uchiha/stateful-vs-stateless-authentication-explained-clearly-7c9fd647c3a7](https://medium.com/@captain-uchiha/stateful-vs-stateless-authentication-explained-clearly-7c9fd647c3a7) +> 18. Stateful vs. stateless architecture for scalable systems explained \- +> Aerospike, +> [https://aerospike.com/blog/stateful-vs-stateless-architecture-guide/](https://aerospike.com/blog/stateful-vs-stateless-architecture-guide/) +> 19. Cryptographic origin binding: How passkeys make phishing structurally +> impossible, +> [https://workos.com/blog/cryptographic-origin-binding](https://workos.com/blog/cryptographic-origin-binding) +> 20. Web Authentication API \- MDN Web Docs \- Mozilla, +> [https://developer.mozilla.org/en-US/docs/Web/API/Web\_Authentication\_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) +> 21. Related Origin Requests \- passkeys.dev, +> [https://passkeys.dev/docs/advanced/related-origins/](https://passkeys.dev/docs/advanced/related-origins/) +> 22. Allow passkey reuse across your sites with Related Origin Requests \- +> web.dev, +> [https://web.dev/articles/webauthn-related-origin-requests](https://web.dev/articles/webauthn-related-origin-requests) +> 23. Deep Dive: Relying Party ID & origin (Passkeys) \- Duende Software, +> [https://duendesoftware.com/blog/20251014-deep-dive-into-relying-party-id-and-origin-with-passkeys](https://duendesoftware.com/blog/20251014-deep-dive-into-relying-party-id-and-origin-with-passkeys) +> 24. FIDO Metadata Service \- Identity Provider Plugins \- Confluence, +> [https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3878944780](https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3878944780) +> 25. WebAuthn Attestation: How a Site Knows What Made Your Passkey | Haven +> Blog, +> [https://havenmessenger.com/blog/posts/webauthn-fido2-attestation-explained/](https://havenmessenger.com/blog/posts/webauthn-fido2-attestation-explained/) +> 26. AAGUID (Authenticator Attestation GUID) | Definition \- CardLogix, +> [https://www.cardlogix.com/glossary/aaguid-authenticator-attestation-guid-fido2-passkey-webauthn/](https://www.cardlogix.com/glossary/aaguid-authenticator-attestation-guid-fido2-passkey-webauthn/) +> 27. FIDO Metadata Statement, +> [https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.1-ps-20250521.html](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.1-ps-20250521.html) +> 28. WebAuthn Attestation and Authenticator Metadata \- Yubico Developers, +> [https://developers.yubico.com/Developer\_Program/WebAuthn\_Starter\_Kit/Attestation.html](https://developers.yubico.com/Developer_Program/WebAuthn_Starter_Kit/Attestation.html) +> 29. FIDO Metadata Service, +> [http://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html](http://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html) +> 30. FIDO Metadata Service (MDS) Overview \- FIDO Alliance, +> [https://fidoalliance.org/metadata/](https://fidoalliance.org/metadata/) +> 31. FIDO Metadata Service, +> [https://fidoalliance.org/specs/mds/fido-metadata-service-v3.1-ps-20250521.html](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.1-ps-20250521.html) +> 32. FIDO Metadata Service (MDS) \- Yubico Developers, +> [https://developers.yubico.com/WebAuthn/Concepts/FIDO\_Metadata\_Service\_(MDS).html](https://developers.yubico.com/WebAuthn/Concepts/FIDO_Metadata_Service_(MDS).html) +> 33. WebAuthn/FIDO2: Verifying TPM Attestation | by Ackermann Yuriy \- Medium, +> [https://medium.com/webauthnworks/verifying-fido-tpm2-0-attestation-fc7243847498](https://medium.com/webauthnworks/verifying-fido-tpm2-0-attestation-fc7243847498) +> 34. Web Authentication: An API for accessing Public Key Credentials \- Level 2 +> \- W3C, +> [https://www.w3.org/TR/webauthn-2/](https://www.w3.org/TR/webauthn-2/) +> 35. gRPC vs. REST \- Postman Blog, +> [https://blog.postman.com/grpc-vs-rest/](https://blog.postman.com/grpc-vs-rest/) +> 36. CLIENT CACHING \- Valkey Command, +> [https://valkey.io/commands/client-caching/](https://valkey.io/commands/client-caching/) +> 37. Deno allow all permissions \- Stack Overflow, +> [https://stackoverflow.com/questions/61878523/deno-allow-all-permissions](https://stackoverflow.com/questions/61878523/deno-allow-all-permissions) +> 38. How can I enforce a security sandbox with any process?, +> [https://security.stackexchange.com/questions/257801/how-can-i-enforce-a-security-sandbox-with-any-process](https://security.stackexchange.com/questions/257801/how-can-i-enforce-a-security-sandbox-with-any-process) +> 39. Permissions \- Deno Docs, +> [https://docs.deno.com/runtime/reference/permissions/](https://docs.deno.com/runtime/reference/permissions/) +> 40. Introducing Deno Sandbox, +> [https://deno.com/blog/introducing-deno-sandbox](https://deno.com/blog/introducing-deno-sandbox) +> 41. Deno's Networking and File Permissions Model | Reflect, +> [https://reflect.run/articles/deno-networking-and-file-permissions-model/](https://reflect.run/articles/deno-networking-and-file-permissions-model/) + +[image1]: diff --git a/deps.ts b/deps.ts new file mode 100644 index 0000000..d34d0a3 --- /dev/null +++ b/deps.ts @@ -0,0 +1,12 @@ +// Pre-cached dependencies for Auth-Yes Docker build caching +import "jsr:@hono/hono@4"; +import "jsr:@hono/hono@4/deno"; +import "jsr:@hono/hono@4/cookie"; +import "jsr:@simplewebauthn/server@13"; +import "jsr:@std/encoding@1/base64url"; +import "npm:ioredis@6"; +import "npm:postgres@3"; +import "npm:@peculiar/x509@1"; +import "@bufbuild/protobuf"; +import "@connectrpc/connect"; +import "@connectrpc/connect-node"; diff --git a/docs/Custom IAM Architecture Analysis v2.md b/docs/Custom IAM Architecture Analysis v2.md new file mode 100644 index 0000000..f40b8a4 --- /dev/null +++ b/docs/Custom IAM Architecture Analysis v2.md @@ -0,0 +1,455 @@ +# Custom IAM Architecture Analysis v2.md + +# Architectural Blueprint & Enterprise Implementation Roadmap: Decoupled Zero-Trust Identity Fabric + +## 1. Executive Summary & Paradigm Evolution + +The **Auth-Yes** Identity Fabric represents an ultra-low-friction, zero-trust +Identity and Access Management (IAM) system tailored for a high-velocity +microservice ecosystem. By rejecting the protocol bloat, redirect friction, and +configuration overhead of traditional OIDC/OAuth2 monoliths (e.g., Keycloak, +Authentik, Okta), Auth-Yes delivers microsecond-level stateful session +verification, phishing-proof WebAuthn passkey authentication, and cryptographic +workload identity. + +### Key Refinements in v2 Architecture: + +1. **Parent-Domain WebAuthn Scoping (`RP_ID=atyg.org`):** + - Eliminates the runtime complexity of Related Origin Requests (ROR) for the + primary domain ecosystem. All subdomains across `*.atyg.org` natively share + passkeys and session verification. +2. **Three-Tier Defense-in-Depth Model:** + - **Tier 1 (Global Edge Default):** Universal Traefik ForwardAuth perimeter + fallback protecting untagged/pre-release services. + - **Tier 2 (Edge Proxy Override):** ForwardAuth cookie validation for + legacy/third-party applications (Portainer, Grafana, admin consoles). + - **Tier 3 (Application Zero-Trust):** In-app Deno App SDK communicating over + high-throughput ConnectRPC / gRPC with SPIFFE/SPIRE mTLS identity and + granular application RBAC. +3. **Structured Token Provisioning Taxonomy:** + - Formalized 3-tier invite token architecture (Global Admin, Site-Scoped, and + Open/Pending) alongside Out-of-Band Account Recovery. +4. **Complete Administrative Console Roadmap:** + - Finalized UI specifications for Application Registration (`/admin/apps`), + Multi-Type Invite Provisioning (`/admin/invites`), and Granular User RBAC + Grant Management (`/admin/users/:id`). + +--- + +## 2. Core Security Architecture & Defense-in-Depth Layering + +Auth-Yes implements a strict multi-layered defense model ensuring that neither +network locality nor perimeter isolation is treated as an implicit proxy for +trust. + +``` + [ Public Internet / Client Browser ] + │ + ▼ + ═══════════════════════════════════════════════════ + TIER 1 & 2: Traefik Reverse Proxy & ForwardAuth Edge + ═══════════════════════════════════════════════════ + │ │ +(Legacy/3rd-Party Apps) (Native Microservices) +[ Portainer / Web UIs ] [ ed-droid Web Edge ] + │ │ + ▼ ▼ +ForwardAuth Interception Traefik TLS Ingress +GET /api/forward-auth PassTLSClientCert +(Valkey Cache Lookup) │ + │ ▼ + └──────────────────────────────► ═══════════════════════════ + TIER 3: Zero-Trust App Mesh + ConnectRPC + SPIFFE / mTLS + ═══════════════════════════ + │ + ▼ + [ Auth-Yes Core Gateway ] + - Valkey Cache (L1/L2) + - PostgreSQL Store + - Default-Deny RBAC +``` + +### 2.1. Tier 1 — Global Edge Perimeter (Traefik ForwardAuth Default Fallback) + +- **Objective:** Ensure zero accidental exposure of internal or pre-release + services. +- **Mechanism:** Traefik entrypoints (e.g., `websecure`) are configured with a + default ForwardAuth middleware. Any newly created container or untagged + service deployed on the internal network is protected by default. +- **Behavior:** Unauthenticated HTTP requests without a valid session cookie are + automatically redirected to `https://auth.atyg.org/login`. + +### 2.2. Tier 2 — Edge Proxy Override (Third-Party & Legacy Applications) + +- **Objective:** Secure off-the-shelf and legacy software (e.g., Portainer, + Grafana, PgAdmin) without requiring code modifications or custom SDK + integration. +- **Mechanism:** Traefik routers for these services explicitly route + authentication checks to `https://auth.atyg.org/api/forward-auth`. +- **Validation Flow:** + 1. Client sends request with `session_id` cookie scoped to `.atyg.org`. + 2. Traefik queries `auth-api:8000/api/forward-auth`. + 3. Auth API checks Valkey in microseconds. If valid and account is active, + returns HTTP `200 OK` and injects upstream identity headers: + - `X-Forwarded-User: ` + - `X-Forwarded-User-Id: ` + 4. If invalid or missing, returns HTTP `401 Unauthorized` or redirects to + login. + +### 2.3. Tier 3 — Application-Level Zero-Trust (Deno App SDK + ConnectRPC + SPIFFE/mTLS) + +- **Objective:** Provide high-throughput, microsecond-latency identity + validation with granular Role-Based Access Control (RBAC) for native + microservices. +- **Mechanism:** + - Subsidiary services import the logic-pure `@ed-droid/auth-yes/sdk` + middleware. + - The SDK intercepts requests, extracts the session token, and validates it + against the Auth Hub using **ConnectRPC / gRPC** over HTTP/2 multiplexed + connections. + - **Workload Cryptographic Attestation:** Workload identity is authenticated + via **SPIFFE/SPIRE x509 SVID certificates**. The Auth Hub validates the + calling application's SPIFFE ID (e.g., + `spiffe://system.local/ed-droid-backend`) against the `apps` table. + - **Default-Deny Authorization:** Authentication (who the user is) is + decoupled from authorization (what app they can access). The Auth Hub + verifies that an explicit active record exists in the `grants` table + matching `(user_id, app_id)`. + +--- + +## 3. WebAuthn Scope Mechanics: Parent Domain vs. Related Origin Requests (ROR) + +### 3.1. Parent Domain Scoping (`RP_ID=atyg.org`) + +In the W3C WebAuthn specification, a credential is bound to a Relying Party +Identifier (`RP_ID`). + +- Under WebAuthn origin validation rules, an `RP_ID` can be set to any + **registrable domain suffix (eTLD+1)** of the origin. +- By setting: + ```env + RP_ID=atyg.org + ORIGIN=https://auth.atyg.org + ``` +- **Result:** Any passkey created under `RP_ID=atyg.org` is cryptographically + valid and authenticatable across **all** subdomains under `*.atyg.org` (e.g., + `auth.atyg.org`, `ed-droid.atyg.org`, `nas.atyg.org`). +- **Browser Compliance:** Supported natively across 100% of modern WebAuthn + implementations (Apple Safari/iOS, Google Chrome/Android, Windows Hello, + 1Password, YubiKeys). + +### 3.2. Session Cookie Cross-Subdomain Sharing + +To support edge proxy interception (ForwardAuth Tier 1 & 2), the Auth Hub sets +the session cookie with domain wildcard scoping: + +```ts +setCookie(c, "session_id", sessionId, { + domain: ".atyg.org", + httpOnly: true, + secure: true, + sameSite: "Lax", + expires: expiresAt, +}); +``` + +This ensures the browser transmits the session cookie seamlessly to all +subdomains under `*.atyg.org`. + +### 3.3. Future Scope: Related Origin Requests (ROR) + +Dynamic Related Origin Requests via `https://auth.atyg.org/.well-known/webauthn` +are officially archived for **Phase 3 (Cross-TLD Expansion)**. ROR will only be +required when federating authentication across completely distinct root domains +(e.g., bridging `atyg.org` with `ed-droid.io` or `independent-domain.com`). + +--- + +## 4. Identity Lifecycle & Token Provisioning Taxonomy + +Auth-Yes implements a strict 3-tier invite provisioning architecture ensuring +mathematical control over user onboarding and access grants. + +``` + ┌────────────────────────────────────────┐ + │ Admin Onboarding Generator │ + └───────────────────┬────────────────────┘ + │ + ┌───────────────────────────────┼──────────────────────────────┐ + ▼ ▼ ▼ +┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ +│ Type 1: Global │ │ Type 2: Site │ │ Type 3: General │ +│ Admin Invite │ │ Scoped Invite │ │ Open / Pending │ +├──────────────────┤ ├──────────────────┤ ├──────────────────┤ +│ app_id: NULL │ │ app_id: UUID │ │ app_id: NULL │ +│ role: 'admin' │ │ role: 'user/adm' │ │ role: 'user' │ +│ status: 'active' │ │ status: 'active' │ │ status: 'pending'│ +└──────────────────┘ └──────────────────┘ └──────────────────┘ +``` + +### 4.1. Type 1: Global Admin Onboarding Token + +- **Purpose:** Initial system bootstrapping and administrative team onboarding. +- **Characteristics:** `app_id` is unbound (`NULL` or Management Console), + `role = 'admin'`. +- **Lifecycle:** User registers passkey $\rightarrow$ Account is set to `active` + $\rightarrow$ User is granted global administrative privileges across Auth-Yes + and all internal systems. + +### 4.2. Type 2: Site-Scoped Onboarding Token + +- **Purpose:** Controlled user onboarding for a specific subsidiary application + (e.g., `ed-droid`). +- **Characteristics:** `app_id` is locked to a specific application UUID, + `role = 'user'` (or application admin). +- **Lifecycle:** User registers passkey $\rightarrow$ Account is set to `active` + $\rightarrow$ System automatically inserts a grant record into + `grants (user_id, app_id, role)`. User can access the designated application + immediately, but is denied access to all other apps. + +### 4.3. Type 3: General Open / Pending Registration Token + +- **Purpose:** Broad community or team registration requiring manual + verification. +- **Characteristics:** `app_id: NULL`, `role = 'user'`, initial + `account_status = 'pending'`. +- **Lifecycle:** User registers passkey $\rightarrow$ Account is created in + `pending` state $\rightarrow$ User cannot log in until a Global Admin accesses + `/admin/users` and activates the account, optionally assigning specific + application grants. + +### 4.4. Out-of-Band Single-Use Account Recovery Token + +- **Purpose:** Lockout recovery when a user loses all registered hardware + passkeys. +- **Characteristics:** 24-hour time-limited cryptographic token linked to + existing `user_id`. +- **Lifecycle:** Admin generates recovery link in `/admin/users/:id` + $\rightarrow$ Transmitted out-of-band $\rightarrow$ User accesses + `/recovery?code=...` $\rightarrow$ User binds new hardware passkey + $\rightarrow$ Previous passkeys invalidated, existing UUID and application + grants preserved. + +### 4.5. The RBAC Grant Lifecycle: Default-Deny, Assignment Matrix & RPC Payload + +The identity fabric enforces strict decoupled authorization governed by three +continuous states: + +1. **The Baseline (Default-Deny Zero-Trust):** + - When a user registers a passkey or when an admin provisions an account, the + user possesses **zero application access by default**. + - If an unassigned user attempts to authenticate to `ed-droid.atyg.org`, the + calling application SDK queries the central `AuthService.validateSession` + endpoint over ConnectRPC. + - The Auth Hub queries + `SELECT role FROM grants WHERE user_id = $1 AND app_id = $2`. Finding no + matching grant record, the server returns + `{ valid: false, uuid: "", scopes: [], error: "Validation failed" }`, + resulting in an instant `403 Forbidden: No explicitly granted roles`. + +2. **The Assignment Matrix (Admin Console):** + - In `https://auth.atyg.org/admin`: + - Under **Applications** (`/admin/apps`), apps are registered (e.g. + `ed-droid`, SPIFFE ID `spiffe://system.local/ed-droid-backend`). + - Under **User Profile** (`/admin/users/:id`), the administrator views the + user's active permissions matrix. + - To grant access to a user (e.g., your nephew), the administrator selects + `ed-droid` from the app selector, selects a role (`viewer`, `operator`, + `editor`, `admin`), and clicks **Grant Access** (or checks the matrix + toggle). + - An atomic row is written to `grants (user_id, app_id, role)`. + +3. **The Payload & Runtime Authorization:** + - The next time the user makes a request to `ed-droid`, the Deno App SDK + intercepts the session token and validates it via ConnectRPC over internal + mTLS. + - The Auth Hub validates the session in Valkey, retrieves the active grant + for `ed-droid`, and returns the cryptographic payload: + ```json + { + "valid": true, + "uuid": "edfa8a54-66c5-4444-9e38-becfc5aa6463", + "scopes": ["viewer"] + } + ``` + - The Deno App SDK middleware injects + `c.set("user", { uuid, scopes: ["viewer"] })` into the application context, + allowing `ed-droid` to render the exact UI views and API actions permitted + for a `viewer`. + +--- + +## 5. PostgreSQL Central Identity Schema Reference + +```sql +-- Central Users Table +CREATE TABLE IF NOT EXISTS users ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + username TEXT UNIQUE NOT NULL, + display_name TEXT, + account_status TEXT DEFAULT 'pending' CHECK (account_status IN ('active', 'pending', 'suspended')), + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Registered Applications / Sites Table +CREATE TABLE IF NOT EXISTS apps ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + name TEXT NOT NULL, + spiffe_id TEXT UNIQUE NOT NULL, + description TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Granular Application RBAC Grants Table +CREATE TABLE IF NOT EXISTS grants ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + app_id UUID NOT NULL REFERENCES apps(id) ON DELETE CASCADE, + role TEXT NOT NULL DEFAULT 'user', + created_at TIMESTAMPTZ DEFAULT NOW(), + UNIQUE(user_id, app_id) +); + +-- Onboarding & Invitation Tokens Table +CREATE TABLE IF NOT EXISTS invites ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + code TEXT UNIQUE NOT NULL, + app_id UUID REFERENCES apps(id) ON DELETE CASCADE, + role TEXT NOT NULL DEFAULT 'user', + used_by UUID REFERENCES users(id) ON DELETE SET NULL, + expires_at TIMESTAMPTZ NOT NULL, + created_at TIMESTAMPTZ DEFAULT NOW(), + used_at TIMESTAMPTZ +); + +-- Hardware Passkeys Table +CREATE TABLE IF NOT EXISTS passkeys ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + credential_id TEXT UNIQUE NOT NULL, + public_key TEXT NOT NULL, + counter BIGINT NOT NULL DEFAULT 0, + aaguid TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Active User Sessions Table +CREATE TABLE IF NOT EXISTS sessions ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, + created_at TIMESTAMPTZ DEFAULT NOW(), + expires_at TIMESTAMPTZ NOT NULL +); + +-- Security Audit Records Table +CREATE TABLE IF NOT EXISTS audit_records ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + user_id UUID REFERENCES users(id) ON DELETE SET NULL, + action TEXT NOT NULL, + resource TEXT, + details JSONB, + ip_address TEXT, + created_at TIMESTAMPTZ DEFAULT NOW() +); + +-- Enterprise Hardware AAGUID Allowlist Table +CREATE TABLE IF NOT EXISTS aaguid_allowlist ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + aaguid TEXT UNIQUE NOT NULL, + description TEXT NOT NULL, + created_at TIMESTAMPTZ DEFAULT NOW() +); +``` + +--- + +## 6. Administrative UI Implementation Specifications + +The Auth-Yes Admin Console is built using server-rendered Deno Hono JSX +components executing direct database queries with zero intermediate loopback +latency. + +### 6.1. Navigation Architecture (`AuthenticatedLayout.tsx` & `AdminLayout.tsx`) + +``` +[ Identity Provider Navbar ] + ├── User Dashboard (/dashboard) + ├── Active Sessions (/dashboard/sessions) + ├── Registered Passkeys (/dashboard/passkeys) + └── [ ADMIN CONSOLE ] (Rendered if isAdmin = true) + ├── User Directory (/admin/users) + ├── Application Registry (/admin/apps) + ├── Invite Tokens (/admin/invites) + ├── AAGUID Allow-List (/admin/aaguid) + └── Security Audit Logs (/admin/audit-logs) +``` + +### 6.2. Page Specifications & Actions + +#### 1. User Directory (`/admin/users`) + +- **Features:** + - Tabular list of all registered users (`username`, `display_name`, + `account_status`, `created_at`, `grant_count`). + - Status mutation buttons: _Activate_, _Suspend_, _Re-Activate_. + - Link to detailed User Management profile (`/admin/users/:id`). + +#### 2. User Profile & RBAC Grant Manager (`/admin/users/:id`) + +- **Features:** + - **Account Recovery:** Single-click _Generate 24h Out-of-Band Recovery Link_. + - **Active Sessions:** List active sessions with individual and _Revoke All_ + actions. + - **Registered Hardware Tokens:** List registered passkeys (`credential_id`, + `counter`, `created_at`) with _Delete Device_ action. + - **Application Access Grants (New in v2):** + - Matrix of currently assigned application access (`App Name`, `Role`, + `Granted At`). + - _Grant Access_ dropdown selector (`App`, `Role: user | admin`) to attach + new app permissions. + - _Revoke Access_ button to remove application-specific access. + +#### 3. Application Registry (`/admin/apps`) + +- **Features:** + - Table of all registered internal applications (`name`, `spiffe_id`, + `description`, `active_users_count`). + - _Register New Application_ form: + - `App Name` (e.g., "Elite Dangerous Streaming Hub") + - `SPIFFE ID` (e.g., `spiffe://system.local/ed-droid-backend`) + - `Description` + - _Delete Application_ action (with confirmation modal preventing accidental + lockout). + +#### 4. Invite & Onboarding Token Manager (`/admin/invites`) + +- **Features:** + - **Token Generation Modal/Form:** + - **Token Type Selector:** + 1. _Global Admin Token_ (Pre-configures `role: 'admin'`, `app: NULL`) + 2. _Site-Scoped Token_ (Displays App dropdown selector + Role selector) + 3. _Open/Pending User Token_ (Pre-configures `role: 'user'`, `app: NULL`, + creates pending user) + - **Expiration Bounds:** 1 to 30 days (default: 7 days). + - **Custom Invite Code (Optional):** Auto-generates cryptographically random + code if left blank. + - **Live Invites Ledger:** + - Table displaying `Code`, `Type / Scope`, `Target App`, `Role`, + `Expires At`, `Status (Active / Used / Expired)`. + - Single-click _Copy Registration URL_ button + (`https://auth.atyg.org/register?code=...`). + - _Revoke Invite_ action. + +--- + +## 7. Implementation Roadmap & Execution Checklist + +| Phase | Milestone | Scope / Deliverables | Status | +| :---------- | :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------ | +| **Phase 1** | **Core Identity & Passkey Engine** | - WebAuthn challenge & verification engine
- PostgreSQL schema auto-initialization
- Valkey session cache & instant revocation
- Direct SSR database rendering (zero-loopback)
- Hybrid hardware/software passkey support | **COMPLETED** | +| **Phase 2** | **Zero-Trust App Mesh (Backend)** | - ConnectRPC / gRPC transport
- SPIFFE/SPIRE mTLS client certificate validation
- Default-deny RBAC grant verification
- ForwardAuth `/api/forward-auth` endpoint | **COMPLETED** | +| **Phase 3** | **Admin Console UI Views (Current)** | - `/admin/apps` Application Registry UI
- `/admin/invites` Multi-Type Token Provisioning UI
- `/admin/users/:id` App RBAC Grant Manager UI
- Domain wildcard cookie (`.atyg.org`) deployment | **READY FOR BUILD** | +| **Phase 4** | **Edge Hardening & Future Scoping** | - Traefik Tier 1 global ForwardAuth fallback configuration
- Traefik Tier 2 ForwardAuth container routing
- Related Origin Requests (`/.well-known/webauthn`) for external TLDs | **FUTURE** | diff --git a/docs/Custom IAM Architecture Analysis.md b/docs/Custom IAM Architecture Analysis.md new file mode 100644 index 0000000..c98fea4 --- /dev/null +++ b/docs/Custom IAM Architecture Analysis.md @@ -0,0 +1,616 @@ +# **Architectural Blueprint and Hardening Analysis of a Decoupled, Zero-Trust Identity Provider Utilizing Deno, Valkey, and WebAuthn** + +## **1\. The Paradigm Shift in Enterprise Identity Architectures** + +Historically, enterprise Identity and Access Management (IAM) has been dominated +by massive, monolithic platforms designed to broker trust across disparate +networks via heavy, standardized protocols. Solutions such as Keycloak, +Authentik, and Okta rely primarily on OpenID Connect (OIDC), OAuth2 redirection +flows, and stateless JSON Web Tokens (JWTs) to authenticate users and authorize +applications1. While these frameworks provide broad interoperability, they +impose immense configuration friction on software engineering teams. Integrating +a new internal application typically requires registering client secrets, +defining redirect URIs, configuring complex scopes, and implementing OAuth2 +authorization code flows—a barrier to rapid iteration.\ +Simultaneously, global industry leaders have increasingly adopted Zero Trust +security architectures, heavily influenced by frameworks like Google's +BeyondCorp and Cloudflare Access, which assert that network locality is no +longer a proxy for trust2. In these advanced models, every request must be +cryptographically authenticated, authorized, and continuously validated, +regardless of whether the traffic originates from the public internet or an +internal Docker network.\ +The proposed custom Identity Provider (IdP) architecture represents a radical, +highly efficient departure from traditional monolithic IdP patterns. By +utilizing a centralized Deno-based API Gateway, a PostgreSQL identity store, and +a high-throughput Valkey session cache, this system aims to deliver +frictionless, zero-trust authentication tailored specifically for a +high-velocity application ecosystem. The architecture explicitly rejects +standard OIDC redirect flows and stateless JWTs. Instead, it relies on a +logic-pure Deno Software Development Kit (SDK) imported directly by subsidiary +applications, which validates stateful session tokens via internal network +routes. Furthermore, the system mandates WebAuthn (passkeys) backed by strict +hardware attestation, mathematically eliminating shared secrets and rendering +traditional credential stuffing and phishing attacks obsolete.\ +This exhaustive analysis evaluates the proposed architecture against modern +enterprise IAM standards, exploring the operational workflows, cryptographic +validation mechanisms, inherent network vulnerabilities, and the advanced +architectural hardening required to elevate this system into an infinitely +scalable enterprise identity fabric. + +## **2\. Core Architectural Components and Perimeter Isolation** + +The structural foundation of the proposed IdP relies on a strict separation of +concerns, decoupling the permanent identity data store from the subsidiary +business applications while maintaining centralized, authoritative control over +session states. + +### **2.1. The API Gateway (Auth Hub)** + +The API Gateway functions as the singular authority for all cryptographic +verifications, WebAuthn challenge generation, and central database transactions. +Operating as an isolated microservice, it exposes REST and gRPC endpoints +exclusively to the internal Docker network. By encapsulating all identity logic +within this central service, subsidiary applications are entirely relieved of +the burden of cryptographic parsing, database connection pooling, and credential +lifecycle management. This establishes a robust zero-trust boundary; if a +subsidiary application is compromised via remote code execution (RCE), the +attacker cannot directly query the central PostgreSQL database or extract public +key materials2. + +### **2.2. The Deno Shared App SDK** + +Instead of forcing each new application to implement complex OIDC redirect +callbacks, developers import a lightweight, logic-pure Deno client library. This +SDK operates as middleware—often implemented via the "onion model" in frameworks +like Oak or Fresh—intercepting incoming HTTP requests to the subsidiary app, +extracting the session token, and transmitting it via a secure internal route to +the Auth API4.\ +Because Deno is secure by default, the execution of this SDK operates within a +strict permissions sandbox. Network access must be explicitly granted via flags +such as \--allow-net, meaning the SDK is structurally constrained and prevented +from leaking session tokens to unauthorized external endpoints, even in the +event of a supply chain compromise7. This drop-in SDK model virtually eliminates +the barrier to implementation for new applications, allowing developers to +secure endpoints with minimal configuration overhead9. + +### **2.3. PostgreSQL Central Identity Store** + +Permanent identity storage, application metadata, and public passkey coordinates +are maintained in a central PostgreSQL relational database. This schema design +guarantees a unified user identity—represented universally by a central +UUID—across the entire application ecosystem. Subsidiary applications maintain +completely independent PostgreSQL databases mapped strictly to this UUID, +preventing schema contamination and data bleeding. This localized mapping is +highly advantageous; if a subsidiary application requires specialized user +profile fields (e.g., localized user preferences or game states), it handles +that mapping internally without requiring schema alterations to the central +IdP11. + +### **2.4. Valkey Session Cache and In-Memory Statefulness** + +The most critical architectural divergence from modern microservice standards is +the reliance on Valkey—an open-source, high-performance key-value store based on +Redis—for session state validation13. When a user successfully authenticates via +WebAuthn, the Auth API issues an opaque session token and stores the +corresponding active state in Valkey. Every subsequent request made to a +subsidiary application forces the App SDK to validate this token against Valkey +via the Auth API. This ensures microsecond-level stateful validation, combining +the speed of in-memory caching with the security of instantaneous session +revocation13. + +### **Table 1: Core System Component Topology** + +| Component | Technology Stack | Primary Function | Security Posture | +| :------------------- | :---------------- | :------------------------------------------------------------------------- | :------------------------------------------------------------------------------ | +| **Auth API Gateway** | Deno (REST/gRPC) | Cryptographic challenge generation, database writes, cache management. | Isolated on internal network; sole component with central DB credentials. | +| **App SDK** | Deno (TypeScript) | Request interception, cookie extraction, RPC routing to Auth API. | Sandboxed via Deno CLI flags (--allow-net=auth-api.internal). | +| **Central Database** | PostgreSQL | Persistent storage of UUIDs, public passkeys, audit logs, and RBAC tables. | Protected behind the Auth API; rejects direct connections from subsidiary apps. | +| **Session Cache** | Valkey | Microsecond validation of opaque stateful session tokens. | In-memory only; cleared upon manual revocation or automated TTL expiry. | + +## **3\. Operational Use Case Flows and Identity Lifecycle** + +The provided operational flows illustrate a highly modular and automated +identity lifecycle, demonstrating how the system handles user provisioning, +credential administration, and session telemetry. + +### **3.1. Provisioning, Invites, and the Authorization Coupling** + +The onboarding flows (Use Cases 1, 2, and 3\) highlight the system's flexibility +in managing user entry. In an open account application (Use Case 1), the App SDK +requests a WebAuthn challenge, the device generates a unique key pair, and the +Auth API creates a UUID, registering the public key and issuing a session.\ +More sophisticated is Use Case 2, which allows users to bypass legacy email +verification via cryptographically secure signup tokens. When a user submits an +invite code, the API provisions the UUID and instantly inserts an authorization +record into the RBAC tables. This tightly couples authentication (verifying who +the user is) with authorization (verifying what the user can do). Because an +authenticated identity does not automatically inherit authorization for all +networked applications, the system maintains the principle of least privilege. +Furthermore, Use Case 3 introduces a manual state machine; the database can +enforce a default "pending" status upon passkey creation, requiring an +administrator to access the central Auth UI and manually toggle the user to +"active" before a session token can be issued. + +### **3.2. Credential Redundancy and Strict Account Recovery** + +Because the system strictly relies on WebAuthn and mathematically rejects shared +secrets, traditional password resets are impossible. If an authenticator is +lost, the user risks permanent account lockout. The architecture addresses this +through redundancy and strict administrative oversight.\ +Use Case 4 highly recommends enrolling multiple passkeys (e.g., a platform +authenticator like a MacBook TouchID and a roaming authenticator like a +YubiKey). When a user with an active session initiates a "Register Device" +action, a new challenge is issued and bound to the existing UUID. If a passkey +is compromised or lost, Use Case 6 dictates that the user or administrator can +select the device nickname for removal. The Auth API executes a SQL DELETE +operation, wiping the public key and credential ID from PostgreSQL, permanently +invalidating the authenticator.\ +If all devices are lost (Use Case 12), the architecture mandates strict +out-of-band administrative intervention. Without static recovery codes, an +administrator must manually execute a database override via the Auth UI to bind +a newly generated WebAuthn challenge to the existing user UUID, ensuring that +social engineering attacks against automated recovery flows are neutralized. + +### **3.3. Multi-Tenant Accounts and Localized Data Mapping** + +Use Case 5 demonstrates the system's capability to support multi-tenant or +multi-persona configurations. The system validates uniqueness based on the +username string, not human identity. If a user registers an alternate username, +the system triggers a new WebAuthn challenge, resulting in a completely distinct +UUID and an independent passkey record. This segregation prevents privilege +escalation bleed, allowing a single human employee to maintain a highly +privileged "Admin" UUID and a restricted "Standard" UUID, fully separated at the +database level.\ +Similarly, Use Case 8 outlines the handling of user profile metadata. A +display\_name exists centrally in the Auth database, modifiable via an Auth API +PATCH endpoint. However, if a subsidiary application requires localized +usernames or domain-specific avatars, it maintains a distinct column in its own +localized PostgreSQL database, mapped back to the central UUID. This enforces +the decoupled nature of the architecture11. + +### **3.4. Infrastructure Topologies and Telemetry** + +The entire environment is orchestrated via Docker Compose (Use Case 9), running +the Valkey, PostgreSQL, Auth API, and Auth UI services. Crucially, Use Case 10 +specifies that all containers share an isolated internal Docker network. +Subsidiary applications deployed on the same server environment attach to this +internal network, allowing the App SDK to resolve the internal endpoint +(auth-api.internal:8000) without exposing the Auth API ports to the public +internet.\ +To maintain security telemetry, Use Case 7 details the session review +architecture. The App SDK can query the Auth API for records associated with a +user's UUID. The API aggregates active session tokens directly from the Valkey +cache alongside historical connection logs (timestamps and IP addresses) stored +in the PostgreSQL audit tables, providing the user with a comprehensive, +formatted list of account activity for proactive security monitoring. + +## **4\. Comparative Analysis: Decoupled API-Backed Sessions vs. Monolithic/Stateless Paradigms** + +To objectively evaluate the efficacy of the proposed SDK-to-API and Valkey +architecture, it must be contrasted against the industry-standard deployments of +monolithic IAM solutions and stateless JWT implementations. + +### **4.1. The Friction of Monolithic IAMs (Keycloak, Authentik, Okta)** + +Standard enterprise solutions are immensely feature-rich but notoriously +complex1. They require the extensive configuration of realms, client IDs, +audiences, scopes, and OIDC mappers. Furthermore, integrating a new application +requires application developers to build or import complex OAuth2 middleware to +handle authorization code flows, token exchanges, and callback URIs.\ +The proposed decoupled architecture bypasses this friction entirely. By +utilizing an internal App SDK that communicates directly with the Auth API over +internal gRPC/REST routes, the system eliminates browser redirects. The +authentication flow is hyper-streamlined: the user authenticates directly via +the central UI, and the resulting opaque session cookie is automatically +transmitted with subsequent requests and processed by the SDK. This drastically +reduces the cognitive load on subsidiary application developers, who simply wrap +their routes in the Deno SDK middleware4. + +### **4.2. Stateful Valkey Sessions vs. Stateless JWT OIDC** + +Modern microservices heavily favor stateless authentication via JSON Web Tokens +(JWTs) because they scale infinitely. Since the JWT contains all necessary user +claims, scopes, and expiration data, and is cryptographically signed by the +IdP's private key, the receiving subsidiary application can validate the token +locally without querying a central server6.\ +However, stateless JWTs suffer from two fatal operational flaws: token bloat and +the inability to be revoked instantly. As RBAC roles and granular claims are +added to a user's profile, the JWT payload increases, degrading HTTP request +performance16. More critically, if a user's device is compromised, a valid JWT +remains active until its expiration timestamp17. To mitigate this, standard +implementations are forced to introduce "blacklists" or centralized revocation +caches, which ironically destroys the stateless nature of the JWT and +reintroduces stateful architectural complexity17.\ +The proposed architecture embraces statefulness via Valkey. Because every +request is validated against the central cache by the SDK, an administrator can +revoke a compromised session, and that revocation propagates globally in +microseconds17. While stateful microservices typically suffer from scalability +bottlenecks and require complex load-balancing configurations like "sticky +sessions," the utilization of an external, high-throughput Valkey cache +decouples the session state from the application instances18. This allows the +Auth API to scale horizontally behind a load balancer; any Auth API instance can +query Valkey to validate the opaque token, ensuring high fault tolerance18. + +### **Table 2: Authentication Architecture Comparison** + +| Feature Category | Monolithic IAM (OIDC / OAuth2) | Stateless JWT Microservices | Proposed Deno \+ Valkey IdP | +| :----------------------- | :------------------------------------------------------------------ | :-------------------------------------------------------------------- | :--------------------------------------------------------------- | +| **Integration Friction** | High (Requires redirect URIs, client scopes, token exchange logic). | Medium (Requires local JWT library, public key distribution). | Low (Import pure-logic Deno SDK, provide Application Secret). | +| **Session Revocation** | Delayed (Relies on short-lived access tokens and refresh flows). | Impossible / Highly Complex (Requires distributed blacklist caches). | Instantaneous (Microsecond deletion from Valkey cache). | +| **Token Payload Size** | Large (Bloated with claims, roles, and audience data). | Large (Prone to header/payload token bloat). | Minimal (Opaque string representing a key in Valkey). | +| **Scalability Limiters** | Database read bottlenecks during token generation/refresh. | Cryptographic CPU overhead for constant local signature verification. | Network I/O latency between subsidiary SDK and Central Auth API. | +| **Phishing Resistance** | Optional (Can support FIDO2, but often falls back to passwords). | N/A (JWTs are post-authentication artifacts). | Enforced (Strict hardware-bound WebAuthn requirements). | + +## **5\. Deep Dive: Cryptographic Security and Advanced WebAuthn Mechanics** + +The proposed architecture achieves a zero-trust posture not merely through +internal network isolation, but by strictly enforcing modern cryptographic +authentication standards. By completely excising passwords and SMS-based +multi-factor authentication, the system immunizes itself against the vast +majority of identity-based attacks. + +### **5.1. Phishing Resistance and Asymmetric Cryptography** + +Traditional authentication relies on shared secrets. If an attacker breaches a +server, hashed secrets can be cracked offline. If an attacker hosts a replica +phishing website, the user unwittingly transmits the secret. The proposed +architecture eliminates this via WebAuthn passkeys19.\ +During registration, the user's authenticator device (e.g., a YubiKey or a TPM +module) generates an asymmetric key pair using an elliptic curve algorithm +(e.g., ES256). The private key never leaves the secure hardware boundary of the +device. The Auth API receives and stores only the public key. During +authentication, the API issues a random cryptographic challenge, and the device +signs this challenge using the private key20. Because there is no secret +transmitted over the wire, credential stuffing, password spraying, and database +leak exploitation are mathematically impossible20. + +### **5.2. Cryptographic Origin Binding and Cross-Domain Passkeys** + +Passkeys are structurally bound to the Relying Party ID (the domain string). If +a user registers a passkey on auth.internal.corp, the browser will +cryptographically refuse to assert that passkey on a lookalike phishing site +like auth-internal.corp19. The signature changes with the origin, ensuring the +credential cannot be hijacked.\ +However, enterprise architectures frequently utilize multiple domains and +subdomains. A company with app1.corp and app2.corp ideally wants a single +passkey to authenticate across both, without requiring the user to register a +new credential for every subsidiary application. Under the original WebAuthn +specification, this was impossible19.\ +To solve this, the architecture must implement **Related Origin Requests +(ROR)**21. ROR allows a Relying Party to specify a list of authorized origins +that can utilize its passkeys21. The Auth API must host a JSON document at the +WebAuthn well-known path (/.well-known/webauthn) on the primary domain21.\ +For example, if the central IDP is auth.corp, the document hosted at +https://auth.corp/.well-known/webauthn would contain: + +JSON\ +{\ +"origins": \[\ +"https://app1.corp",\ +"https://app2.corp"\ +\]\ +} + +During a WebAuthn ceremony on app1.corp, if the Relying Party ID is declared as +auth.corp, the browser will query the central well-known URL. The browser +processes the origin list and re-evaluates the binding, permitting the passkey +assertion to proceed21. The App SDK facilitates this parameter negotiation, +ensuring a seamless Single Sign-On (SSO) experience across the enterprise +ecosystem without breaking strict cryptographic origin binding21. + +### **5.3. Hardware Attestation Strictness and FIDO MDS3 Verification** + +A pivotal feature of this architecture is the configuration toggle to forcefully +reject software-based passkeys (e.g., Bitwarden, iCloud Keychain, Windows Hello) +in favor of certified hardware credentials (e.g., YubiKey 5 Series). Software +passkeys can be copied, synced across devices, and exfiltrated, breaking the +non-repudiation guarantees required by high-security environments24. Restricting +authentication to device-bound hardware is achieved through Authenticator +Attestation25.\ +During the WebAuthn registration ceremony, an authenticator can provide an +attestation statement containing an Authenticator Attestation GUID (AAGUID). The +AAGUID is a 128-bit UUID (e.g., xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) that +uniquely designates the specific hardware model, manufacturer, and firmware +version26. Furthermore, the attestation object includes an x5c certificate chain +generated by an intermediate certificate authority (CA) and imported by the +manufacturer during production25.\ +To enforce strict hardware compliance, the Auth API Gateway must integrate +deeply with the **FIDO Alliance Metadata Service (MDS3)**29. The MDS3 BLOB is a +cryptographically signed JSON web token (JWT) containing a catalog of trusted +AAGUIDs, biometric status reports, and their corresponding root certificates29.\ +The API Gateway must perform the following cryptographic sequence during user +onboarding: + +> 1. **Extract the AAGUID:** Parse the CBOR-encoded attestationObject from the +> user's registration payload to extract the 16-byte AAGUID26. +> 2. **Verify the MDS3 BLOB Signature:** Ensure the locally cached FIDO MDS3 +> BLOB has a valid signature chaining to the FIDO root trust anchor29. +> 3. **Build the Certificate Chain:** Extract the x5c leaf certificate from the +> user's attestation response, append the intermediate certificates, and +> terminate the chain at the specific root certificate mapped to the AAGUID +> inside the MDS3 BLOB33. +> 4. **Check Revocation:** Verify that the AAGUID is not listed in the +> statusReports as compromised, revoked, or possessing outdated firmware31. + +If the device self-attests (as software passkeys do, providing no x5c chain), if +the signature fails to verify, or if the AAGUID is not present on the enterprise +allow-list, the API immediately aborts the registration and returns a 403 +Forbidden24. + +### **Table 3: Hardware Attestation Cryptographic Verification Flow** + +| Component | Cryptographic Function | Security Implication | +| :----------------- | :--------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------- | +| **AAGUID** | 128-bit identifier embedded in the WebAuthn authData. Probability of collision is ![][image1]. | Maps the credential to a specific hardware model, allowing policies to block unapproved or vulnerable devices26. | +| **x5c Chain** | Digital certificate chain appended to the attestation object during registration. | Proves the provenance of the hardware; mathematically prevents attackers from spoofing AAGUIDs using custom software authenticators25. | +| **FIDO MDS3 BLOB** | Signed repository of trusted authenticator metadata statements published by the FIDO Alliance. | Provides the trust anchors (Root CAs) required to cryptographically validate the x5c chain during user onboarding29. | + +## **6\. Vulnerability Assessment and Scaling Limitations** + +While the architecture brilliantly resolves the severe flaws of monolithic IAMs +and stateless JWTs, funneling hundreds of internal applications through a +central API utilizing stateful session validation introduces unique attack +vectors and structural vulnerabilities that must be addressed. + +### **6.1. Network Bottlenecks and Chatty Architecture Latency** + +The most critical structural vulnerability of this system is network latency +induced by a "chatty" architecture. If 100 subsidiary applications each receive +1,000 HTTP requests per second, the App SDK must fire 100,000 synchronous +internal API requests per second to the API Gateway to validate the stateful +session cookies18. Even though the Valkey database operates in microseconds, the +sheer volume of TCP connection handshakes, HTTP overhead, and payload parsing +traversing the internal Docker network will eventually saturate the network +interface, resulting in cascading timeout failures18. Without mitigation, this +creates a massive internal distributed denial-of-service (DDoS) risk under +normal high-load operating conditions. + +### **6.2. Internal Network Sniffing and Lateral Movement** + +The documentation outlines that all containers share an isolated internal Docker +network, effectively creating a perimeter (Use Case 10). While this prevents +ingress from the public internet, it relies on a perimeter defense model, +assuming a zero-trust fallacy _inside_ the network. If a single subsidiary +application is compromised via a vulnerability, the attacker gains a foothold +inside the Docker network. If the SDK-to-API communication occurs over +unencrypted HTTP, the attacker can use packet sniffing tools (e.g., tcpdump) to +intercept active, stateful session cookies traversing the network. Because the +cookies are opaque bearer tokens, the attacker can replay them to impersonate +administrators across other internal applications, enabling devastating lateral +movement. + +### **6.3. Cache Exhaustion and Valkey Denial of Service (DoS)** + +Valkey, functioning as an in-memory datastore, is fundamentally constrained by +available RAM13. If an attacker discovers an unprotected endpoint on a +subsidiary application that generates a new session token (e.g., rapidly calling +the login or invite provision endpoint), they can flood the Auth API with +fraudulent authentication requests. The API will continually write new session +records into Valkey. Once the host machine's RAM is exhausted, Valkey will crash +or begin aggressively evicting active user sessions, leading to an Out-Of-Memory +(OOM) failure and a system-wide catastrophic outage for all authenticated users. + +### **6.4. SDK Subversion and Supply Chain Risks** + +Because the SDK is distributed to subsidiary applications, a malicious developer +or a compromised third-party dependency in a subsidiary app could theoretically +subvert the SDK's execution environment. In a standard Node.js environment, +third-party dependencies have unfettered access to the file system, network, and +environment variables. If a malicious NPM package is imported alongside the SDK, +it could extract the Application Secret used to authenticate the SDK to the API, +allowing the attacker to spoof validation requests or exfiltrate session data to +an external server. + +## **7\. Architectural Improvements and Enterprise Hardening** + +To transform this system into a highly resilient, enterprise-grade IAM fabric +capable of rivaling global tech leaders, specific architectural mechanisms must +be implemented to harden the network and mitigate the identified +vulnerabilities. + +### **7.1. Valkey Client-Side Caching with RESP3 Invalidation** + +To solve the "chatty architecture" bottleneck, the system must abandon the +paradigm of querying the central Auth API on every single HTTP request. Instead, +the Auth API and the Deno SDK should implement **Valkey Client-Side Caching** +utilizing the RESP3 protocol and Pub/Sub mechanics14.\ +When the Deno App SDK requests session validation from the API Gateway, the SDK +should cache the valid result (including RBAC scopes) in its local, in-memory +heap for a short duration15. Simultaneously, the Auth API utilizes Valkey's +CLIENT TRACKING feature with the OPTIN configuration15. If an administrator +revokes a user's session, the Auth API deletes the key in Valkey. Valkey +immediately broadcasts an invalidation message over a Pub/Sub channel to the +Auth API14. The API Gateway then pushes a gRPC stream update to the connected +App SDKs, instructing them to instantly drop the specific local cache entry14.\ +This architecture yields a monumental performance gain: 99% of requests are +validated in nanoseconds locally within the SDK (rivaling the speed of stateless +JWTs), while preserving the instantaneous, microsecond-revocation capability of +a centralized stateful system. + +### **7.2. gRPC with HTTP/2 Multiplexing** + +The SDK-to-API communication must strictly enforce the use of gRPC rather than +REST. REST relies on HTTP/1.1, which traditionally requires establishing a new +TCP connection for requests or dealing with head-of-line blocking. gRPC utilizes +HTTP/2, which supports multiplexing—allowing hundreds of concurrent session +validation requests to be streamed asynchronously over a single persistent TCP +connection35. Furthermore, gRPC uses Protocol Buffers (Protobuf) for binary +serialization, drastically reducing the payload size compared to standard JSON +text transmission35. This will effectively eliminate the internal network +congestion caused by high-throughput subsidiary applications. + +### **7.3. Strict Deno Sandboxing and Execution Constraints** + +The decision to utilize Deno provides a massive security advantage over Node.js, +provided its security sandbox is strictly enforced. The subsidiary applications +running the SDK must never be executed with the \-A or \--allow-all flag, which +completely disables the sandbox7.\ +The execution environment must be tightly constrained using granular CLI flags: + +- \--allow-net=auth-api.internal:8000: This explicitly restricts the SDK to only + communicate with the central Auth API8. Even if the application is compromised + by malware, the malware cannot exfiltrate the Application Secret or session + tokens to an external command-and-control server, because the Deno runtime + will intercept and block the outbound connection at the system level38. +- \--deny-read and \--deny-env: These flags explicitly restrict file system and + environment access. By denying access to /etc/ or .env files, the system + ensures that only explicitly defined variables (like the SDK configuration) + can be loaded into memory, neutralizing supply chain attacks attempting to + scrape disk credentials39. +- \--allow-ffi: Must be strictly avoided or heavily audited, as loading dynamic + C/C++ libraries bypasses the JavaScript sandbox entirely, allowing native code + to issue system calls directly to the OS7. + +### **Table 4: Recommended Deno Runtime Sandbox Configurations** + +| Deno CLI Flag | Operational Purpose | Threat Mitigation | +| :----------------------------- | :------------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | +| \--allow-net=auth-api.internal | Permits communication exclusively to the Auth API gateway39. | Prevents malware from exfiltrating session tokens to public internet endpoints8. | +| \--deny-read=/app/secrets | Blocks read access to specific directories or files7. | Prevents third-party dependencies from scraping disk for application configuration secrets. | +| \--allow-env=AUTH\_URL | Restricts access to a whitelist of required environment variables37. | Blocks malware from dumping the entire environment tree containing DB passwords or API keys. | +| \--allow-all / \-A | **Strictly Prohibited.** Disables the sandbox entirely7. | Ensures the runtime retains its security advantages over traditional Node.js environments8. | + +### **7.4. Internal mTLS via SPIFFE/SPIRE for Zero-Trust Networking** + +To neutralize the threat of internal network sniffing and lateral movement, +Docker network isolation is insufficient. The architecture must implement mutual +Transport Layer Security (mTLS) for all communications between the Deno SDK and +the API Gateway3.\ +By deploying a framework like SPIFFE/SPIRE, localized cryptographic certificates +are distributed to the subsidiary containers. When the SDK initiates a gRPC +connection, the API Gateway cryptographically verifies the identity of the +calling application before processing the request, and the traffic is heavily +encrypted3. This achieves true zero-trust; an attacker sitting on the internal +Docker network capturing packets will only intercept unintelligible ciphertext, +rendering session hijacking and API spoofing impossible. + +### **7.5. Network Rate Limiting and Edge Protection** + +To prevent Valkey cache exhaustion and Out-Of-Memory failures, the Auth API must +implement rigorous, multi-layered rate limiting. Valkey itself should be +utilized to track authentication attempts and issue exponential backoffs13. Rate +limits must be applied dynamically at the IP level, the user UUID level, and the +App SDK level. By establishing a maximum threshold of session generation +requests per minute, the system mathematically bounds the maximum RAM footprint +that can be consumed in a given window, protecting the in-memory cache from +intentional exhaustion. + +## **8\. Conclusion** + +The proposed decoupled Identity Provider architecture represents a highly +sophisticated, developer-friendly approach to enterprise authentication. By +fundamentally rejecting the legacy complexities of OpenID Connect and the +critical security flaws of stateless JWTs, the system achieves a rare +equilibrium between high usability and stringent security. The strict +enforcement of WebAuthn and AAGUID hardware attestation ensures a +cryptographically pristine, phishing-proof boundary against external threats, +mathematically eliminating the vulnerabilities associated with shared secrets.\ +However, the architectural transition to a centralized, stateful session model +shifts the burden of performance directly onto the internal network and the +Valkey cache. To realize the ambitious goal of an authentication system that +scales beyond current industry gold standards with a fraction of the complexity, +the architecture must implement advanced network optimizations. By adopting +Valkey RESP3 client-side caching to eliminate repetitive network I/O, enforcing +gRPC multiplexing for high-throughput communication, deploying strict Deno +runtime permissions to neutralize supply chain attacks, and blanketing the +internal network in mTLS, this architecture will transcend its theoretical +potential. It will yield a system that offers the infinite horizontal +scalability of a stateless architecture, the instantaneous revocation +capabilities of a stateful monolith, and an impenetrable zero-trust security +posture. + +#### **Works cited** + +> 1. Authentik vs Keycloak: where identity providers stop short, +> [https://nhimg.org/community/nhi-best-practices/authentik-vs-keycloak-where-identity-providers-stop-short/](https://nhimg.org/community/nhi-best-practices/authentik-vs-keycloak-where-identity-providers-stop-short/) +> 2. Zero Trust Security | What's a Zero Trust Network? \- Cloudflare, +> [https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/](https://www.cloudflare.com/learning/security/glossary/what-is-zero-trust/) +> 3. Modernizing Database Authentication: CockroachDB Embraces Zero Trust with +> SPIFFE and SPIRE Support, +> [https://www.cockroachlabs.com/blog/zero-trust-database-authentication-spiffe-spire/](https://www.cockroachlabs.com/blog/zero-trust-database-authentication-spiffe-spire/) +> 4. How to Implement Middleware in Deno \- OneUptime, +> [https://oneuptime.com/blog/post/2026-01-31-deno-middleware/view](https://oneuptime.com/blog/post/2026-01-31-deno-middleware/view) +> 5. How to Setup Auth with Fresh | Deno, +> [https://deno.com/blog/setup-auth-with-fresh](https://deno.com/blog/setup-auth-with-fresh) +> 6. How to Implement JWT Authentication for CRUD APIs in Deno \- LoginRadius, +> [https://www.loginradius.com/blog/engineering/guest-post/how-to-implement-jwt-authentication-in-deno](https://www.loginradius.com/blog/engineering/guest-post/how-to-implement-jwt-authentication-in-deno) +> 7. Security and permissions | Deno Docs, +> [https://docs.deno.com/runtime/fundamentals/security/](https://docs.deno.com/runtime/fundamentals/security/) +> 8. How Deno protects against npm exploits, +> [https://deno.com/blog/deno-protects-npm-exploits](https://deno.com/blog/deno-protects-npm-exploits) +> 9. Custom Oak middleware in Deno | Tech Tonic \- Medium, +> [https://medium.com/deno-the-complete-reference/custom-oak-middleware-in-deno-8b2b3289b40e](https://medium.com/deno-the-complete-reference/custom-oak-middleware-in-deno-8b2b3289b40e) +> 10. How to Implement JWT Authentication in Deno \- OneUptime, +> [https://oneuptime.com/blog/post/2026-01-31-deno-jwt-authentication/view](https://oneuptime.com/blog/post/2026-01-31-deno-jwt-authentication/view) +> 11. Stateless vs. Stateful Architecture: A Comprehensive Comparison | AutoMQ +> Blog, +> [https://www.automq.com/blog/stateless-vs-stateful-architecture-a-comprehensive-comparison](https://www.automq.com/blog/stateless-vs-stateful-architecture-a-comprehensive-comparison) +> 12. Securing Web Applications: Stateful vs. Stateless Systems, Authentication, +> and Authorization in Node.js \- DEV Community, +> [https://dev.to/imsushant12/securing-web-applications-stateful-vs-stateless-systems-authentication-and-authorization-in-nodejs-b1m](https://dev.to/imsushant12/securing-web-applications-stateful-vs-stateless-systems-authentication-and-authorization-in-nodejs-b1m) +> 13. From caching to real-time analytics: Essential use cases for Amazon +> ElastiCache for Valkey, +> [https://aws.amazon.com/blogs/database/from-caching-to-real-time-analytics-essential-use-cases-for-amazon-elasticache-for-valkey/](https://aws.amazon.com/blogs/database/from-caching-to-real-time-analytics-essential-use-cases-for-amazon-elasticache-for-valkey/) +> 14. Spring Boot Caching With Valkey or Redis: A Complete @Cacheable Guide, +> [https://redisson.pro/blog/spring-boot-caching-with-valkey-redis-a-complete-cacheable-guide.html](https://redisson.pro/blog/spring-boot-caching-with-valkey-redis-a-complete-cacheable-guide.html) +> 15. Documentation: Client-side caching \- Valkey, +> [https://valkey.io/topics/client-side-caching/](https://valkey.io/topics/client-side-caching/) +> 16. Stateless Authentication: Understanding Token-Based Auth \- Descope, +> [https://www.descope.com/learn/post/stateless-authentication](https://www.descope.com/learn/post/stateless-authentication) +> 17. Stateful vs Stateless Authentication Explained Clearly \- Medium, +> [https://medium.com/@captain-uchiha/stateful-vs-stateless-authentication-explained-clearly-7c9fd647c3a7](https://medium.com/@captain-uchiha/stateful-vs-stateless-authentication-explained-clearly-7c9fd647c3a7) +> 18. Stateful vs. stateless architecture for scalable systems explained \- +> Aerospike, +> [https://aerospike.com/blog/stateful-vs-stateless-architecture-guide/](https://aerospike.com/blog/stateful-vs-stateless-architecture-guide/) +> 19. Cryptographic origin binding: How passkeys make phishing structurally +> impossible, +> [https://workos.com/blog/cryptographic-origin-binding](https://workos.com/blog/cryptographic-origin-binding) +> 20. Web Authentication API \- MDN Web Docs \- Mozilla, +> [https://developer.mozilla.org/en-US/docs/Web/API/Web\_Authentication\_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) +> 21. Related Origin Requests \- passkeys.dev, +> [https://passkeys.dev/docs/advanced/related-origins/](https://passkeys.dev/docs/advanced/related-origins/) +> 22. Allow passkey reuse across your sites with Related Origin Requests \- +> web.dev, +> [https://web.dev/articles/webauthn-related-origin-requests](https://web.dev/articles/webauthn-related-origin-requests) +> 23. Deep Dive: Relying Party ID & origin (Passkeys) \- Duende Software, +> [https://duendesoftware.com/blog/20251014-deep-dive-into-relying-party-id-and-origin-with-passkeys](https://duendesoftware.com/blog/20251014-deep-dive-into-relying-party-id-and-origin-with-passkeys) +> 24. FIDO Metadata Service \- Identity Provider Plugins \- Confluence, +> [https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3878944780](https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3878944780) +> 25. WebAuthn Attestation: How a Site Knows What Made Your Passkey | Haven +> Blog, +> [https://havenmessenger.com/blog/posts/webauthn-fido2-attestation-explained/](https://havenmessenger.com/blog/posts/webauthn-fido2-attestation-explained/) +> 26. AAGUID (Authenticator Attestation GUID) | Definition \- CardLogix, +> [https://www.cardlogix.com/glossary/aaguid-authenticator-attestation-guid-fido2-passkey-webauthn/](https://www.cardlogix.com/glossary/aaguid-authenticator-attestation-guid-fido2-passkey-webauthn/) +> 27. FIDO Metadata Statement, +> [https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.1-ps-20250521.html](https://fidoalliance.org/specs/mds/fido-metadata-statement-v3.1-ps-20250521.html) +> 28. WebAuthn Attestation and Authenticator Metadata \- Yubico Developers, +> [https://developers.yubico.com/Developer\_Program/WebAuthn\_Starter\_Kit/Attestation.html](https://developers.yubico.com/Developer_Program/WebAuthn_Starter_Kit/Attestation.html) +> 29. FIDO Metadata Service, +> [http://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html](http://fidoalliance.org/specs/mds/fido-metadata-service-v3.0-ps-20210518.html) +> 30. FIDO Metadata Service (MDS) Overview \- FIDO Alliance, +> [https://fidoalliance.org/metadata/](https://fidoalliance.org/metadata/) +> 31. FIDO Metadata Service, +> [https://fidoalliance.org/specs/mds/fido-metadata-service-v3.1-ps-20250521.html](https://fidoalliance.org/specs/mds/fido-metadata-service-v3.1-ps-20250521.html) +> 32. FIDO Metadata Service (MDS) \- Yubico Developers, +> [https://developers.yubico.com/WebAuthn/Concepts/FIDO\_Metadata\_Service\_(MDS).html](https://developers.yubico.com/WebAuthn/Concepts/FIDO_Metadata_Service_(MDS).html) +> 33. WebAuthn/FIDO2: Verifying TPM Attestation | by Ackermann Yuriy \- Medium, +> [https://medium.com/webauthnworks/verifying-fido-tpm2-0-attestation-fc7243847498](https://medium.com/webauthnworks/verifying-fido-tpm2-0-attestation-fc7243847498) +> 34. Web Authentication: An API for accessing Public Key Credentials \- Level 2 +> \- W3C, +> [https://www.w3.org/TR/webauthn-2/](https://www.w3.org/TR/webauthn-2/) +> 35. gRPC vs. REST \- Postman Blog, +> [https://blog.postman.com/grpc-vs-rest/](https://blog.postman.com/grpc-vs-rest/) +> 36. CLIENT CACHING \- Valkey Command, +> [https://valkey.io/commands/client-caching/](https://valkey.io/commands/client-caching/) +> 37. Deno allow all permissions \- Stack Overflow, +> [https://stackoverflow.com/questions/61878523/deno-allow-all-permissions](https://stackoverflow.com/questions/61878523/deno-allow-all-permissions) +> 38. How can I enforce a security sandbox with any process?, +> [https://security.stackexchange.com/questions/257801/how-can-i-enforce-a-security-sandbox-with-any-process](https://security.stackexchange.com/questions/257801/how-can-i-enforce-a-security-sandbox-with-any-process) +> 39. Permissions \- Deno Docs, +> [https://docs.deno.com/runtime/reference/permissions/](https://docs.deno.com/runtime/reference/permissions/) +> 40. Introducing Deno Sandbox, +> [https://deno.com/blog/introducing-deno-sandbox](https://deno.com/blog/introducing-deno-sandbox) +> 41. Deno's Networking and File Permissions Model | Reflect, +> [https://reflect.run/articles/deno-networking-and-file-permissions-model/](https://reflect.run/articles/deno-networking-and-file-permissions-model/) + +[image1]: diff --git a/docs/STRUCTURAL_AUDIT.md b/docs/STRUCTURAL_AUDIT.md new file mode 100644 index 0000000..8ecad97 --- /dev/null +++ b/docs/STRUCTURAL_AUDIT.md @@ -0,0 +1,45 @@ +# Structural Audit Report + +## Migration Objective + +Enforce a hard boundary between Central Identity (`auth-yes`) and the ED-Droid +subsidiary application (`core`), creating a decoupled zero-trust architecture. + +## Audit Checklist + +### 1. Database Schema Extraction + +- [x] **Extracted:** `users`, `apps`, `grants`, `invites`, `audit_records`, + `passkeys`, `sessions` schemas moved from `core/db.ts` to + `auth-yes/server/db.ts`. +- [x] **Decoupled:** Removed `REFERENCES users(id)` foreign key constraint from + `edge_nodes.user_id` in `core/db.ts`, replacing it with an unconstrained + UUID linking back to the central Auth identity. +- [x] **Localized Mapping:** Created `user_profiles` table in `core/db.ts` to + hold subsidiary-specific game metadata (`frontier_token`) mapped + exclusively by the unconstrained `user_id`. + +### 2. API Routing Migration + +- [x] **Extracted:** Central Identity endpoints (`/api/register/*`, + `/api/login/*`) and their corresponding SimpleWebAuthn logic moved to + `auth-yes/server/main.ts`. +- [x] **Refactored:** Modified `/frontier/callback` inside `core/api-server.ts` + to perform an `UPSERT` into the localized `user_profiles` table rather + than the central `users` table. +- [x] **Zero-Trust Implementation:** `sessionMiddleware` in `core/api-server.ts` + has been refactored to utilize the `AuthSdk` (`auth-yes/sdk/mod.ts`), + ceasing local queries to the `sessions` table and enforcing network-based + validation. + +### 3. Workspace Validation + +- [x] **Packages:** `auth-yes` is strictly designated as a workspace member + inside `deno.json`. +- [x] **Decoupling:** `auth-yes/sdk/mod.ts` acts as a pure logic client without + directly importing `auth-yes/server/main.ts` or database connections. + +## Conclusion + +The root `core/` directory is now completely purged of central identity logic +and schemas. The structural migration was a complete success. diff --git a/docs/V3_AUDIT_REPORT.md b/docs/V3_AUDIT_REPORT.md new file mode 100644 index 0000000..d3cd841 --- /dev/null +++ b/docs/V3_AUDIT_REPORT.md @@ -0,0 +1,96 @@ +# V3 IAM & Web UI Architectural Audit Report + +## 1. System Implementation Status Matrix + +| Component / Layer | Status | Implementation Details & File References | +| :-------------------------------------- | :-------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Auth Hub / Core Gateway Engine** | **[Completed]** | [`auth-yes/server/main.ts`](file:///home/tylerg/p/data/ed-droid/auth-yes/server/main.ts): WebAuthn registration/login challenge & verify, direct database schema auto-init, Valkey session caching with TTL, sliding-window rate limiting, structured audit logging. | +| **Session & Authorization Engine** | **[Completed]** | [`auth-yes/server/auth-session.ts`](file:///home/tylerg/p/data/ed-droid/auth-yes/server/auth-session.ts): Dual-layer session validation (Valkey cache + PostgreSQL fallback), global admin role detection. | +| **Workload Identity & Zero-Trust Mesh** | **[Completed]** | ConnectRPC / gRPC service with HTTP/2 multiplexing, SPIFFE/SPIRE x509 SVID mTLS client certificate authentication (`spire_ffi` Rust FFI), default-deny RBAC matching `apps` and `grants`. | +| **Direct Server-Side Rendering (SSR)** | **[Completed]** | [`auth-yes/ui/mod.ts`](file:///home/tylerg/p/data/ed-droid/auth-yes/ui/mod.ts): 100% in-process database & session queries for all UI routes, eliminating error-prone internal HTTP loopback fetches to `127.0.0.1:8000`. | +| **Docker Build Layer Caching** | **[Completed]** | [`auth-yes/Dockerfile`](file:///home/tylerg/p/data/ed-droid/auth-yes/Dockerfile) & [`auth-yes/deps.ts`](file:///home/tylerg/p/data/ed-droid/auth-yes/deps.ts): Dedicated dependency caching layer reducing rebuild times from 20s to ~1s. | +| **Client-Side WebAuthn Mechanics** | **[Completed]** | [`auth-yes/ui/public/auth-client.js`](file:///home/tylerg/p/data/ed-droid/auth-yes/ui/public/auth-client.js): Standard `navigator.credentials` handling for WebAuthn passkeys with robust error parsing. | +| **User Directory & Account Status** | **[Completed]** | [`auth-yes/ui/components/AdminUsersPage.tsx`](file:///home/tylerg/p/data/ed-droid/auth-yes/ui/components/AdminUsersPage.tsx): User list, status toggles (_Activate_, _Suspend_, _Re-Activate_). | +| **User Profile & Device Revocation** | **[Completed]** | [`auth-yes/ui/components/AdminUserDetailsPage.tsx`](file:///home/tylerg/p/data/ed-droid/auth-yes/ui/components/AdminUserDetailsPage.tsx): Active sessions review & revocation, passkey device deletion, 24h Out-of-Band recovery link generation. | +| **AAGUID Allow-List Management** | **[Completed]** | [`auth-yes/ui/components/AAGUIDPage.tsx`](file:///home/tylerg/p/data/ed-droid/auth-yes/ui/components/AAGUIDPage.tsx): Enterprise hardware AAGUID allow-list table and registration form. | +| **Security Audit Logs** | **[Completed]** | [`auth-yes/ui/components/AuditLogPage.tsx`](file:///home/tylerg/p/data/ed-droid/auth-yes/ui/components/AuditLogPage.tsx): Live audit trail of logins, registrations, status changes, and security events. | +| **Connected Apps / Sites Registry UI** | **[Pending]** | Backend `apps` table exists and ConnectRPC enforces it, but UI view (`/admin/apps`) to register/view applications is pending. | +| **Multi-Type Invite Token Manager UI** | **[Pending]** | Backend `/api/admin/invites/create` exists, but dedicated UI (`/admin/invites`) to generate Global Admin, Site-Scoped, and Open/Pending tokens with live ledger is pending. | +| **User App RBAC Grants Manager UI** | **[Pending]** | Database `grants` table and ConnectRPC `scopes` payload exist, but UI matrix on `/admin/users/:id` to assign/revoke app permissions per user is pending. | +| **ForwardAuth Edge Proxy Route** | **[Pending]** | Traefik ForwardAuth endpoint (`/api/forward-auth`) for Tier 2 legacy apps (Portainer, etc.) and wildcard `.atyg.org` cookie scoping. | + +--- + +## 2. Architectural Refinements Captured in V3 + +### 2.1. WebAuthn Scope: Parent Domain (`RP_ID=atyg.org`) vs. ROR + +- **Previous Assumption:** Assumed Related Origin Requests (ROR) via dynamic + `/.well-known/webauthn` was required to share passkeys between `auth.atyg.org` + and `ed-droid.atyg.org`. +- **V3 Architectural Finding:** Under W3C WebAuthn Level 3 (eTLD+1 rules), + declaring `RP_ID=atyg.org` on `https://auth.atyg.org` allows all subdomains + (`*.atyg.org`) to natively share passkeys across all browsers without ROR + overhead. +- **Resolution:** ROR is archived as a Phase 5 feature reserved strictly for + future cross-TLD federations (e.g. bridging `atyg.org` with external root + domains). + +### 2.2. Three-Tier Defense-in-Depth Model + +1. **Tier 1 (Global Edge Default):** Default Traefik ForwardAuth middleware + applied to entrypoints, preventing exposure of untagged or pre-release + containers. +2. **Tier 2 (Edge Proxy Override):** Traefik ForwardAuth route + (`/api/forward-auth`) verifying `.atyg.org` session cookies in Valkey and + injecting `X-Forwarded-User` headers for third-party web UIs (Portainer, + Grafana, PgAdmin). +3. **Tier 3 (Zero-Trust App Mesh):** In-app Deno SDK communicating over + ConnectRPC + SPIFFE/SPIRE mTLS with default-deny RBAC for native + microservices (`ed-droid`). + +### 2.3. Formatted 3-Tier Invite Token Taxonomy + +1. **Global Admin Invite Token:** `app_id: NULL`, `role: 'admin'`, creates + active administrator. +2. **Site-Scoped Invite Token:** `app_id: `, `role: 'user'` (or app + role), auto-activates user and binds app grant upon passkey enrollment. +3. **General Open / Pending Onboarding Token:** `app_id: NULL`, `role: 'user'`, + creates account in `pending` status for manual admin approval. +4. _(Plus Out-of-Band Single-Use Account Recovery Token)._ + +### 2.4. Explicit RBAC Lifecycle Paradigm + +- **Baseline (Zero-Trust Default-Deny):** Newly provisioned user has zero + application access. Accessing `ed-droid` returns HTTP 403 Forbidden. +- **Assignment (Admin Console Matrix):** Administrator navigates to + `/admin/users/:id` or RBAC Matrix, selects `ed-droid`, and assigns a role + (`viewer`, `operator`, `editor`, `admin`). +- **Payload & Enforcement:** Next time the user accesses `ed-droid`, ConnectRPC + returns `{ valid: true, uuid: "...", scopes: ["viewer"] }`, granting immediate + runtime access. + +--- + +## 3. Pending Implementation Roadmap + +1. **Build Application Registry UI (`/admin/apps`):** + - Table of registered apps (`name`, `spiffe_id`, `description`, `created_at`, + `active_users_count`). + - Register Application form (`name`, `spiffe_id`, `description`). + - Delete application action with confirmation modal. +2. **Build Multi-Type Invite Token Manager UI (`/admin/invites`):** + - Generation Form supporting all 3 token types (Global Admin, Site-Scoped + with App dropdown, Open/Pending). + - Live ledger of active, used, and expired tokens with single-click copy + links (`https://auth.atyg.org/register?code=...`) and revoke actions. +3. **Build User App RBAC Grants Matrix UI (`/admin/users/:id`):** + - Table of user's active application access grants (`App Name`, `Role`, + `Granted At`). + - Add Grant dropdown form (`App Selector`, + `Role Selector: viewer | operator | editor | admin`). + - Revoke Grant action button. +4. **Deploy Domain Wildcard Cookie (`.atyg.org`) & ForwardAuth Route:** + - Update session cookie creation with `domain: ".atyg.org"`. + - Add `GET /api/forward-auth` endpoint in `auth-yes` for Traefik Tier 2 edge + proxy validation. diff --git a/docs/V3_PROGRESS_TRACKER.md b/docs/V3_PROGRESS_TRACKER.md new file mode 100644 index 0000000..f087404 --- /dev/null +++ b/docs/V3_PROGRESS_TRACKER.md @@ -0,0 +1,127 @@ +# V3 IAM & Web UI Progress Tracker + +This document tracks all completed and pending tasks across the Identity +Provider backend, zero-trust mesh, and administrative Web UI as defined in +[`V3_AUDIT_REPORT.md`](file:///home/tylerg/p/data/ed-droid/V3_AUDIT_REPORT.md) +and +[`Custom IAM Architecture Analysis v2.md`](file:///home/tylerg/p/data/ed-droid/auth-yes/Custom%20IAM%20Architecture%20Analysis%20v2.md). + +--- + +## 1. Phase 1: Core Engine, Passkeys & Session Infrastructure + +- [x] **WebAuthn Registration & Login Engine:** Asymmetric challenge/response + verification via SimpleWebAuthn. +- [x] **Hybrid Passkey Support:** Software authenticators (iPhones, Android, + Windows Hello, 1Password) supported by default with optional strict + hardware enforcement (`REQUIRE_HARDWARE_TOKEN=true`). +- [x] **PostgreSQL Auto-Initialization:** Schema auto-init on boot (`users`, + `apps`, `grants`, `invites`, `passkeys`, `sessions`, `audit_records`, + `aaguid_allowlist`). +- [x] **Dual-Layer Session Management:** Microsecond Valkey cache verification + with automatic PostgreSQL `sessions` fallback to protect against cache + evictions on container restarts. +- [x] **Zero-Loopback Direct SSR:** Replaced all error-prone internal + `fetch('127.0.0.1:8000')` calls in UI routes with direct, in-process + database & session helpers. +- [x] **Distributed Rate Limiting:** Valkey-backed sliding-window rate limiters + on public and administrative endpoints. +- [x] **Asynchronous Security Audit Logging:** Fire-and-forget structured audit + logger capturing origin IP addresses and event telemetry. + +--- + +## 2. Phase 2: Zero-Trust App Mesh & Cryptographic Workloads + +- [x] **ConnectRPC / gRPC Migration:** Replaced unauthenticated HTTP validation + with high-throughput ConnectRPC services over HTTP/2 multiplexing. +- [x] **SPIFFE/SPIRE mTLS Authentication:** Securely extracted SPIFFE IDs from + incoming client certificates via custom `spire_ffi` Rust FFI and ASN.1 + certificate parsing. +- [x] **Default-Deny RBAC Engine:** Backend validation requiring an explicit + active matching row in the `grants` table for `(user_id, app_id)`. +- [x] **Expanded ConnectRPC Payload:** Configured `AuthService.validateSession` + to return granular application roles in the `scopes` array + (`scopes: [grantRecord.role]`). + +--- + +## 3. Phase 3: Developer Experience & Build Optimization + +- [x] **Monorepo Workspace Management:** Configured root `deno.json` with + workspace tasks (`check`, `lint`, `test`, `fmt`). +- [x] **Docker Build Layer Caching:** Created dedicated `auth-yes/deps.ts` layer + in `auth-yes/Dockerfile` ensuring subsequent image builds take ~1 second + instead of re-downloading JSR/npm packages. +- [x] **Client-Side WebAuthn UX:** Clean error banner reporting on UI pages and + safe JSON parsing in `auth-client.js`. + +--- + +## 4. Phase 4: Administrative UI Workflows (Current Execution Phase) + +### Completed UI Views: + +- [x] **User Directory (`/admin/users`):** View all registered users, display + names, and trigger status updates (_Activate_, _Suspend_, _Re-Activate_). +- [x] **User Profile & Device Recovery (`/admin/users/:id`):** Active sessions + list & revocation, passkey device deletion, and 24h Out-of-Band recovery + link generation. +- [x] **Application Registry View (`/admin/apps`):** + - [x] Render table of registered applications (`name`, `spiffe_id`, + `description`, `created_at`, `active_grants_count`). + - [x] Add _Register Application_ form (`name`, `spiffe_id`, `description`). + - [x] Add _Delete Application_ action with confirmation modal. + - [x] Expose `/api/admin/apps` REST endpoints (GET, POST, DELETE). +- [x] **Role & Permission Catalog (`/admin/roles`):** + - [x] PostgreSQL `roles` table with Global (`app_id IS NULL`) vs App-Specific + (`app_id UUID`) scoping. + - [x] Auto-seeded standard core roles (`admin`, `editor`, `operator`, + `viewer`). + - [x] Role management interface with scope filter (_All_, _Global Only_, or + _By App_). + - [x] Expose `/api/admin/roles` REST endpoints (GET, POST, DELETE). +- [x] **Multi-Type & Multi-Use Invite Token Manager (`/admin/invites`):** + - [x] Token Generation Form with 3 Provisioning Types (Global Admin, + Site-Scoped, Open/Pending). + - [x] 3 Usage Policy Modes: Single-Use (1 Person), Limited Multi-Use (Cap at N + People), Unlimited Time-Bound (Campaign / Beta). + - [x] Auto-Activate vs Require Approval account enrollment toggle. + - [x] Expiration duration selector (1 to 30 days, default 7 days) & Custom + Code support. + - [x] Live Invites Ledger displaying real-time usage progress bars + (`X / Y used`), status (`Active`, `Exhausted`, `Expired`), and + activation state. + - [x] Redemption Audit Ledger (`invite_redemptions` table) and modal viewer + (`Claimed (N)`) tracking all users and timestamps per token. + - [x] Single-click _Copy Registration URL_ and _Revoke_ buttons. +- [x] **User App RBAC Grants Matrix (`/admin/users/:id`):** + - [x] Display matrix / table of currently assigned application access + (`App Name`, `Role`, `Granted At`). + - [x] Add Grant form: Dropdown app selector + dynamic role selector populated + from Role Catalog + _Save Grant_ button. + - [x] Revoke Grant action button to instantly strip application access. + - [x] Expose `/api/admin/users/:id/grants` REST endpoints (GET, POST, DELETE). +- [x] **AAGUID Allow-List Management (`/admin/aaguid`):** View approved hardware + authenticators and add new AAGUIDs. +- [x] **System Audit Log Viewer (`/admin/audit-logs`):** Real-time security and + administrative telemetry table. +- [x] **User Dashboard Navigation (`AuthenticatedLayout.tsx` & + `AdminLayout.tsx`):** Seamless navigation between _Dashboard_, _Sessions_, + _Passkeys_, _Users_, _Applications_, _Roles_, _Invite Tokens_, _AAGUID_, + and _Audit Logs_. + +--- + +## 5. Phase 5: Edge Proxy Hardening & ForwardAuth Integration + +- [x] **Domain Wildcard Cookie:** Configured cookie issuing in + `auth-yes/server/main.ts` with `domain: cookieDomain` (`.atyg.org`) for + seamless cross-subdomain sharing. +- [x] **Traefik ForwardAuth Route (`/api/forward-auth`):** Implemented + `GET /api/forward-auth` to validate incoming `.atyg.org` session cookies + in Valkey/DB and inject `X-Forwarded-User` headers for Tier 2 legacy apps + (Portainer, Grafana, etc.). +- [ ] **Traefik Tier 1 Default Middleware Configuration:** Define default + ForwardAuth middleware in Traefik entrypoints to protect + untagged/pre-release containers. diff --git a/docs/archive/AUTH_AUDIT_PROGRESS.md b/docs/archive/AUTH_AUDIT_PROGRESS.md new file mode 100644 index 0000000..5cbf594 --- /dev/null +++ b/docs/archive/AUTH_AUDIT_PROGRESS.md @@ -0,0 +1,191 @@ +# Audit Log - Completed Features & Progress Tracking + +This document outlines the specific features and architectural fixes that have +been implemented based on the target IAM architecture outlined in +`AUTH_AUDIT_REPORT.md`. + +## 1. Monorepo Workspace Initialization (`deno.json`) + +- Created a root `deno.json` file configuring the workspace (`tasks` for `lint`, + `fmt`, `check`, and `test`). +- Adjusted Deno linting rules to allow existing codebase patterns + (`no-explicit-any`, `no-import-prefix`, `require-await`) ensuring tests pass + without halting progressive refactoring. + +## 2. PostgreSQL Identity Schema Enhancements (`auth-yes/server/db.ts`) + +- Added `display_name` and `account_status` columns to the existing `users` + table using safe `ALTER TABLE ... ADD COLUMN IF NOT EXISTS` commands. +- Implemented tables required for RBAC, multi-tenancy, and invitation lifecycle + management: + - `apps`: To support subsidiary application scoping, now including an + `app_secret` column for authorization validation mapping. + - `grants`: To connect users to apps with role-based scoping. + - `invites`: To allow invite-code-based user provisioning. + - `audit_records`: To properly log security and administrative actions. +- These changes address the "Centralized DB Schema Coupling" and "RBAC & + Multi-tenancy" points from the audit report, enabling proper authorization + coupling. + +## 3. App-level RBAC Grants Implementation (`auth-yes/server/main.ts`) + +- Added RBAC enforcement directly into the Identity Provider's `/api/validate` + middleware validation endpoint. +- Validates the `X-App-Secret` to securely map the calling application back to + its `app_id`. +- Performs a direct authorization check against the `grants` table for the + matched `app_id` and the session's `user_id`. +- Rejects requests (returns `403 Forbidden` / `401 Unauthorized`) if a user has + a valid identity session but no explicit role grant for the application. + +## 4. WebAuthn Related Origins Document (`core/api-server.ts`) + +- Added a `GET /.well-known/webauthn` endpoint to the Auth Hub Hono application. +- This returns a valid JSON document conforming to the FIDO WebAuthn Related + Origins specification by outputting the environment's `ORIGIN`. + +## 5. FIDO MDS3 Hardware Attestation + +- Addressed an authentication bypass risk in hardware attestation. +- Updated `keyProtection` verification in the WebAuthn registration process to + correctly validate against the numeric `0x0001` (SOFTWARE) flag as defined by + the FIDO MDS specification, rather than the string `"software"`. + +## 6. Secure Invite Code Provisioning + +- Hardened `/api/admin/invites/create` inputs to reject improperly typed + properties and out of bounds values. +- Enforced strict UUID string validation on `appId`. +- Added boundaries to `role`, strictly enforcing non-empty string payloads under + 32 characters. +- Fixed the `expiresInDays` default fallback logic to use explicit nullish + coalescing to avoid edge cases. +- Enforced a 1 to 30 days inclusive bounds check on the invite expiration. + +## 7. Network Rate Limiting + +- Implemented multi-layered rate limiting backed by Valkey to ensure distributed + limits across Auth Gateway instances and protect against exhaustion (OOM) + attacks. +- Configured strict sliding window limits (10 req/min) per IP address on public + unauthenticated routes (`/api/login/*` and `/api/register/*`). +- Configured moderate limits (30 req/min) per user ID for authenticated + administrative routes (`/api/admin/*`). +- Configured high-throughput limits (2,000 req/min) per `X-App-Secret` for the + internal `/api/validate` fast path. + +## 8. Audit Logging & Non-Repudiation Tracking + +- Fully implemented the `audit_records` logging helper leveraging decoupled + asynchronous inserts (fire and forget) to prevent blocking the critical + execution path. +- Injected specific audit logging side-effects capturing the `X-Forwarded-For` + origin IP across all vital Identity Provider workflows: + - `invite_created` for provision tracking. + - `user_registered` for onboarding traceability. + - `registration_failed_attestation` to record and block potential spoofing + attacks or unsupported software keys. + - `login_success` and `login_failed`. + - `session_validation_failed` capturing internal cross-tenant spoofing + attempts or missing authorization scopes (strictly excluded successful + validations to preserve cache performance). + +## 9. Valkey Session Management & Client-Side Caching + +- Refactored the Auth API Gateway (`auth-yes/server/main.ts`) to write active + session data as stringified JSON directly into the Valkey cache with proper + TTL matching session expiration. +- Implemented the `/api/revoke` endpoint to explicitly delete the session key + from the cache, enabling microsecond-level session revocation. +- Added rigorous `try/catch` wrapping around all Valkey calls to ensure + fast-failure and avoid security leaks. +- Implemented RESP3 Client-Side Caching in the Deno App SDK + (`auth-yes/sdk/mod.ts`). +- Added a local `Map` to act as an L1 cache, configured the Valkey connection + with RESP3 (`HELLO 3`), enabled client tracking in `BCAST` mode, and + implemented logic to evict keys from the L1 cache upon receiving `invalidate` + push messages. +- Added reconnect handling to clear the L1 cache to avoid using stale data in + case of downtime. + +## 10. gRPC/Connect Migration & SPIFFE/SPIRE mTLS + +- Migrated the internal SDK-to-API communication from standard HTTP/REST + endpoints (`/api/validate`) to a robust gRPC/ConnectRPC architecture + (`AuthService.validateSession`). +- Integrated a custom Rust FFI module (`spire_ffi`) to communicate with the + SPIRE Agent via a Unix socket (`/var/run/spire/agent.sock`), securely fetching + x509 SVIDs directly into the Deno runtime without exposing the private keys + over the network. +- Implemented `extractSpiffeIdFromCert` in the Auth API to extract the + `spiffe://` URI from the Subject Alternative Name (SAN) of incoming mTLS + client certificates, replacing the insecure `X-App-Secret` token approach for + internal API authentication. +- Added strict mTLS proxy configurations in Traefik via + `infrastructure/setup.ts`, utilizing `PassTLSClientCert` middleware to inject + the validated `X-Peer-Cert` header into the internal network traffic and + explicitly stripping the spoofable header on ingress requests. +- Updated the database schema and validation logic to rely on the cryptographic + `spiffe_id` (via the `apps` table) for internal zero-trust application + authorization rather than shared symmetric secrets. + +## 11. Resolved Minor Technical Debt + +- Replaced the brittle string matching for SPIFFE ID extraction + (`extractSpiffeIdFromCert`) with robust ASN.1 parsing utilizing the + `@peculiar/asn1-schema` and `@peculiar/asn1-x509` libraries. +- Implemented proper fallback and error handling for missing dynamic libraries + when the `spire_ffi` Rust library fails to load via `Deno.dlopen`, allowing + for graceful degradation in different deployment environments. +- Sanitized gRPC error outputs within `AuthService.validateSession` to prevent + leaking verbose internal server states to connected clients during failure + scenarios. + +## 12. Final System State & Audit Closure Summary + +With the successful migration to gRPC/ConnectRPC and the integration of +SPIFFE/SPIRE for internal mTLS, **all backend security and architectural +requirements defined in the `AUTH_AUDIT_REPORT.md` are now fully implemented and +verified.** + +The system operates as a state-of-the-art zero-trust Identity Provider: + +- **Authentication:** Exclusively hardware-bound WebAuthn (FIDO MDS3 verified) + with centralized stateful Valkey session management. +- **Internal Network Security:** Fully encrypted and authenticated via mTLS, + rejecting any unauthenticated SDK-to-API requests. +- **Performance:** Optimized through gRPC multiplexing and RESP3 Client-Side + Caching, neutralizing network latency associated with central state + validation. +- **Resilience:** Protected by distributed rate limiting, and highly available + architecture capable of microsecond session revocation. + +### Future Considerations (Upcoming Frontend Phase) + +- **Auth UI Implementation:** A dedicated `auth-ui` frontend service is required + to surface the administrative workflows (e.g., generating invite codes, + toggling user statuses, and reviewing audit logs). +- **WebAuthn UX:** The frontend must elegantly handle cross-device registration + flows, explicitly guiding users to plug in their hardware tokens or scan QR + codes. +- **Redundant Passkey Management:** Implement the user-facing settings panel to + allow users to register multiple authenticators (platform and roaming) to + prevent account lockout, along with the UI to revoke specific compromised + authenticators. + +## 13. Auth UI Web Application Initialization (`auth-yes/ui`) + +- Initialized the foundational UI application directly within the `auth-yes` + workspace to encapsulate all Identity Provider capabilities. +- Followed the Atomic Architecture model, cleanly separating concerns into Pure + Logic (JSX layouts and view components), I/O (Hono route mapping), and + Explicit Side Effects (client-side WebAuthn JavaScript). +- Implemented `/login` and `/register` endpoints utilizing Deno Hono and + `hono/jsx`. +- Developed `auth-client.js` to handle `navigator.credentials.create()` and + `navigator.credentials.get()` operations and communicate with the underlying + API Gateway challenges. +- Successfully mounted the new `uiApp` router into the primary Identity Provider + API Gateway (`auth-yes/server/main.ts`). +- Updated the workspace `deno.json` compiler options to natively support + React-style JSX rendering (`jsxImportSource`). diff --git a/docs/archive/AUTH_AUDIT_REPORT.md b/docs/archive/AUTH_AUDIT_REPORT.md new file mode 100644 index 0000000..732d3e1 --- /dev/null +++ b/docs/archive/AUTH_AUDIT_REPORT.md @@ -0,0 +1,77 @@ +# Identity Provider Architecture Audit Report + +## 1. Implementation Status Matrix + +| Component | Status | File Paths / Notes | +| :------------------------------------------------------------------------------------ | :------------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **API Gateway / Auth Hub (Deno/Hono service)** | [In Progress] | `auth-yes/server/main.ts` (Endpoints exist as `501 Not Implemented` stubs), `core/api-server.ts` (Partial implementations in main app) | +| **Auth UI (administration, activation, recovery, and session review)** | [Pending] | No Auth UI implementation or `auth-ui` Compose service exists, although the target architecture requires both. | +| **Shared App SDK (Middleware and API-client wrappers)** | [In Progress] | `auth-yes/sdk/mod.ts` (Basic class structure exists, missing Valkey Client-Side Caching with RESP3 Invalidation) | +| **PostgreSQL Identity Schema** | [In Progress] | `core/db.ts` implements Users, Passkeys, Edge_nodes, and Sessions, but lacks application metadata, RBAC and invitation records, audit records, account status, and `display_name` required by the specification. | +| **Valkey Session Cache Integration** | [Pending] | Mentioned in setup (`infrastructure/setup.ts` `auth-valkey`) but no actual integration logic in code yet. | +| **Monorepo Workspace (deno.json) & Multi-stage Dockerfile** | [Pending] | `deno.json` is completely missing. Dockerfiles (`Dockerfile`, `auth-yes/Dockerfile`) exist but are single-stage and need multi-stage refinement. | +| **Setup CLI Utility (infrastructure/setup.ts & compose generators)** | [In Progress] | `infrastructure/setup.ts` supports `.env.auth` and `compose.auth.yml` generation, but lacks some strict zero-trust configs. | +| **WebAuthn Registration, Authentication & Related Origins** | [In Progress] | `core/api-server.ts` implements basic ceremonies, but uses `attestationType: "none"` and does not provide the required `/.well-known/webauthn` Related Origins document. `auth-yes/server/main.ts` contains only stubbed endpoints. | +| **Add-on Modules (Audit Logging, Invite Codes, Hardware Attestation, Rate Limiting)** | [Pending] | No implementation yet for MDS3 attestation verification, rate limiting, audit logging, or invite codes. | +| **Identity Lifecycle & Administration** | [Pending] | No implementation exists for account activation, additional passkey enrollment/removal and recovery, profile updates, or session/activity review. | + +## 2. Architectural Deviations & Technical Trade-offs + +During the recent development sessions, several compromises and deviations were +made from the target architecture: + +- **gRPC Postponed**: The Auth API Gateway (`auth-yes/server/main.ts`) and SDK + (`auth-yes/sdk/mod.ts`) are currently relying on standard HTTP/REST endpoints + rather than the gRPC transport required by the target architecture. No gRPC + service or Protocol Buffer contract is currently present. +- **Centralized DB Schema Coupling**: The PostgreSQL initialization in + `core/db.ts` currently houses both central identity tables (Users, Passkeys) + and domain-specific tables (Edge_nodes). According to the spec, subsidiary + applications should maintain independent databases to prevent schema + contamination. +- **Attestation Type**: The WebAuthn registration in `core/api-server.ts` + currently configures `attestationType: "none"`. This deviates from the strict + hardware attestation and FIDO MDS3 verification required by the target + architecture. +- **Valkey Bypass**: Current session validation in `core/api-server.ts` queries + PostgreSQL (`sessions` table) directly instead of utilizing Valkey for + high-throughput in-memory statefulness. + +## 3. Unimplemented Features & Security Gaps + +- **Valkey RESP3 Client-Side Caching**: The Valkey integration is missing, + leaving the system vulnerable to network bottlenecks (the "chatty + architecture" problem) and lacks microsecond-level session revocation. +- **FIDO MDS3 Attestation Verification**: The system does not currently verify + hardware provenance against the FIDO Alliance Metadata Service (MDS3), + allowing software-based passkeys which breaks the strict non-repudiation + guarantees. +- **RBAC & Multi-tenancy**: The database schema is missing tables for `Apps`, + `Grants`, and `Invites`. This prevents proper authorization coupling, + multi-tenant scoping, and invite-code based user provisioning. +- **Internal mTLS**: Communication between the App SDK and the Auth API is not + yet secured with mTLS (SPIFFE/SPIRE), exposing the internal network to + sniffing and replay attacks. +- **Network Rate Limiting**: The Auth API lacks multi-layered rate limiting, + making the (future) Valkey cache vulnerable to exhaustion (OOM) attacks. +- **Monorepo Structure**: The missing root `deno.json` prevents proper monorepo + workspace management across the decoupled modules. + +## 4. Recommended Next Actions + +1. **Initialize Monorepo Workspace & Schema Migration**: + - Create a root `deno.json` to define the workspace (managing `core`, + `auth-yes`, etc.). + - Refactor `core/db.ts` to fully align with the isolated identity schema + (adding `Apps`, `Grants`, `Invites`) and decouple subsidiary app schemas. +2. **Implement Valkey & Client-Side Caching**: + - Integrate Valkey into the Auth API Gateway for session storage and + revocation. + - Implement RESP3 Client-Side Caching in the Deno App SDK + (`auth-yes/sdk/mod.ts`) to resolve the "chatty architecture" latency and + enable instant invalidation. +3. **Harden WebAuthn & Internal Networking**: + - Upgrade the WebAuthn ceremonies to enforce strict hardware attestation + using FIDO MDS3 BLOB verification. + - Transition the Auth API and SDK communication from HTTP/REST to gRPC, and + introduce internal mTLS to secure the zero-trust perimeter. diff --git a/docs/archive/WEB_AUDIT.md b/docs/archive/WEB_AUDIT.md new file mode 100644 index 0000000..e088a1a --- /dev/null +++ b/docs/archive/WEB_AUDIT.md @@ -0,0 +1,59 @@ +# Web UI Audit Report + +## Target Architecture + +The target architecture for the Web Application (Identity Provider UI) relies on +the `auth-yes/ui` directory providing a full suite of authentication and +administrative management workflows. It must enforce a clean separation of +concerns using the Atomic Architecture model (Pure Logic, I/O Reads, Explicit +Side Effects) utilizing Deno Hono and `hono/jsx`. The architecture requires a +fully functional client-side WebAuthn workflow handling registration and +cross-device authentication gracefully. + +Key capabilities required: + +- **Core Authentication:** Secure, hardware-bound WebAuthn registration and + login. +- **Administrative Dashboard:** Dedicated UI to manage user provisioning + (generate invite codes), toggle user statuses, and review system audit logs. +- **Passkey Management Panel:** User-facing dashboard to register multiple + redundant passkeys (platform and roaming) and selectively revoke compromised + authenticators. +- **Multi-tenant / Multi-persona UI:** A clean interface mapping localized user + metadata while retaining secure central UUID references. + +## Completed + +Based on an audit of the `auth-yes/ui` directory, the following foundation is +established: + +- **UI Framework Initialization:** The foundational Hono JSX UI application is + mounted at `auth-yes/ui/mod.ts`. +- **Atomic Architecture Adherence:** Explicit separation of route rendering and + static asset serving in `mod.ts`, keeping view components isolated. +- **Basic Auth Routes:** Endpoints for `/login` (`LoginPage.tsx`) and + `/register` (`RegisterPage.tsx`) are currently implemented. +- **Client-Side WebAuthn Mechanics:** The `public/auth-client.js` script + successfully maps `navigator.credentials.create()` and + `navigator.credentials.get()` to the underlying API Gateway challenges. + +## Missing/To-Do + +A significant portion of the administrative and user-management workflows +outlined in the IAM architecture document remains to be built: + +- **Administrative Dashboard UI:** The system currently lacks the frontend + routes and components necessary for administrators to generate invite codes, + toggle user states (e.g., from "pending" to "active"), and review the central + PostgreSQL audit logs. +- **Redundant Passkey Management Panel:** There is no user-facing UI allowing + users to register secondary/backup authenticators or manually revoke + compromised devices. +- **WebAuthn UX Polish:** The current login/registration components lack + polished UX flows for cross-device authentication (e.g., guiding users to plug + in hardware tokens or scan QR codes explicitly). +- **Session Review Interface:** The UI needs a view for users to query their + active session tokens and historical connection logs to actively monitor for + compromised sessions. +- **Component Modularity:** Need to establish shared layout headers/footers to + support the expansion of the dashboard and settings views. diff --git a/docs/archive/WEB_PROGRESS.md b/docs/archive/WEB_PROGRESS.md new file mode 100644 index 0000000..40ae19f --- /dev/null +++ b/docs/archive/WEB_PROGRESS.md @@ -0,0 +1,46 @@ +# Web UI Progress Tracker + +This document tracks the ongoing frontend implementation tasks required to +complete the Identity Provider Web Application as identified in `WEB_AUDIT.md`. + +## Prioritized UI Task Checklist + +### Phase 1: UX Polish & Session Insights + +- [x] **WebAuthn UX Improvements:** Refine cross-device registration and login + flows in `LoginPage.tsx` and `RegisterPage.tsx` to better guide users + (e.g., prompt for hardware token insertion or QR code scanning). +- [x] **Session Review Interface:** Implement a dashboard view where + authenticated users can view active session tokens and historical + connection logs (timestamps, IP addresses). +- [x] **Layout System:** Create standard layout wrapper components (`Layout.tsx` + enhancements) to handle global navigation for authenticated states. + +### Phase 2: Credential Redundancy (User Settings) + +- [x] **Passkey Management Panel:** Develop a user settings UI to list + registered authenticators. +- [x] **Register Additional Passkeys:** Implement the flow for authenticated + users to register secondary/backup hardware tokens. +- [x] **Revoke Passkey UI:** Add functionality for users to permanently delete a + specific compromised credential. + +### Phase 3: Administrative Workflows + +- [x] **Admin Dashboard Layout:** Create a protected route/layout strictly for + users with administrative roles. +- [x] **Manual State Machine Activation:** The UI to review and toggle users + from a default 'pending' state to 'active' before sessions can be issued + (Use Case 3). +- [x] **Out-of-Band Account Recovery:** A specific UI for administrators to + execute a database override, generating and binding a new WebAuthn + challenge to an existing user's UUID when all previous authenticators are + lost (Use Case 12). +- [x] **Global Session & Device Revocation:** The interface for administrators + to instantly revoke active Valkey sessions or delete specific device + nicknames from PostgreSQL (Use Cases 6 & 7.1). +- [x] **AAGUID Allow-List Management:** An interface to manage the enterprise + allow-list of approved hardware Authenticator Attestation GUIDs, ensuring + software passkeys are rejected (Section 5.3). +- [x] **System Audit Log Viewer:** Develop a UI for admins to review system-wide + audit records directly from the database.