Hugo Fund Formation Platform14 Jun, 03:53 CET

Authentication

Cloudflare Access JWT validation, mock-user fallback, and fund-level access control.

The MVP and full Hugo deployments are fronted by Cloudflare Access; review adds a password gate for lawyer review. Requests to mvp.hugo.nordiclawfirm.com must carry a valid Access identity or approved service/add-in token when REQUIRE_CF_ACCESS=true. App identity is resolved by src/middleware/auth.ts from the mapped Access email, app cookie, add-in session, or local fallback.

Production mode

REQUIRE_CF_ACCESS=true (fail-closed)

When REQUIRE_CF_ACCESS=true (set in wrangler.toml), the worker enforces a strict three-mode dispatch in src/middleware/auth.ts:

  1. Valid Access identity: accept CF-Access-JWT-Assertion or the Access-authenticated email header, then resolve the application user from the users table.
  2. Service token or add-in bearer: allow approved machine/add-in access without relying on browser cookies, then resolve app identity through the existing user/session paths.
  3. No accepted identity: returns 401 Unauthorized immediately. This is the fail-closed safety net — if CF Access is ever misconfigured (policy flipped, tunnel rerouted), the worker refuses the request rather than falling through to a default user.

Auth-relevant DB calls go through the retry-wrapped proxy (c.var.db if available, else retryableDB(c.env.DB)), so transient D1 errors on the first query of a request don't surface as 500s.

Local development

Mock-user fallback (REQUIRE_CF_ACCESS=false)

When REQUIRE_CF_ACCESS is not "true" (e.g. local wrangler dev with .dev.vars), the worker falls back to a mock-user system so a fresh D1 still boots:

  • A hugo_user_id cookie selects the user from the users table (regex-capped at 64 chars)
  • If absent, defaults to seed_user_alice; a fresh empty D1 falls through to an admin dev passthrough so the app can boot
  • This branch is gated on REQUIRE_CF_ACCESS !== 'true' — in production it never fires
  • See .dev.vars.example for the keys to set locally

Fund access control

User typeAccessEnforcement
Admin All funds Bypass fundAccessMiddleware
Full access All funds (full_access = 1) Bypass fundAccessMiddleware
Standard user Only granted funds user_funds table check on all /funds/:fundSlug/* routes

The fundContextMiddleware enforces access control on all /funds/:fundSlug/* routes. It resolves the slug to a canonical fund id, loads the user's fund grants from the user_funds table, and returns 403 if the user does not have access to the requested fund.

Auth flow summary

  1. Request arrives at Cloudflare Access edge or the review password gate
  2. CF Access validates identity (human SSO or service token) and passes Access headers to the Worker
  3. Hugo worker's authMiddleware classifies the perimeter auth kind, including add-in bearer sessions
  4. If REQUIRE_CF_ACCESS=true and neither is present: 401
  5. App identity resolution checks review login, add-in session, mapped Access email, app cookie, seed fallback, then empty-D1 admin passthrough
  6. fundContextMiddleware checks user_funds for route-specific fund access
  7. Admin-gated routes additionally check userRole === 'admin'
  8. Request proceeds or 403

Tested guarantees

tests/middleware/auth.test.ts and tests/middleware/review-login.test.ts cover fail-closed auth, review login, mapped-user lookup, local-dev fallback, and the c.var.db retry-wrapped DB usage.

Ctrl+K to open · ↑↓ navigate · Enter go · Esc close
Copied