Skip to content

0008 — Gate the learner-web Sync monitor to admins

Status: done — built 2026-07-10, same day as opened Opened: 2026-07-10 · Area: learner-web (/sync route, nav, home hero action) Resolution: canSeeSyncMonitor (learner-web features/auth/lib/policy.ts, wrapping hasAdminConsoleAccess — the claims were already client-side via the shared auth bindings) gates the nav button, the home hero action, and the /sync route (no-flash home redirect for authenticated non-admins). Deliberately no server-side enforcement, per the not-security framing below. Predicate + redirect covered by unit and render tests.

Surfaced during the prototype-copy rewrite (2026-07-10): the Sync monitor — mutation-queue tiles (Pending/Sending/Acked/Failed), sync phase, and direct queue controls (flush/retry/reconcile) — renders unconditionally for every signed-in learner: nav button (__root.tsx ~L228), home hero action (index.tsx ~L67), and the /sync route itself (no guard, no beforeLoad). The owner’s working assumption was that it was already restricted to org/platform admins; it is not.

“This isn’t in any way a security measure, it is just distracting noise for anyone who is not an admin.” The data shown is the learner’s own synced dataset — no confidentiality issue; the queue controls are recoverable diagnostics. The gate is a UX concern: hide the nav item, the home hero action, and ideally the route for non-admin sessions.

  • Learner-web needs a client-side “is admin” signal to gate on — check what the session/authClaim actually carries in learner-web before designing (admin-console has scope data; learner-web may not surface roles today). If no signal exists, the smallest honest step is hiding the two links behind a dev/admin flag and leaving the route URL-reachable (explicitly fine given the not-security framing).
  • Copy on the screen stays engineer-register (per the prototype-copy rulings); no learner rewrite needed once hidden.