The address people remember. Sign in with Keycloak, then a grid of links to everything else.
Deliberately one page. Its job is to get you somewhere else quickly; anything more becomes something to maintain that nobody asked for.
- Next.js 15, App Router. Server-rendered, no client state to speak of.
- No database. JWT sessions, so it can be restarted or rescheduled without logging anyone out.
- No authorisation of its own. It shows links; each service authenticates you when you arrive. A link grid is not a security boundary and pretending otherwise would be worse than not trying.
Every link is an environment variable with no default (LINK_CHAT, LINK_WORKSPACE, …). A link
whose variable is unset renders as a disabled "coming soon" card rather than a button that 404s —
admitting something is not ready costs less trust than a dead link does.
The Helm chart derives those variable names from values.links, so links.computerUse becomes
LINK_COMPUTER_USE. Verified by rendering, not assumed.
npm install
cp .env.example .env.local # fill in the Keycloak client
npm run devAUTH_SECRET can be anything ≥32 chars locally; in the cluster it comes from a Secret.
Image builds to ghcr.io/wide-moat/lab. Runtime config only — no environment values are baked in
at build time, so one image serves stage and prod rather than needing a rebuild per environment.
The OIDC client secret and the NextAuth signing key come from the lab-oidc Secret, delivered
from OpenBao by External Secrets. Neither is ever in values or in git.
publicUrl must match the redirect URI registered for the lab client in Keycloak
(stacks/identity in platform-infra). A mismatch fails with "invalid redirect_uri" and no hint
about which side is wrong.