Skip to content

Admin panel

The admin panel lives at /admin/ and is restricted to users with is_admin = true. Every action you take in the panel writes a signed entry to the audit chain.


Logging in as admin

Log in with the admin account at /auth/login. The admin credentials are seeded from the ADMIN_USERNAME and ADMIN_PASSWORD environment variables on first run. Once logged in, the /admin/ prefix is accessible; non-admin users who attempt to reach it receive a 403.


Dashboard (/admin/)

The dashboard gives you a live operational snapshot:

Core stats row

  • Total users, teams, challenges (total and visible)
  • Total submissions and solves

Activity row (time-windowed)

  • Submissions in the last hour / last 24 hours
  • Solves in the last hour
  • Active users in the last hour (based on USER_LOGIN audit events)
  • Running container instances
  • New registrations in the last 24 hours

Security row

  • Wrong flag attempts (total and last hour)
  • Banned users
  • Unique IPs seen (total, from logins, from instance spawns)

Challenge solve breakdown

  • Top 5 most-solved visible challenges
  • Bottom 5 least-solved visible challenges

Event breakdown

  • Top 10 event types by count in the last 24 hours
  • Severity totals (INFO / WARNING / CRITICAL) across all time

Running instances panel

Lists every instance currently in running state, sorted by expiry time. From here you can extend an instance's window.

Score adjustment

A quick form at the bottom of the dashboard lets you apply a manual point adjustment (+ or -) to any Principal. You must supply a reason; the adjustment is recorded as a MANUAL_SCORE_ADJUST WARNING event.

Scoreboard freeze toggle

A single button freezes or unfreezes the public scoreboard. The frozen state persists in the Flask-Caching layer until the app restarts or you unfreeze it. Freeze events are logged as SCOREBOARD_FREEZE_TOGGLED.

Docker telemetry panel

When LAB_DOCKER_HOST is configured, the dashboard shows per-container CPU, memory, and network I/O for every running instance. If the Docker host is unreachable the panel reports "unavailable" without crashing the dashboard.

WireGuard telemetry panel

When WireGuard is configured, the dashboard shows connected peers, expected peers per lease, and any stale peers (peers with no known lease).

Two action buttons appear:

  • Reconcile VPN peers — re-syncs all WireGuard peer configs from the instance metadata. Use this if peers went stale after a restart.
  • Test VPN access — probes the WireGuard interface and reports status.

Challenges (/admin/challenges)

A table of all challenges, sorted by category then point value, with status badges (Visible / Hidden). From this page you can:

  • Toggle visibility — makes a hidden challenge visible (or vice versa). When a challenge becomes visible, flags are pre-generated for all active Principals. Logged as CHALLENGE_TOGGLED.
  • Generate files — runs the challenge workspace generator with an admin-preview flag. Useful for checking that the importer and build scripts work before exposing the challenge to players.
  • Navigate to edit or delete.

Create a challenge (/admin/challenges/new)

Fields:

Field Notes
Title Max 200 characters
Slug URL-safe identifier, must be unique
Category One of: crypto, web, pwn, misc, osint, rev, forensics
Description Markdown rendered at display time
Points 1–10000
Flag prefix Defaults to the server's DEFAULT_FLAG_PREFIX (e.g. GRIZZ)
Requires container Enables the dynamic-challenge fields below
Container image Docker image reference
Container port Port the container listens on (1–65535)
Service scheme http, ws, ftp, gopher, ssh
Port transport TCP / UDP / SCTP
Lab stack JSON Full multi-service stack spec (optional, validated against ChallengeStackSpec)
Status Hidden (default) or Visible
Attachments Files served to players; allowed types include common binary, source, and document formats

Saving a visible challenge pre-generates flags for all active Principals. Logged as CHALLENGE_CREATED.

Edit a challenge (/admin/challenges/<id>/edit)

Same fields as create. If you change a challenge from Hidden to Visible, flags are generated for all active Principals at save time. Logged as CHALLENGE_UPDATED.

Delete a challenge

Deletes the challenge row and all associated submissions, solves, flags, and uploaded files. The event log challenge reference is nulled (events are not deleted). Logged as CHALLENGE_DELETED at WARNING severity.


YAML import (/admin/challenges/import)

Upload one or more .yaml / .yml files and CTFHive parses each one through the challenge importer (ctfapp/services/challenge_importer.py). The results page shows per-file status: ok, skipped, or error with a reason.

