Glossary
Agent
agent.py, the Python 3 daemon on each workstation. Serves the loopback setup API, holds one WebSocket to its organization's OrgHub (/api/devices/ws) for status, frames, configuration and commands — falling back to the three-second POST /api/telemetry heartbeat when it cannot — syncs the Chromium policy, and executes operator commands. Started from the Openbox autostart under a supervisor loop, not as a systemd service — it needs the kiosk user's X session. → Client Agent
Allowlist
The set of domains a workstation's Chromium may load. Chromium blocks everything by default (URLBlocklist deny-all) and URLAllowlist re-permits. The effective allowlist is the organization's permanent list unioned with every portal app's host and the active broadcast's host, computed per heartbeat by buildEffectiveWhitelist().
Automatic bug report
An opt-in, per organization: a workstation's error or warning, redacted (no addresses, host names, identifiers, or organization or workstation names), filed by the hourly cron as a GitHub issue in the platform's GITHUB_ISSUES_REPO, or linked to a matching issue already filed. Requires accepting the current Automatic Bug Report Terms (/terms/bug-reports). → Admin Console Guide
Boot report
What an installed workstation's last boot did with its system image (installed, failed, rolled-back, fallback, error), recorded by labkiosk-boot-slots check in /run/labkiosk-update/status.json and posted by the agent to POST /api/devices/boot-report. Kept on the workstation's client_devices row; anything but installed is also listed in Errors & Warnings.
Broadcast
A page URL pushed to a whole lab at once, persisted on the tenant row so it survives reboots and colo differences. Not its own command action: it is navigate to target: "all" plus a broadcastEpoch. → Admin Console Guide
Broadcast epoch
A monotonic marker (tenants.broadcast_epoch for the whole organization, client_devices.broadcast_epoch for a broadcast sent to selected workstations) that lets a workstation tell a new broadcast from one it already obeyed, so it navigates exactly once rather than every three seconds. The heartbeat serves whichever of the two is newer; a reset to the portal is recorded with an epoch too, so it outranks an older broadcast. 0 means no broadcast is active.
Client ID
A workstation's human-readable identifier — PC-01, LAB3-07. Matches ^[A-Z0-9][A-Z0-9_-]{0,62}$. Chosen at enrolment; changing it means decommissioning and re-enrolling.
Command delivery receipt
A row in an OrgHub's deliveries table (command_id, client_id) recording that a workstation has received a command, so a broadcast executes exactly once per machine.
OrgHub
The Durable Object each organization has one of: it holds the WebSockets of its workstations and consoles, who is online, and the command queue, and writes the registry back to D1.
Control plane
The Cloudflare Worker and its D1 database. One deployment serves every organization. → Control Plane Internals
Curtain
See Lock curtain.
D1
Cloudflare's SQLite-at-the-edge database. Lab Kiosk's only durable store.
Device token
A 32-byte random hex bearer token issued to a workstation at enrolment. Only its SHA-256 is stored. It — never the request body — determines a workstation's identity and tenant on /api/devices/ws, /api/telemetry and /api/devices/boot-report.
Enrollment key
A per-organization shared secret a new workstation exchanges once for its own device token. Empty by default, and an empty key authenticates nothing. Rotating it does not affect already-enrolled workstations.
Errors & Warnings
The Settings sub-tab (?tab=issues) listing problems an organization's workstations reported themselves, such as a system update that failed its first boot and was rolled back. Kept in workstation_issues for 90 days, apart from the audit log, which records what people did. Also where automatic bug reports are turned on.
ESP
EFI System Partition. Partition 2 of the installed layout (2 MiB – 514 MiB, FAT32), holding the UEFI bootloader. GRUB's modules, grub.cfg and grubenv live on LABKIOSK_ROOT under boot/grub/ instead (--boot-directory).
Fail closed
Missing configuration is an error, not a reason to fall back to something weaker. Unapplied migrations, absent super-admin secrets, and unverified build pins all refuse to proceed.
Guard
A function in src/guard.ts enforcing authorization before a handler runs: resolveTenant(), requireTenantAdmin(), requireSuperAdmin(), requireDevice(), rejectCrossSiteMutation(). A route without one is a security defect.
Hybrid GPT
The installer's four-partition layout — bios_grub, ESP, ROOT, DATA — that boots on both legacy BIOS and UEFI machines. → Disk Installer
Image store
What an installed disk's LABKIOSK_ROOT is: no root filesystem, but images/<version>/ (vmlinuz, initrd.img, filesystem.squashfs, copied from the live medium) plus boot/grub/. The installed system boots the chosen image through live-boot, exactly as the ISO does. Two images fit, so an update can be tried and rolled back. → Disk Installer
is_live_session()
The check, implemented identically in the agent and the installer, deciding whether the machine booted from removable media (/run/live, boot=live) or from an installed disk. An installed disk boots through live-boot too, so labkiosk.installed=1 on the kernel command line is what tells them apart (or /etc/labkiosk-installed on a disk installed before the image store).
Kiosk user
The unprivileged Linux account the whole session runs as. Has an empty password rather than a locked one — a locked account deadlocked nodm's PAM stack — and exactly one sudo grant, NOPASSWD on the installer.
LABKIOSK_DATA
The 512 MiB ext4 partition at the end of an installed disk, mounted at /etc/labkiosk. The only persistent write target on an installed workstation, existing so a post-install enrolment survives a reboot.
LABKIOSK_ROOT
The ext4 partition of an installed disk that holds the image store and boot/grub/ (grub.cfg, grubenv, the boot password in labkiosk-password.cfg, the DATA partition's UUID in labkiosk-data.cfg). The running system is the squashfs image under a RAM overlay, so nothing on it changes in normal use.
Live-build
Debian's ISO construction toolchain. Driven by auto/config, auto/build, and auto/clean under distro-builder/.
Lock curtain
A full-screen overlay the extension raises on every tab when an operator sends lock. Swallows mouse, keyboard, and touch events in the capture phase. A DOM-level block, not an X11 input grab. → Browser Extension
Loopback API
The agent's HTTP server on 127.0.0.1:8888. Requires a loopback Host and a loopback Origin — or the kiosk extension's own pinned chrome-extension:// origin, which Chromium puts on the service worker's POST to /api/admin/verify; either check failing returns 403.
Manifest V3 / MV3
Chromium's current extension platform. Lab Kiosk's extension uses a service worker (background.js) rather than a persistent background page.
Mode
portal (the app-launcher grid) or single_url (one destination, no launcher). Stored on the tenant row and delivered in every telemetry response.
nodm
The minimal auto-login display manager that starts the X session as kiosk. Configured through /etc/default/nodm rather than a systemd unit in the overlay.
Nonce
A random per-response value stamped on every <script> and named in the Content-Security-Policy header. A script without it does not execute.
noVNC
The HTML5 VNC client. The console serves it from /novnc/ (the exactly pinned @novnc/novnc package) on its Remote Control viewer page; the simulator also serves its own copy on port 6080. The workstation image has none.
One-try boot
How an installed workstation tries a new system image: grubenv names current, previous, next and next_tries. GRUB spends the try before booting next, so any failure (a hang, a panic, a power cut) ends with current on the following boot. labkiosk-boot-ok.service runs labkiosk-boot-slots check, which confirms the new image once the agent and the browser stay up for about a minute, or reboots into the old one. See Rollback.
Openbox
The window manager, running with a deliberately empty keybinding table so Alt+Tab, Alt+F4, and Ctrl+Alt+Del are inert.
overlayroot
The Debian package for a read-only root with a RAM overlay. Still shipped in the image with overlayroot="tmpfs:recurse=0" in /etc/overlayroot.conf and on every boot command line, but the RAM overlay itself now comes from live-boot (boot=live), on live media and installed disks alike: a read-only squashfs under a tmpfs layer. That overlay is the project's core guarantee.
PBKDF2
The password hashing function, run through crypto.subtle: HMAC-SHA256, 100 000 iterations, 32-byte random salt, 256 derived bits.
Portal site / portal card
An application card on the User Portal. Adding one implicitly authorises its domain. → User Portal
RemoteRelay
The Durable Object, one per workstation, that carries a Remote Control session: it pairs the console viewer's WebSocket with the one the agent opens on request and forwards the VNC bytes between them. Sessions must be joined within 60 seconds and last at most four hours. → Remote Control
Reserved slug
A subdomain the platform keeps for itself: www, super, labkiosk, api, admin, portal, status, mail, app, kiosk, root. Neither registerable nor resolvable as an organization.
Rollback
The return to the previous system image when a new one does not confirm its one-try boot. Reported as rolled-back (or failed, when the health check failed on that boot) and shown in Errors & Warnings.
Shadow DOM
The isolated DOM subtree the extension's UI lives in, attached with { mode: "closed" } so page script cannot reach it.
single_url mode
Total lockdown to one destination, with no launcher. See Mode.
Simulator
The Docker container that behaves like an enrolled thin client, viewable through noVNC. Defined by the repository-root Dockerfile. → Workstation Simulator
Super admin
The platform operator, distinct from an organization's organization admin. Approves and suspends organizations, and binds custom domains. → Super Admin Guide
Telemetry
The workstation's state flowing up to the control plane, and configuration and commands flowing down. The main channel is the WebSocket to the OrgHub (/api/devices/ws): status on change, frames only while an operator watches; allowlist, mode, target, broadcast and commands pushed as they change. The three-second POST /api/telemetry heartbeat is the fallback for agents without the WebSocket client, carrying the same in one request and reply.
Tenant
One organization. Every query touching devices, commands, sessions, or portal apps filters by tenant_id.
Thumbnail
A base64 JPEG captured with scrot -t 20 -q 35: sent as a frame over the WebSocket only while an operator is watching that workstation, or with every HTTP heartbeat on the fallback path. Dropped — not shrunk — when it would exceed 256 KB.
toram
An opt-in boot menu entry copying the whole image into RAM before starting, so the USB stick can be removed. Not what the default entry does.
websockify
Bridges the WebSocket the browser speaks to the raw VNC port x11vnc listens on. Used only by the simulator, on port 6080, so a developer can watch its screen; the workstation image has no websockify.
Wizard
wizard.html, the first-boot setup and installation UI served by the agent at http://127.0.0.1:8888/setup. Returns 403 once the workstation is enrolled.
x11vnc
The VNC server exporting display :0, bound to loopback with a per-boot ephemeral password and run with -noclipboard -noremote -nocmds.