docs: preserve complete architectural analysis, audit reports, and dependency layer
This commit is contained in:
parent
3ae77473a9
commit
f3bcbddfc8
455
Custom IAM Architecture Analysis v2.md
Normal file
455
Custom IAM Architecture Analysis v2.md
Normal file
@ -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: <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. 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<br>- PostgreSQL schema auto-initialization<br>- Valkey session cache & instant revocation<br>- Direct SSR database rendering (zero-loopback)<br>- Hybrid hardware/software passkey support | **COMPLETED** |
|
||||
| **Phase 2** | **Zero-Trust App Mesh (Backend)** | - ConnectRPC / gRPC transport<br>- SPIFFE/SPIRE mTLS client certificate validation<br>- Default-deny RBAC grant verification<br>- ForwardAuth `/api/forward-auth` endpoint | **COMPLETED** |
|
||||
| **Phase 3** | **Admin Console UI Views (Current)** | - `/admin/apps` Application Registry UI<br>- `/admin/invites` Multi-Type Token Provisioning UI<br>- `/admin/users/:id` App RBAC Grant Manager UI<br>- Domain wildcard cookie (`.atyg.org`) deployment | **READY FOR BUILD** |
|
||||
| **Phase 4** | **Edge Hardening & Future Scoping** | - Traefik Tier 1 global ForwardAuth fallback configuration<br>- Traefik Tier 2 ForwardAuth container routing<br>- Related Origin Requests (`/.well-known/webauthn`) for external TLDs | **FUTURE** |
|
||||
616
Custom IAM Architecture Analysis.md
Normal file
616
Custom IAM Architecture Analysis.md
Normal file
@ -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]: <data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAWCAYAAAB9oOpzAAAAm0lEQVR4Xu3VMQrCQBCF4bmAtzD3EC8gCUmTMqVY2likTNqAN0mrp8oJ9MHuWgw7sI2EZd8Hf5Nhm9dEhIj+4IAe6KIPperRE23oIxzmZ0JvdBUOE1UJh4niMAYOY+AwhjBMrQ+GMxoTu/s3WQrDNPpguIn7m6W0+jdZCsO0+lC6MEynD6U6ohOaxQ3zQoP/VrRF3CCxiIiIaFdfotYqcq8XgxEAAAAASUVORK5CYII=>
|
||||
12
deps.ts
Normal file
12
deps.ts
Normal file
@ -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";
|
||||
455
docs/Custom IAM Architecture Analysis v2.md
Normal file
455
docs/Custom IAM Architecture Analysis v2.md
Normal file
@ -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: <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. 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<br>- PostgreSQL schema auto-initialization<br>- Valkey session cache & instant revocation<br>- Direct SSR database rendering (zero-loopback)<br>- Hybrid hardware/software passkey support | **COMPLETED** |
|
||||
| **Phase 2** | **Zero-Trust App Mesh (Backend)** | - ConnectRPC / gRPC transport<br>- SPIFFE/SPIRE mTLS client certificate validation<br>- Default-deny RBAC grant verification<br>- ForwardAuth `/api/forward-auth` endpoint | **COMPLETED** |
|
||||
| **Phase 3** | **Admin Console UI Views (Current)** | - `/admin/apps` Application Registry UI<br>- `/admin/invites` Multi-Type Token Provisioning UI<br>- `/admin/users/:id` App RBAC Grant Manager UI<br>- Domain wildcard cookie (`.atyg.org`) deployment | **READY FOR BUILD** |
|
||||
| **Phase 4** | **Edge Hardening & Future Scoping** | - Traefik Tier 1 global ForwardAuth fallback configuration<br>- Traefik Tier 2 ForwardAuth container routing<br>- Related Origin Requests (`/.well-known/webauthn`) for external TLDs | **FUTURE** |
|
||||
616
docs/Custom IAM Architecture Analysis.md
Normal file
616
docs/Custom IAM Architecture Analysis.md
Normal file
@ -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]: <data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEYAAAAWCAYAAAB9oOpzAAAAm0lEQVR4Xu3VMQrCQBCF4bmAtzD3EC8gCUmTMqVY2likTNqAN0mrp8oJ9MHuWgw7sI2EZd8Hf5Nhm9dEhIj+4IAe6KIPperRE23oIxzmZ0JvdBUOE1UJh4niMAYOY+AwhjBMrQ+GMxoTu/s3WQrDNPpguIn7m6W0+jdZCsO0+lC6MEynD6U6ohOaxQ3zQoP/VrRF3CCxiIiIaFdfotYqcq8XgxEAAAAASUVORK5CYII=>
|
||||
45
docs/STRUCTURAL_AUDIT.md
Normal file
45
docs/STRUCTURAL_AUDIT.md
Normal file
@ -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.
|
||||
96
docs/V3_AUDIT_REPORT.md
Normal file
96
docs/V3_AUDIT_REPORT.md
Normal file
@ -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: <app-uuid>`, `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.
|
||||
127
docs/V3_PROGRESS_TRACKER.md
Normal file
127
docs/V3_PROGRESS_TRACKER.md
Normal file
@ -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.
|
||||
191
docs/archive/AUTH_AUDIT_PROGRESS.md
Normal file
191
docs/archive/AUTH_AUDIT_PROGRESS.md
Normal file
@ -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`).
|
||||
77
docs/archive/AUTH_AUDIT_REPORT.md
Normal file
77
docs/archive/AUTH_AUDIT_REPORT.md
Normal file
@ -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.
|
||||
59
docs/archive/WEB_AUDIT.md
Normal file
59
docs/archive/WEB_AUDIT.md
Normal file
@ -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.
|
||||
46
docs/archive/WEB_PROGRESS.md
Normal file
46
docs/archive/WEB_PROGRESS.md
Normal file
@ -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.
|
||||
Loading…
x
Reference in New Issue
Block a user