The full YAML schema is documented at Challenge format. Import activity is logged as CHALLENGES_IMPORTED.


Users (/admin/users)

A table of all users, sorted by registration date (newest first). For each user you can:

  • Toggle admin — grants or revokes is_admin. You cannot toggle your own admin status. Logged as ADMIN_TOGGLED at WARNING severity.
  • Ban / unban — sets state to "banned" or "active". Banned users cannot log in. You cannot ban yourself. Logged as USER_BAN_TOGGLED at WARNING severity.

Appearance (/admin/appearance or /admin/theme)

Limited customization

See Theming for a precise description of what is and is not configurable.

The appearance page exposes the UI knobs that do work. Theme, layout, and font-pack switching are preserved as stubs in the codebase for backward compatibility but currently only one choice exists for each. The functional controls are UI density and UI motion (and by extension the background animation, set via Site Settings).


Audit log (/admin/events)

A paginated view of the event_log table, newest first. Filter by:

  • Severity: ALL / INFO / WARNING / CRITICAL
  • Event type: substring search (e.g. FLAG, USER_LOGIN)

Each entry shows: timestamp, severity badge, event type, actor user ID, principal ID, challenge ID, and the JSON payload.

The audit log is tamper-evident. The Verify chain button at the top of the page (/admin/events/verify-chain) re-walks every entry and checks that each entry's HMAC signature matches its recomputed value. If the chain is intact you get a green confirmation flash. If any entry has been modified or deleted since it was written, the flash reports the first bad event ID.

See Audit chain for the technical details of how the chain is constructed.


Site settings (/admin/settings)

These global settings are stored in the app_settings table and cached in memory for 5 minutes.

Setting Default Description
max_team_size 4 Maximum members per team (enforced at join time)
default_bg_animation matrix Background animation shown to new visitors
allow_solo_play true Allow players to create solo Principals
allow_team_switch true Show the solo-to-team switch option
registration_open true Allow new user registration

Changing any setting is logged as SETTINGS_UPDATED.

Background animation choices

Value Description
matrix Matrix rain (canvas)
particles Particle network (canvas)
mrrobot Mr. Robot effect (canvas)
binary Binary rain (canvas)
hexgrid Hex grid pulse (canvas)
starfield Starfield warp (canvas)
circuit Circuit board (canvas)
rain Rain drops (canvas)
fireflies Fireflies (canvas)
topography Topographic map (canvas)
dna DNA helix (canvas)
waveform Audio waveform (canvas)
glitch Glitch effect (canvas)
constellation Constellation (canvas)
plasma Plasma — GPU-accelerated (WebGL)
aurora Aurora borealis — GPU-accelerated (WebGL)
nebula Nebula — GPU-accelerated (WebGL)
voronoi Voronoi flow — GPU-accelerated (WebGL)
electric Electric storm — GPU-accelerated (WebGL)
fluid Fluid gradient — GPU-accelerated (WebGL)
none No animation

GPU animations require WebGL support in the player's browser. Fall back to a canvas option if you are unsure about your audience's hardware.


Audit events written by the admin panel

Event Severity Trigger
CHALLENGE_CREATED INFO New challenge saved
CHALLENGE_UPDATED INFO Challenge edited
CHALLENGE_TOGGLED INFO Visibility toggled
CHALLENGE_DELETED WARNING Challenge deleted
CHALLENGES_IMPORTED INFO YAML import completed
INSTANCE_EXTENDED INFO / WARNING Instance time window extended
ADMIN_TOGGLED WARNING Admin status changed
USER_BAN_TOGGLED WARNING User banned or unbanned
MANUAL_SCORE_ADJUST WARNING Manual point adjustment
SCOREBOARD_FREEZE_TOGGLED WARNING Scoreboard frozen or unfrozen
SETTINGS_UPDATED INFO Site settings saved
THEME_CHANGED INFO Active theme changed
LAYOUT_CHANGED INFO Active layout changed
FONT_PACK_CHANGED INFO Active font pack changed
UI_DENSITY_CHANGED INFO Density mode changed
UI_MOTION_CHANGED INFO Motion mode changed
PRESET_APPLIED INFO Appearance preset applied
VPN_RECONCILED INFO / WARNING WireGuard peer reconcile run
VPN_ACCESS_TESTED INFO / WARNING WireGuard access probe