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