auth-yes/README.md

25 KiB

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: 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: 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: 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: Full mathematical and specification audits (W3C WebAuthn Level 3, RFC 9421, RFC 7638, RFC 6962, RFC 9106).
  • 📦 Raw SDK Module Distribution: 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.

flowchart LR
    subgraph Lifecycle ["Sequential Engineering Lifecycle"]
        direction LR
        P["1. plan<br/>(tasks/plan.md)"] --> A1["2. audit-1<br/>(tasks/audit-1.md)"]
        A1 --> D["3. do<br/>(tasks/do.md)"]
        D --> A2["4. audit-2<br/>(tasks/audit-2.md)"]
    end

    subgraph Standalone ["On-Demand / Any Time"]
        DBG["debug<br/>(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 System Analyst Deep codebase research & drafting task in tasks/new/ tasks/plan XYZ tasks/plan a prompt for Jules
2 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 Developer Execution, state machine (wip/ \rightarrow complete/), quality gates tasks/do task #1 tasks/do a prompt for Jules
4 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 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 and 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: <username>
      • X-Forwarded-User-Id: <uuid>
    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.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:
    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).

To support edge proxy interception (ForwardAuth Tier 1 & 2), the Auth Hub sets the session cookie with domain wildcard scoping:

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.

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:
      {
        "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

-- 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:

SPDX-License-Identifier: MIT OR Apache-2.0