auth-yes/tasks/new/2026-0824.01.jul.feat.auth-api.traefik-ingress-control-2105.md
google-labs-jules[bot] 5f31989137 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>
2026-08-24 21:12:30 +00:00

54 lines
4.8 KiB
Markdown

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