Files
rootnode-academy/platform
ced4568 face0ae132 test(phase3a): add identity and RBAC end-to-end coverage
New e2e-phase3a.js (21 cases): no account enumeration, CSRF positive/negative, login rate
limiting, RBAC across all three roles, cohort-scoped instructor access (visibility + route
access), last-owner protection, live role/status re-evaluation (no separate revoke needed),
password change (old password rejected after, other sessions revoked), audit log content
(including a no-secrets-in-metadata assertion), student session RBAC/logout, and session
persistence across a REAL docker compose restart api mid-test.

New session-helper.js — a shared cookie-jar test helper (Node's fetch doesn't persist
cookies across calls) that also auto-attaches X-CSRF-Token from whichever rn_csrf_*
cookie it's holding, replacing the single-cookie-string trackers e2e-phase2a.js and
e2e-phase2b.js each had their own copy of.

e2e-phase2a.js and e2e-phase2b.js updated for the new auth model: admin login is now a real
bootstrapped OWNER_EMAIL/OWNER_PASSWORD account instead of the old shared ADMIN_PASSWORD.
All cases still passing: 10/10 and 12/12 respectively.
2026-08-18 13:36:45 -05:00
..

RootNode Academy — Platform

The full multi-student platform, layered on top of the unmodified Lab image at the repo root. Start here, then go to the component you need:

  • provisioner/ — Postgres-backed environment registry and lifecycle. Design: docs/LAB_ARCHITECTURE.md, docs/PHASE1_PLATFORM_FOUNDATION.md. Operational reference: provisioner/README.md.
  • api/ — the lightweight Platform API: students, cohorts, enrollments, curriculum, progress, scenario attempts, student/admin sessions, and the instructor/admin control plane. No k3s, no --privileged — this replaced Phase 2A's "identity" instance, which was a full Lab image booting an unused k3s cluster just to serve these APIs. Design: docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md. Operational reference: api/README.md.
  • gateway/ — the only student-facing path to a Lab (HTTP + WebSocket proxy, environment-aware routing derived from a server-controlled session — not a client-suppliable header/param). Design: docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md (routing), docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md §3 (session ownership).
  • egress-proxy/ — shared allowlisting proxy every Lab's outbound traffic passes through.
  • docker-compose.dev.yml — the full stack (Postgres, egress proxy, Provisioner, Platform API, Gateway) on one machine. This is the Phase 1/2A/2B local dev exception — production is the two-VM Proxmox split described in docs/LAB_ARCHITECTURE.md §1.

Running the full stack locally

cd platform
echo "PROVISIONER_SHARED_SECRET=$(openssl rand -hex 32)" > .env
echo "ADMIN_PASSWORD=$(openssl rand -hex 12)" >> .env
docker compose -f docker-compose.dev.yml build
docker compose -f docker-compose.dev.yml up -d

No k3s boot to wait for at this layer anymore (Platform API starts instantly) — the whole platform is reachable at http://localhost:4200 (the Gateway) right away: students at /, instructors at /admin.

Tests

  • provisioner/test/run.js — fast, isolated Provisioner tests (network/container/firewall mechanics, no Gateway/Platform API involved). Run against provisioner/docker-compose.dev.yml.
  • test/e2e-phase2a.js — student-flow regression through real session cookies: roster → login → curriculum → launch → Gateway routing → cross-student rejection → progress relay → reset.
  • test/e2e-phase2b.js — the classroom acceptance workflow: instructor creates a cohort, adds students, assigns curriculum, Prepare Labs (concurrent), students complete different scenarios, instructor resets one, instructor destroys all cohort Labs after class — progress survives every step. Needs ADMIN_PASSWORD set (see platform/.env).

Both e2e suites are slow (real k3s boots) and need the full stack up. Neither substitutes for the manual real-Lab-image checks (node-pty, terminal WebSocket, kubectl, scenario validation) in docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md §8 — those need a browser-equivalent client and aren't automated here.

Known limitations

See provisioner/README.md (Phase 1), docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md §9 (Phase 2A), and docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md §13 (Phase 2B) for the full, honest lists — including in-memory sessions, the single shared admin credential, and exam mode's live bookkeeping staying Lab-local.