diff --git a/ONBOARDING.md b/ONBOARDING.md new file mode 100644 index 0000000..06d4ca4 --- /dev/null +++ b/ONBOARDING.md @@ -0,0 +1,212 @@ +# Auth-Yes — Client Application Onboarding & Integration Guide + +This guide provides end-to-end instructions for connecting subsidiary +applications (such as **`ed-droid`**) to the **Auth-Yes** Zero-Trust Identity & +Access Management (IAM) fabric. + +--- + +## 1. System Architecture & Authentication Flow + +Auth-Yes provides ultra-low-friction, passkey-first authentication with a +**3-tier defense-in-depth model**: + +``` + [ Browser / Public Internet ] + │ + 1. WebAuthn Passkey Login + 2. Scoped Cookie: *.atyg.org + │ + ▼ + ═════════════════════════════════════ + Traefik Ingress Proxy (traefik-net) + ═════════════════════════════════════ + │ + ┌────────────────────┴────────────────────┐ + ▼ ▼ +[ Tier 2: ForwardAuth ] [ Tier 3: Native App ] + (Portainer / Web UIs) (ed-droid) + │ │ + │ GET /api/forward-auth │ 1. Extract session_id + │ (Valkey Cache Lookup) │ 2. SDK ConnectRPC + │ ▼ + │ ┌─────────────────────────────────┐ + │ │ SPIRE Agent (spire-socket) │ + │ │ - Provides Client X509 SVID │ + │ │ - spiffe://system.local/ed-droid│ + │ └────────────────┬────────────────┘ + │ │ + │ │ ConnectRPC over HTTP/2 + ▼ ▼ + ═════════════════════════════════════════════════════════════════════ + Auth-Yes Central Gateway (auth-internal-net: auth-api:8000) + - Microsecond L1/L2 Valkey Session Verification (RESP3 Tracking) + - Cryptographic SPIFFE Workload Validation (spire_ffi) + - Default-Deny PostgreSQL Application RBAC Grants (grants table) + ═════════════════════════════════════════════════════════════════════ +``` + +--- + +## 2. Docker / Podman Compose Configuration + +To connect a subsidiary service to Auth-Yes and SPIRE, update your application's +`compose.yml`: + +```yaml +version: "3.8" + +services: + ed-droid: + image: ${REG}/library/ed-droid:latest + container_name: ed-droid + environment: + - AUTH_API_URL=http://auth-api:8000 + - VALKEY_URL=redis://auth-valkey:6379 + - SPIFFE_ENDPOINT_SOCKET=/var/run/spire/agent.sock + networks: + - default # Internal service mesh + - traefik-net # Ingress routing + volumes: + # Mount zero-trust SPIRE Workload API socket (read-only) + - spire-socket:/var/run/spire:ro + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik-net" + - "traefik.http.routers.ed-droid.rule=Host(`ed-droid.atyg.org`)" + - "traefik.http.routers.ed-droid.entrypoints=websecure" + - "traefik.http.routers.ed-droid.tls=true" + - "traefik.http.services.ed-droid.loadbalancer.server.port=3000" + +volumes: + # Reference the pre-existing SPIRE socket volume + spire-socket: + external: true + +networks: + default: + name: auth-internal-net + external: true + traefik-net: + external: true +``` + +--- + +## 3. SDK Integration (Deno / TypeScript / Hono) + +The `@auth-yes/sdk` is zero-dependency on backend databases and uses +**ConnectRPC** with **RESP3 client-side caching**. + +### 3.1. Importing the SDK + +In `deno.json` / `package.json`: + +```json +{ + "imports": { + "@auth-yes/sdk": "https://git.atyg.org/tylerg/auth-yes/raw/branch/main/sdk/mod.ts", + "@auth-yes/sdk/hono": "https://git.atyg.org/tylerg/auth-yes/raw/branch/main/sdk/hono.ts" + } +} +``` + +### 3.2. Initializing the SDK & Protecting Routes + +```typescript +import { Hono } from "jsr:@hono/hono@4"; +import { createAuthSdk } from "@auth-yes/sdk"; +import { createAuthMiddleware } from "@auth-yes/sdk/hono"; + +// 1. Initialize SDK with internal mesh endpoints +export const authSdk = createAuthSdk({ + authApiUrl: Deno.env.get("AUTH_API_URL") || "http://auth-api:8000", + valkeyUrl: Deno.env.get("VALKEY_URL") || "redis://auth-valkey:6379", +}); + +const app = new Hono(); + +// 2. Public Routes (No Auth Required) +app.get("/health", (c) => c.text("OK")); + +// 3. Protected API Routes (Protected by Auth-Yes Middleware) +const authMiddleware = createAuthMiddleware(authSdk); + +app.use("/api/*", authMiddleware); + +app.get("/api/me", (c) => { + const userId = c.get("userId"); // Injected UUID + return c.json({ userId, status: "authenticated" }); +}); + +// 4. Granular Scope / Role Validation +app.get("/api/admin/system", async (c) => { + const token = c.req.header("Authorization")?.replace("Bearer ", "") || + c.req.raw.headers.get("cookie")?.match(/session_id=([^;]+)/)?.[1]; + + const session = await authSdk.validateSession(token!); + + if (!session.scopes?.includes("admin")) { + return c.json( + { error: "Forbidden: Requires application admin scope" }, + 403, + ); + } + + return c.json({ message: "Admin console unlocked" }); +}); + +export default app; +``` + +--- + +## 4. Administrative Setup in Auth-Yes Console + +Before users can access `ed-droid`, complete these steps in +`https://auth.atyg.org`: + +### Step 1: Register Application (`/admin/apps`) + +1. Log in to **Auth-Yes Admin Console** $\rightarrow$ **Applications**. +2. Click **+ Register Application**. +3. Fill in: + - **Name:** `ed-droid` + - **SPIFFE ID:** `spiffe://system.local/ed-droid` + - **Description:** + `Elite Dangerous streaming hub and telemetry module system` +4. Click **Save Application**. + +### Step 2: Onboard Users via Invite Tokens (`/admin/invites`) + +1. Go to **Invite Tokens** $\rightarrow$ **Generate Invite**. +2. Select Token Type: + - **Site-Scoped Invite:** Choose `ed-droid` and role (`user`, `operator`, or + `admin`). + - _Effect:_ When the user registers their passkey, they are instantly + granted access to `ed-droid` without admin intervention. + - **Global Admin Invite:** For core infrastructure administrators. +3. Share the generated registration link: + `https://auth.atyg.org/register?code=`. + +### Step 3: Manage Existing User Grants (`/admin/users/:id`) + +1. Navigate to **User Directory** $\rightarrow$ Click on a user. +2. In the **Application Access Grants** matrix: + - Select `ed-droid` from the dropdown. + - Assign role (`viewer`, `operator`, `admin`). + - Click **Grant Access**. +3. **Revocation:** Click **Revoke Access** at any time to instantly terminate + access (invalidated across Valkey in $< 1$ millisecond). + +--- + +## 5. Verification Checklist + +| Step | Verification Command / Check | Expected Result | +| :------------------------------ | :------------------------------------------------------------- | :---------------------------------------------- | +| **1. SPIRE Socket Mounted** | `podman exec -it ed-droid ls -la /var/run/spire/agent.sock` | Socket file is present (`srw-rw-rw-`) | +| **2. Auth Gateway Reachable** | `podman exec -it ed-droid curl -I http://auth-api:8000/health` | Returns HTTP `200 OK` | +| **3. Valkey Caching Active** | Check app logs during `validateSession()` | L1 cache hits log 0ms response times | +| **4. Default-Deny Active** | Request without grant for `ed-droid` | Returns HTTP `403 Forbidden: Validation failed` | +| **5. Valid Session Authorized** | Passkey authenticated user with grant | Returns HTTP `200 OK` with user UUID and scopes |