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

4.8 KiB

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.