From 5f31989137104dd925eda7f1a296f39f07b8ce1c 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 21:12:30 +0000 Subject: [PATCH] feat(tasks): create Traefik Universal Edge Ingress task file Generates `tasks/new/2026-0824.01.jul.feat.auth-api.traefik-ingress-control-2105.md` outlining the architecture and implementation steps for: - Traefik global default-deny ForwardAuth setup - Valkey-cached dynamic database bypass matrix (`is_public`, `bypass_paths`) - Hybrid universal path and CIDR exemptions - Dual-response error handling (302 vs 403) for unregistered apps - Ephemeral guest sandbox flow with passkey promotion Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com> --- ...t.auth-api.traefik-ingress-control-2105.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 tasks/new/2026-0824.01.jul.feat.auth-api.traefik-ingress-control-2105.md diff --git a/tasks/new/2026-0824.01.jul.feat.auth-api.traefik-ingress-control-2105.md b/tasks/new/2026-0824.01.jul.feat.auth-api.traefik-ingress-control-2105.md new file mode 100644 index 0000000..a618396 --- /dev/null +++ b/tasks/new/2026-0824.01.jul.feat.auth-api.traefik-ingress-control-2105.md @@ -0,0 +1,53 @@ +# TASK METADATA + +- **Target Files:** `COMPOSE_CONVENTIONS.md`, `server/main.ts`, `server/auth-session.ts`, `server/db.ts` +- **Core Objective:** Architect and formalize the Tier 1 Universal Global Edge Ingress Protection protocol for Traefik to enforce default-deny while supporting a dynamic, multi-tier bypass and guest sandbox matrix. +- **Dependencies:** Database schema update for `apps` table (`is_public`, `bypass_paths`). +- **Additional Important Notes:** Must align closely with `docs/FORWARDAUTH_REDIRECT_SPEC.md` for dual-response handling and rely entirely on Valkey L1/L2 caching to maintain sub-millisecond edge latency for dynamic routing decisions. + +--- + +### 1. TASK METADATA + +(Defined in the header block above) + +### 2. Architectural Considerations & Risks + +- **Risks:** + - **Recursive Deadlocks (Self-Exemption):** Applying ForwardAuth globally introduces the risk of `auth-api` protecting itself, leading to an infinite authentication loop where users cannot reach the login page to authenticate. `auth-api` must be explicitly exempted. + - **Health Probe Failures:** Traefik and orchestrator liveness/readiness probes (e.g., `/healthz`) might be blocked if they fall under the global ForwardAuth middleware, causing rolling restart failures. + - **Latency Regressions:** If `auth-api` queries PostgreSQL on every request to evaluate dynamic bypass paths (`is_public`, `bypass_paths`, or CIDRs), performance will tank. We must guarantee this data is piggybacked onto the existing Valkey app caching flow. +- **Alternatives & Architectural Decisions:** + - **Dynamic Bypass Matrix:** Evaluated inside `auth-api` with Valkey L1/L2 caching instead of dynamic Traefik HTTP providers to avoid sync overhead and polling complexity. + - **Universal Bypasses (Hybrid Approach):** + - Critical infrastructural paths (`/.well-known/acme-challenge/*`, `/healthz`) bypass ForwardAuth directly at the Traefik router level to prevent lockout during restarts. + - Semantic app paths (`/api/public/*`, `/webhooks/*`) and CIDR allowlists are evaluated within `auth-api` for centralized auditing and hot-reloading. + - **Unregistered App Handling:** Adheres to the Dual-Response protocol. Web browsers receive a `302 Redirect` to a polished Hono SSR error page (`/errors/unregistered`), while API/cURL clients receive a fast `403 Forbidden` response. + - **Guest Sandboxes:** Handled natively via a Valkey ephemeral session with an `account_status: "guest"` and `X-Forwarded-Scopes: guest,trial`. Seamless in-flight passkey promotion transitions them to full users. + +### 3. Proposed Implementation + +1. **Global Default-Deny Configuration:** + - Document how Traefik's `entryPoints.websecure.http.middlewares` should be updated to universally apply the `auth-forward@docker` middleware. + - Define the explicit router priority and empty middleware override required for `auth-api` and ACME challenge routers to guarantee self-exemption. + - Define the mechanism for explicit host-level application bypass where fully public applications (e.g. landing pages, sandboxes) can use specific Docker labels (like `traefik.http.routers.app.middlewares=`) to bypass ForwardAuth entirely at the edge without traversing to `auth-api`. + +2. **Schema & Database Updates:** + - Add database migrations for the `apps` table: + - `is_public` (boolean, default `false`) + - `bypass_paths` (text array, default `[]`) + - `allowed_cidrs` (text array, default `[]`) + +3. **Valkey Caching Upgrades (`server/auth-session.ts`):** + - Update `getAppByHost` to SELECT and cache the new `is_public`, `bypass_paths`, and `allowed_cidrs` fields within the `auth:app_by_host:` Valkey payload. + +4. **Dynamic Bypass & Dual-Response Execution (`server/main.ts`):** + - In `GET /api/forward-auth`: + - **Unregistered App Handling:** If `getAppByHost` returns null, evaluate the `Accept` header. Issue a `302 Redirect` to `https://auth.atyg.org/errors/unregistered?host=...` if it contains `text/html`, otherwise return `403 Forbidden`. + - **Path & CIDR Exemption Check:** Before checking for a valid session, evaluate the requested URI (`X-Forwarded-Uri`) and Client IP against the cached `bypass_paths`, `allowed_cidrs`, and `is_public` flags. + - **Immediate Allowance:** If the request matches a bypass rule or is public, immediately return `200 OK` without querying `getAuthenticatedUser()`. + +5. **Ephemeral Guest Session Generation:** + - Expose a new endpoint (e.g., `/api/guests/sandbox`) that provisions a Valkey session ID without requiring PostgreSQL insertion. + - Attach `account_status: "guest"` to the Valkey payload and map the corresponding `X-Forwarded-Scopes`. + - Update the `/api/passkeys/register/verify` flow to detect `upgrade_session` and persist the guest's UUID and session context to the `users` table upon successful passkey verification.