Appearance
Student Role & Journey
Purpose
Students are BSIT Network & Cybersecurity learners. They use the platform to practice attack and defense skills in a private lab, guided step by step, with automatic scoring. A student can only ever see and change their own labs, scores and reports.
Pages and navigation
| Page | What the student sees | Source |
|---|---|---|
/login | Sign-in page; the Enter Cyber Range button starts the Keycloak login | cyberrange/portal/src/app/login/page.tsx |
/orientation | One-time lab orientation shown before any other page until the student presses Continue to the lab portal: choose a lab, provision a pod, follow the guide, finish cleanly. Completion is stored by the API, so it is shown once per account, not once per browser | cyberrange/portal/src/app/orientation/page.tsx, components/auth/OnboardingGate.tsx |
/dashboard | Welcome, "Continue learning" with progress per scenario, "How labs work", live lab status, and My Verification Requests (reviews and instructor feedback) | cyberrange/portal/src/app/dashboard/page.tsx |
/scenario/orientation | Scenario 0: a static orientation to the lab layout, scoring and flags; starts no lab | cyberrange/portal/src/app/scenario/orientation/page.tsx |
/scenarios ("My Labs") | An orientation card and four scenario cards: Scenario number, Recommended next badge, difficulty, duration and role (Offensive or Defensive), description, progress (Completed, In progress, Not started with points) and a Start, Continue or Review button | cyberrange/portal/src/app/scenarios/page.tsx, components/scenarios/ScenarioCard.tsx |
/scenario/[id] | The lab workspace: scenario info, Big Picture explanation, provisioning checklist, then a two-pane lab (exercise panel plus terminal or DVWA), verification requests | cyberrange/portal/src/app/scenario/[id]/page.tsx |
/lab/dvwa/... | DVWA served through the portal for Scenario 2's embedded pane (own lab only) | cyberrange/portal/src/app/lab/dvwa/[[...path]]/route.ts |
Sidebar: Dashboard and My Labs (studentNavItems in cyberrange/portal/src/lib/navigation.ts).
Restricted pages: /instructor/* and /admin/* redirect a student to /dashboard (cyberrange/portal/src/lib/routeRoles.ts).
Student workflow
The complete journey
1. Logging in
The student opens the site and presses Enter Cyber Range. NextAuth sends them to Keycloak (authorization code flow with PKCE). After the password, Keycloak asks for a 6-digit code from an authenticator app; the first time, it shows a QR code to enrol one. An account created by an Admin starts with a temporary password, so on the first sign-in Keycloak also asks for a new password; the page shows an advisory strength meter, and Keycloak checks length, common passwords, the username, the email and the last 3 passwords when it is saved. Ordinary words and passphrases are allowed (pull request 249). After sign-in, the portal reads their role from the token and sends them to /dashboard; the very first time, it shows the lab orientation at /orientation first and then returns them to the page they asked for. Log out returns them straight to the sign-in page. An account with no application role is sent to /no-role instead (cyberrange/portal/src/lib/auth.ts, lib/routeRoles.ts, components/auth/OnboardingGate.tsx, cyberrange/deploy/keycloak/themes/cyberrange/login/resources/js/password-strength.js).
2. Browsing scenarios
My Labs starts with the Scenario 0 orientation card, then lists four scenarios from the static catalog in cyberrange/portal/src/hooks/useScenarios.ts. All four can be started in any order. "Recommended next" is only a suggestion based on progress (cyberrange/portal/src/lib/scenarioProgress.ts).
3. Reading guides and objectives
The scenario page shows the objectives and milestones. A Big Picture modal explains the scenario in plain language the first time. Once a lab is running, the exercise panel's Walkthrough shows the current task's section of the Markdown guide from cyberrange/portal/public/scenarios/, rendered with react-markdown, remark-gfm and rehype-sanitize (cyberrange/portal/src/components/scenario/MarkdownView.tsx). The PDF export contains the whole guide.
4. Provisioning a lab
Start lab calls POST /api/pods/provision. The API accepts only if the student has no other live lab, a slot is free (MAX_PODS) and the host has enough RAM and storage. It answers 202 and builds the lab in the background. The portal shows a checklist ("Creating your machines", "Connecting the network", "Linking the SIEM", "Opening your terminal") and polls the status until it is ACTIVE (cyberrange/portal/src/components/scenario/ProvisioningView.tsx, hooks/useScenarioPod.ts).
5. Using the terminal
The lab page opens an xterm.js terminal in the right-hand pane, with only the tabs the scenario needs (Kali only for Scenario 1; Kali and meta for Scenarios 3 and 4; Scenario 2 uses the DVWA pane instead). Each tab is a WebSocket to the terminal bridge, which opens a shell in the matching container inside a tmux session called lab. Kali and dvwa sessions run as user student; meta runs as msfadmin (cyberrange/bridge-src/bridge.py). The target IP addresses are shown in the header and exported in Kali as $TARGET_META and $TARGET_DVWA.
6. Completing tasks
Students work task by task: the outline unlocks each task when the previous one is done. Scenarios 1 and 3 are done in the terminal, Scenario 2 in the embedded DVWA pane, and Scenario 4 on the meta tab. Scenarios 1 and 2 end with a flag the student types into the Status area. See the scenario pages.
7. Viewing scores and progress
The task outline shows each task, its points and whether it is done; the Score area shows the running total and the time left. A background check runs on the server every 3 seconds, and the page re-reads the results every 3 seconds, so completed tasks turn green without clicking anything, with a "Task auto-detected! +N pts" toast. Manual Check forces an immediate check, but only once per task: if it fails, the task locks to instructor review. When every task has passed, a completion dialog opens (cyberrange/portal/src/hooks/useScenarioMilestones.ts, components/scenario/ExercisePanel.tsx).
8. Asking for help or submitting a report
If a task is not detected, the Ask an instructor form (VerificationRequestModal) creates a review request asking "What command did you use?", with up to 5 optional screenshots. The API freezes a snapshot of the lab's SIEM alerts at that moment for the instructor. If the instructor approves it, the task is credited and the points appear in the student's score.
9. Completing a scenario
When every milestone has a PASS, the scenario shows as completed with its points. The student ends the session (the lab is destroyed) or leaves it until the scenario's time limit runs out. Scores stay in the database after the lab is gone.
10. Reviewing results
The dashboard lists the student's review requests with their status (PENDING, APPROVED, REJECTED, RETRY), a hint and the instructor's written feedback. The numeric review score is not shown to the student in this list. A request marked RETRY shows Add detail and send again (cyberrange/portal/src/components/reviews/MyVerificationRequests.tsx).
When every milestone of a scenario is complete, the scenario page says the scenario was completed with full points and offers to start again. Confirming resets that scenario's progress: it permanently deletes the student's own milestone rows for that scenario and writes a SCENARIO_PROGRESS_RESET audit event (cyberrange/portal/src/components/scenario/ScenarioInfoView.tsx, DELETE /progress/{scenario}).
API permissions
All of these routes require an authenticated user with any application role (require_app_role), and all are self-scoped: the student ID always comes from the verified token, never from the request.
| Endpoint | What it allows | Guard |
|---|---|---|
POST /pods/provision | Start one lab for yourself | identity from token, one live lab per account |
GET /pods | List your own live labs | filtered by identity |
GET /pods/{id}/status | Status, IPs, time left for your lab | owner (or admin) |
GET /pods/{id}/lab-urls | DVWA and SIEM links for your lab | owner |
DELETE /pods/{id}/destroy | End your lab | owner |
POST /pods/{id}/verify/{scenario}/{milestone} | Manual Check, once per task (a used attempt returns REVIEW) | owner, lab ACTIVE |
GET /pods/{id}/milestones | Your milestone results for that lab's scenario | owner |
GET /pods/{id}/alerts | SIEM alerts for your lab (six safe fields) | owner |
GET /progress | All your milestone results | identity |
DELETE /progress/{scenario} | Reset your progress for one scenario | identity, audited |
POST /progress/{scenario}/flag | Submit a flag (the portal's flag box on Scenario 1 and 2 Task 5) | identity |
GET /progress/{scenario}/rubrics | Read the milestone rubric | any app role |
GET, POST /users/me/orientation | Read or record your own first-login orientation | identity (sub) from token |
POST /reviews/submit, GET /reviews/{id}, POST /reviews/{id}/resubmit | Create, read and resubmit your own reviews | owner (staff can read) |
POST/GET /reviews/{id}/images, GET/DELETE /reviews/{id}/images/{image} | Upload, list, view and delete screenshots on your own reviews | owner |
Lab and scenario permissions
- One live lab at a time per account. The check runs inside the database transaction and is backed by a unique partial index (
idx_pods_one_active_per_student,schema/v2.sql). - Any scenario, any order. There is no prerequisite lock.
- Lab lifetime: the scenario's limit, 30 minutes (Scenario 1), 45 (Scenarios 2 and 3) or 60 (Scenario 4), counted from the Start request (
SCENARIO_TTL_MINUTES,ttl.py). The reaper checks every 60 seconds and destroys expired labs. - Inside the lab: the student has passwordless
sudoon Kali (userstudent), andmsfadminhas passwordlesssudoon meta so Scenario 4 can edit root-owned files (cyberrange/src/provisioning/provision.py). This is root inside their own containers only.
Data a student can view or modify
| Data | View | Modify |
|---|---|---|
| Own labs (status, IPs, time left) | Yes | Start and end |
| Own milestone results and points | Yes | Created by checks and flag submissions; can reset per scenario (also clears used Manual Checks) |
| Own reviews and instructor feedback (the API also returns the score; the dashboard list does not display it) | Yes | Submit, resubmit when RETRY |
| Own evidence screenshots | Yes | Upload and delete |
| Own lab's SIEM alerts | Yes (allow-listed fields) | No |
| Own authenticator (MFA) | Enrolled at first sign-in | Only by an Admin Reset MFA (no self-service recovery) |
| Other students' labs, scores, reviews, screenshots | No (404) | No |
| Scoring-conflict cases about themselves | No (staff-only) | No |
Check-failure reason codes and the source of each attempt | No (staff-only; the student sees a generic result) | No |
| Own orientation status | Yes | Recorded once by Continue |
| Accounts, roles, audit log, system health | No | No |
What happens on unauthorized attempts
| Attempt | Result |
|---|---|
Opens /instructor or /admin | Redirected to /dashboard |
| Calls an instructor or admin API route directly | 403 Forbidden: Insufficient privileges |
| Uses another student's lab ID or review ID | 404 (the resource looks like it does not exist) |
| Starts a second lab | 409 with ALREADY_PROVISIONED and the existing lab ID |
| Starts a lab when capacity is full | 503 POD_CAP_REACHED, RAM_FULL or STORAGE_FULL |
| Opens a terminal for someone else's lab | "Not authorized for this pod" in the terminal, connection closed (code 1008) |
Sources
cyberrange/portal/src/app/**, cyberrange/portal/src/lib/navigation.ts, lib/routeRoles.ts, hooks/useScenarioPod.ts, components/scenario/*, components/auth/OnboardingGate.tsx, cyberrange/src/provisioning/pods_router.py, onboarding_router.py, alerts_endpoint.py, auth.py, provision.py, cyberrange/bridge-src/bridge.py.