# 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`). --- ## ⚡ Quick Navigation & Practical Integration Playbooks - 📘 **[Practical Playbook & 11 High-ROI Use Cases](docs/USE_CASES_AND_EFFORT.md):** Step-by-step guides for Appliance Setup, Traefik ForwardAuth, SSR Hydration, Live WebSockets, Ephemeral Trial/Guest Tokens, and SSS Recovery. - _Raw Gitea Mirror:_ `https://git.atyg.org/tylerg/auth-yes/raw/branch/main/docs/USE_CASES_AND_EFFORT.md` - ⚡ **[The Ghost Cockpit Protocol Spec](docs/GHOST_COCKPIT_SPEC.md):** Specification and client snippet for non-destructive WebSocket telemetry freezes and in-flight WebAuthn re-auth. - _Raw Gitea Mirror:_ `https://git.atyg.org/tylerg/auth-yes/raw/branch/main/docs/GHOST_COCKPIT_SPEC.md` - 🌐 **[ForwardAuth Browser Redirection & Deep-Link Spec](docs/FORWARDAUTH_REDIRECT_SPEC.md):** Specification for browser 302 vs API 401 dual-response handling, open redirect prevention (CWE-601), and deep-link query parameter preservation. - _Raw Gitea Mirror:_ `https://git.atyg.org/tylerg/auth-yes/raw/branch/main/docs/FORWARDAUTH_REDIRECT_SPEC.md` - 🛡️ **[Cryptographic Standards & Verification Dossier](docs/VERIFY.md):** Full mathematical and specification audits (W3C WebAuthn Level 3, RFC 9421, RFC 7638, RFC 6962, RFC 9106). - 📦 **[Raw SDK Module Distribution](sdk/mod.ts):** `https://git.atyg.org/tylerg/auth-yes/raw/branch/main/sdk/mod.ts` --- ## 🛠️ Engineering Lifecycle & Task Protocols Auth-Yes development follows a strict, disciplined 4-step task lifecycle designed to preserve context, prevent regressions, and enforce dual-level deliberation between human developers and AI agents. ```mermaid flowchart LR subgraph Lifecycle ["Sequential Engineering Lifecycle"] direction LR P["1. plan
(tasks/plan.md)"] --> A1["2. audit-1
(tasks/audit-1.md)"] A1 --> D["3. do
(tasks/do.md)"] D --> A2["4. audit-2
(tasks/audit-2.md)"] end subgraph Standalone ["On-Demand / Any Time"] DBG["debug
(tasks/debug.md)"] end DBG -.->|"Feeds Root Cause into"| P ``` ### Protocol Quick Reference | Step / Tool | Protocol File | Role | Purpose | Direct Command | Prompt Prep Command | | :---------: | :----------------------------------------- | :------------- | :------------------------------------------------------------------------- | :---------------------- | :------------------------------- | | **1** | [**`tasks/plan.md`**](tasks/plan.md) | System Analyst | Deep codebase research & drafting task in `tasks/new/` | `tasks/plan XYZ` | `tasks/plan a prompt for Jules` | | **2** | [**`tasks/audit-1.md`**](tasks/audit-1.md) | Plan Critic | 5-point plan audit, scoring, and refinement | `tasks/audit-1 task #1` | `tasks/audit-1 prompt for Jules` | | **3** | [**`tasks/do.md`**](tasks/do.md) | Developer | Execution, state machine (`wip/` $\rightarrow$ `complete/`), quality gates | `tasks/do task #1` | `tasks/do a prompt for Jules` | | **4** | [**`tasks/audit-2.md`**](tasks/audit-2.md) | QA Auditor | Post-implementation code quality & zero-regression audit | `tasks/audit-2 branch` | `tasks/audit-2 prompt for Jules` | | 🔬 | [**`tasks/debug.md`**](tasks/debug.md) | Investigator | Hermetic root-cause analysis & experiments in `scratch/` | `tasks/debug issue` | `tasks/debug a prompt for Jules` | _For master guidelines and orchestrator index, see [**`tasks/path.md`**](tasks/path.md) and [**`tasks/GUIDELINES.md`**](tasks/GUIDELINES.md)._ --- ## 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** | --- ## 8. License Auth-Yes is dual-licensed under: - **MIT License** ([LICENSE-MIT](LICENSE-MIT)) - **Apache License, Version 2.0** ([LICENSE-APACHE](LICENSE-APACHE)) `SPDX-License-Identifier: MIT OR Apache-2.0`