From 38310f4eada2aa0ff848b9a51da270e77983eeb6 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Mon, 24 Aug 2026 03:56:04 +0000 Subject: [PATCH] docs: draft task file for Ingress Grant Injection in forward-auth Creates a new task markdown file in `tasks/new` detailing the architecture and implementation steps required to inject flattened RBAC grants via Valkey caching for `/api/forward-auth`. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com> --- ...t.auth-api.ingress-grant-injection-1200.md | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 tasks/new/2026-0824.03.jul.feat.auth-api.ingress-grant-injection-1200.md diff --git a/tasks/new/2026-0824.03.jul.feat.auth-api.ingress-grant-injection-1200.md b/tasks/new/2026-0824.03.jul.feat.auth-api.ingress-grant-injection-1200.md new file mode 100644 index 0000000..d228b55 --- /dev/null +++ b/tasks/new/2026-0824.03.jul.feat.auth-api.ingress-grant-injection-1200.md @@ -0,0 +1,82 @@ +# TASK METADATA + +- **Target Files:** `server/main.ts`, `server/db.ts`, `server/auth-session.ts` +- **Core Objective:** Implement Ingress Grant Vector Injection in + `/api/forward-auth` to resolve `X-Forwarded-Host` against registered apps, + evaluate RBAC grants via Valkey caching, and inject flattened user grant + headers into downstream requests. +- **Dependencies:** Valkey caching infrastructure, database migration for + `domain` column on `apps` table. +- **Additional Important Notes:** Latency is critical; ForwardAuth must resolve + in <30μs using Valkey and must not hit PostgreSQL on every request. Global + Admins bypass app-specific grant checks. + +--- + +## Architectural Considerations & Risks + +### Risks + +- **Cache Invalidation:** Stale data in Valkey could allow revoked users to + retain access or prevent newly granted users from accessing apps. We must + ensure that grants and app updates properly invalidate or update their + respective Valkey keys. +- **Header Spoofing / Parsing Issues:** Ensure the `X-Forwarded-*` headers are + safely injected and override any existing headers from the client to prevent + privilege escalation (handled by Traefik, but good to be mindful of). +- **Performance Bottlenecks:** While caching resolves database latency, improper + cache interactions (e.g., waiting for multiple sequential round-trips to + Valkey instead of using pipelining or MGET where appropriate) could still add + overhead. + +### Alternatives Evaluated + +- **Direct PostgreSQL queries:** Rejected due to the high volume of requests + hitting the edge proxy `/api/forward-auth`. +- **JWT Injection:** Instead of flattened headers, injecting a signed JWT was + considered. However, flattened headers (`X-Forwarded-User-Id`, + `X-Forwarded-Scopes`) are native to Traefik ForwardAuth and simpler for + downstream SSR hydration without requiring public key distribution to every + downstream app. + +## Proposed Implementation + +### 1. Database Schema Update (`server/db.ts`) + +- Modify `initDb()` to add the `domain` column to the `apps` table: + `ALTER TABLE apps ADD COLUMN IF NOT EXISTS domain TEXT;`. +- Ensure application seeding or registry logic accounts for the new `domain` + field if necessary. + +### 2. Caching Strategy Implementation + +- Implement helper functions to fetch from Valkey or fallback to DB and populate + Valkey. +- **App Resolution Cache (`auth:app_by_host:`):** + - Match `X-Forwarded-Host` against `apps.domain`. + - Fallback: Match `apps.name` against the first subdomain segment. + - Cache the resulting `app_id` and `name` in Valkey as JSON. +- **Grants Cache (`auth:grants::`):** + - Cache the user's roles for the specific app. + +### 3. ForwardAuth Endpoint Logic (`server/main.ts`) + +- Update `GET /api/forward-auth` to: + 1. Extract `X-Forwarded-Host` from the request. + 2. Resolve the target application via the App Resolution Cache (Valkey). If no + app matches, decide whether to allow pass-through without scopes or + strictly deny (typically 403 for protected routes without an app, or allow + pass-through if unmapped). Assuming strict mapping per requirements, return + 403 or 404 if not found. + 3. Validate the user session (existing logic). + 4. Check if the user is a Global Admin (`isGlobalAdmin`). If yes, authorize + automatically and set `X-Forwarded-Scopes: admin`. + 5. For regular users, resolve their scopes for the target app via the Grants + Cache (Valkey). + 6. Enforce Default-Deny: If no scopes are found, return 403 Forbidden. + 7. On success, inject headers: + - `X-Forwarded-User-Id: ` + - `X-Forwarded-User-Name: ` + - `X-Forwarded-Scopes: ` + - `X-Forwarded-App-Id: ` + - Return HTTP 200 OK.