Skip to content

Chaos admin — instructor panel

The chaos-admin instructor panel is the main interface used by instructors to drive a PerfShop session. It is served by the same container as the student page (perfshop-chaos-admin) but organized in a dedicated subpath: /admin/. It is protected by authentication and exposes advanced controls that the student page does not provide.

Sources

chaos-admin/public/admin/index.html, login.html, gestion.html, mon-compte.html, chaos-admin/public/admin/chaos-sections.js, chaos-admin/public/admin/js/{login.js, gestion.js, gestion-licence.js, mon-compte.js}

The three HTML pages

Page URL Access
login.html /admin/login.html Public
index.html /admin/ Requires sessionStorage.chaos_auth === 'true'
gestion.html /admin/gestion.html Requires auth and chaos_is_superadmin === 'true'
mon-compte.html /admin/mon-compte.html Requires auth (any admin)

The protection is a simple JavaScript guard at the top of each page:

if (sessionStorage.getItem('chaos_auth') !== 'true') {
  window.location.href = 'login.html';
}

This guard is deliberately client-side — real security is handled server-side by the Spring Boot backend which verifies the HTTP session and/or the X-Admin-Token header on each API call. See Admin authentication.

Login

login.html is a simple form (email + password) that calls POST /api/admin/login. On success, the backend returns:

{
  "email": "admin@perfshop.fr",
  "adminToken": "abcd...",
  "isSuperAdmin": true,
  "canAccessChaos": true,
  "canAccessMonitoring": true,
  "canAccessAdmin": true
}

The login.js script stores this information in sessionStorage and redirects to /admin/:

  • chaos_auth, chaos_user, chaos_token
  • chaos_is_superadmin
  • chaos_can_access_chaos, chaos_can_access_monitoring, chaos_can_access_admin

The backend returns HTTP 402 if no valid license is active — the form then displays a message explaining that a license is required to access the instructor panel. This is an important security rule: without a license, even the admin login is blocked. License activation must therefore go through the student page (which remains accessible) or through the PERFSHOP_LICENSE_KEY environment variable.

Main page — index.html

The main page displays seven tabs:

flowchart LR
  B[🔧 Backend Chaos]
  F[🖥️ Frontend Chaos]
  S[🔐 Scripting Chaos]
  M[🧑‍💼 Business Chaos]
  Sec[🔒 Security Chaos]
  Fn[⚡ Functional Chaos]
  P[🎓 Pedagogical]
  B --> F --> S --> M --> Sec --> Fn --> P

Header and global buttons

  • ↻ Reload — calls loadCurrentState() and refreshes all panels
  • ⊘ Reset all — resets all chaos families in a single operation
  • ⚙️ Administration — opens gestion.html, visible only if chaos_is_superadmin === 'true'
  • 👤 My account — opens mon-compte.html, visible for any admin
  • Logout — empties sessionStorage and calls POST /api/admin/logout

Student mode bar

Just below the warning is a student mode control bar:

State Behavior on the student side
✅ Active (green) The student page is usable, sliders respond to clicks
🔒 Blocked (red) The student page displays the "Session not started — waiting for instructor" banner and all sliders are locked

The toggleStudentMode() button toggles this state via POST /api/chaos/student/admin/mode { enabled: !current }. This is the main lever the instructor uses to start or stop a session.

Backend Chaos tab

Rendered dynamically via chaos-sections.js. Displays a grid of cards — one per infrastructure chaos (CPU, memory, GC, DB pool, thread pool, slow queries, deadlock, network). Each card displays the current intensity, a control slider and real-time metrics. A 5-second poll refreshes the request counters and intensities. See Performance Chaos.

Scripting Chaos tab

Five stacked cards (sc-card-0 to sc-card-4) present the five levels:

  • Disabled — free API, no tokens
  • Junior — X-Session-Token on the checkout
  • Confirmed — Double token + action correlation
  • Expert — CSRF + sequential step + HMAC signature (15 s)
  • Maestro — HMAC key derived per session

