Adds the task definition markdown file `2026-0826.01.jul.story.events.phase-1-guest-ingress-1400.md` detailing the architectural scope and plan for enabling Traefik ForwardAuth guest ingress, bridging custom scopes to the Launchpad UI via UNION query, and wiring event claim audit logs using event.id. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
4.6 KiB
4.6 KiB
TASK METADATA
- Target Files:
server/routes/auth_forward.ts,ui/db_queries.ts,ui/mod.ts,server/routes/events.ts,server/tests/forward_auth.test.ts,server/tests/events.test.ts - Core Objective: Implement Phase 1 of the Event & Session Overhaul: Enable Traefik ForwardAuth guest ingress for scoped event attendees, bridge session custom scopes to the Launchpad UI, and wire audit logging on event seat claims.
- Dependencies: None.
- Additional Important Notes: Follow zero-trust default-deny principles for ForwardAuth. Guest sessions minting needs to correctly log to the Merkle audit ledger for SIEM visibility.
2. Architectural Considerations & Risks
-
Risks:
- ForwardAuth Security: Modifying ForwardAuth to accept
guestaccounts risks inadvertently allowing guests to access applications they are not explicitly scoped for. Strict validation ofauth.customScopesagainst the requestedappRecord.nameis critical. - Launchpad Leakage: The
getDashboardAppsquery modification must be robust. If the UNION query is not correctly structured, it could leak visibility of unregistered or unauthorized apps to guests. - Audit Logging Integrity: Failure to capture the audit events properly
during the
joinphase would break SIEM visibility. Using the non-blockingauditWrapper.auditLogis required to avoid impacting user request latency while ensuring compliance.
- ForwardAuth Security: Modifying ForwardAuth to accept
-
Alternatives:
- We considered a bypass in
ui/db_queries.tswhere guests completely skip thegrantsJOIN. However, using aUNIONis structurally superior as it seamlessly supports both pure guests and regular active users who might hold delegated scoped passes. It provides a unified data retrieval flow.
- We considered a bypass in
3. Proposed Implementation
Phase 1: ForwardAuth Guest Ingress (server/routes/auth_forward.ts)
- Permit Guest Accounts: Update the account status validation to allow
user.account_status === 'guest'in addition to'active'. - Custom Scopes Validation: If the user is a guest (or relying on custom
scopes), verify that
auth.customScopescontains the explicit application grant (e.g.,app:${appRecord.name}). If not, return a 403 Forbidden. - Header Injection: For guest sessions, compute the scopes to inject into
X-Forwarded-Scopesby taking the comma-joined list ofauth.customScopes(auth.customScopes.join(",")). This propagates the app scope (e.g.,app:ed-droid) and role (e.g.,viewer) to downstream reverse proxies.
Phase 2: Launchpad App Query (ui/db_queries.ts & ui/mod.ts)
- Function Signature Update: Update
getDashboardApps(userId: string, isAdmin: boolean, customScopes?: string[])to accept the session's custom scopes. - UNION Query: Update the non-admin SQL query to use a
UNION.- The first part queries explicitly granted apps via the
grantstable. - The second part parses the provided
customScopesarray to extract allowed app names (e.g., stripping theapp:prefix), querying theappstable for those matching names, and assigning them a pseudo-role such as"Guest (Viewer)"(or extracting the role from the scopes if possible).
- The first part queries explicitly granted apps via the
- UI Integration: In
ui/mod.ts, passauth.customScopesfrom the resolved session intogetDashboardApps.
Phase 3: Join Audit Logging (server/routes/events.ts)
- Audit
POST /api/join(Web): Immediately after minting the guest session, invokeauditWrapper.auditLog(guestUuid, "event_seat_claimed", event.id, { slug: event.slug, name: event.name, seatNumber: event.seats_claimed, method: "web" }, getClientIp(c)). - Audit
GET /join/:slug(CLI): Similarly, wireauditWrapper.auditLog(guestUuid, "event_seat_claimed", event.id, { slug: event.slug, name: event.name, seatNumber: event.seats_claimed, method: "cli" }, getClientIp(c))into this endpoint before returning the token.
Phase 4: Unit Testing
- ForwardAuth Tests (
server/tests/forward_auth.test.ts):- Add tests simulating a guest session with an
app:{name}scope to ensure a200 OKresponse with correctly formattedX-Forwarded-Scopes. - Add tests simulating a guest session without the necessary
app:{name}scope to ensure a403 Forbiddenresponse.
- Add tests simulating a guest session with an
- Events Tests (
server/tests/events.test.ts):- Ensure the
POST /api/joinandGET /join/:slugassertions capture theauditLogspy calls and verify the exact payload (event_seat_claimedaction,event.idas resource, correct metadata structure).
- Ensure the