Each card contains a JMeter/k6 code example that the student can reproduce. A click on a card calls setScriptingLevel(N). The active card carries the CSS class .active. See Scripting Chaos.

Business Chaos tab

Five cards (N0 to N4 — Master). The selected card triggers setBusinessLevel(N) which sends POST /api/chaos/business with the requested level. Each level cumulatively adds anomalies A1 to A16. A reset button resetBusiness() forces the return to level 0. See Business Chaos.

Security Chaos tab

Same structure as Business — five cards N0 to N4 (Master) activating flaws S1 to S12. The Master card activates the hidden admin portal which unlocks S10, S11 and S12 (chained scenario GET /api/admin/portal/statsPOST /api/admin/portal/loginPUT /api/admin/portal/accounts/{id}/promote). A real-time counter sec-hits-label displays the number of detected attacks. See Security Chaos.

Functional Chaos tab

Five cards presenting the F1 to F4 anomalies:

  • N1 — F1: NullPointerException in processPaymentPublic()
  • N2 — F1 + F2: StackOverflow in calculateOrderTotal()
  • N3 — F1 + F2 + F3: OutOfMemoryError in getAllProducts()
  • N4 Master — F4: silent data corruption (no crash, corrupted payload)

A counter panel displays live the occurrences of each exception. See Functional Chaos.

Frontend Chaos tab

Grid of cards for CPU burn, memory leak, DOM flood, fetch flood. No server impact — the chaos runs in visitor browsers via chaos-agent.js which polls /api/chaos/frontend/state every 5 seconds. See Frontend Chaos.

Pedagogical tab

Rendered dynamically by buildPedagogyAdminPanel() in chaos-sections.js. Allows the instructor to:

  • Select a journey level (BAC1 to BAC5) — independent of the student slider
  • Set the timer (duration in minutes before expiration)
  • Enable or disable the memory cache of pedagogical sessions (pedagogical value: when enabled, MutableSession objects appear in heap dumps during a Memory Chaos, demonstrating a token leak)
  • Enable or disable hints
  • View the list of active student sessions and their progress
  • Trigger a global journey reset

License panel on gestion.html

In the superadmin's gestion.html page there is a panel dedicated to the license (chaos-admin/public/admin/js/gestion-licence.js) that exposes:

  • The current state (plan, holder, issue date, expiration date, days remaining, unlocked features)
  • A <textarea> to paste a new PFSH-xxx.yyy key
  • An Activate button that calls POST /api/license/activate
  • A Revoke button that calls POST /api/license/revoke
  • A help block explaining how to inject the key via .env at startup

See License system.

Admin account management — gestion.html

Accessible to the superadmin only. Displays the list of admin accounts as a table with the columns: email, chaos-admin, monitoring, backoffice, JMeter, Scripts, role, created on, actions.

Three actions are available:

  • Create an account — form with email, password (min 6 characters) and permission checkboxes
  • Change passwordmodal-password modal
  • Modify permissionsmodal-rights modal, except for the superadmin (fixed permissions)
  • Delete — except for the superadmin

All requests go through adminFetch(), a wrapper that automatically injects X-Admin-Token from sessionStorage.chaos_token into every request. This wrapper is necessary because in cross-origin deployments (NAS, third-party HTTPS, local HTTP), the session cookie does not always follow: the explicit token is the reliable path.

My account page

mon-compte.html is accessible to any logged-in admin, including the superadmin. It allows everyone to change their own password. The form displays:

  • A New password field with a strength indicator
  • A Confirm password field
  • A "Save" button

The mon-compte.js script exposes checkStrength(value) which computes a score and updates the .strength-bar, then savePassword() which sends PUT /api/admin/accounts/me with the new password after confirmation verification. The strength is purely visual — the server policy enforces a minimum of 6 characters.

Internationalization

All displayed texts use the data-i18n="key" attribute and are replaced at load time by applyI18n() from public/i18n/{fr,en}.json. The i18n.js loader is shared with the student page and allows adding a language without modifying any code — just add a public/i18n/<lang>.json file and set PERFSHOP_LANG to the corresponding value. See Ancillary tools.