Analytics showed students closing and reopening the lockdown browser 15–20 times inside one invigilated exam, undetected. I shaped a fix that puts a human back in the loop, and argued it through as a platform-wide feature rather than an LDB patch.
A lockdown browser stops a student reaching the rest of their machine while it is open. Nothing stopped them closing it.
Each block is a separate lockdown-browser session in one sitting. Every gap is time spent outside the locked environment — and nothing surfaced it to the invigilator in the room. Schematic, sized from the pattern analytics surfaced.
The signal existed the whole time — in retrospective logs, which could only ever prove misconduct after the exam. Never prevent it.
Respondus itself already offers configurable re-entry limits. A gap in the market is one thing; a gap in the layer customers trust to hold an exam together is another.
Closes the lockdown browser, looks up answers in a normal one, relaunches and carries on. Physically present the whole time.
Declares they're finished, walks out, then completes the exam from another device at home — with help. The session never closed.
UWA identified the behaviour. A second heavy lockdown-browser customer hadn't noticed it. A real vulnerability with almost no customer pressure behind it — work that only gets prioritised if someone makes the case.
There is already a trained human standing in the room. The cheapest reliable check is the one that uses them — not more detection.
Exploiting the gap forces the student to ask a human for permission to continue. No automated verdict, no accusation, no false positives.
Whatever we built had to add almost nothing to the academic's exam-setup workload. Integrity features that cost teachers time don't get switched on.
Two invariants: a student can hold one active exam session at a time, and a session can't sit idle indefinitely.
The trigger was lockdown-browser specific. I specced it lockdown-browser agnostic — a Cadmus Exams-wide capability. An LDB patch would have needed rebuilding the first time the same question came up for a normal-browser exam.
Product leadership's position was that a re-entry key was redundant — students already type an access code to get in. I disagreed, and this is the argument I made.
Nothing new to build. But a cohort access code is distributed to every student by design — so re-entry stays silent and self-service. It re-locks the door with a key the room already has.
Held and typed by the invigilator. The access code opens the first session only. Every session after it needs a person to walk over — that's the entire mechanism.
A memorised code checks that the student knows something. A code typed by an invigilator checks that a person agreed. Only the second lets the invigilator simply refuse — which is what handles the student who has already left the hall.
The two scenarios fail differently, so they needed different catches: a UX prompt, a server-side fact, and a human.
No input for the configured period and the student sees an “Are you still there?” prompt. Purely UX: it catches the honest case and makes the rule visible.
While the student is genuinely working, a heartbeat fires on a fixed interval and extends the session's expiry. Stop working and the extensions stop — the session lapses on the server, where the client can't argue.
Once a session lapses or closes, nothing gets the student back in except the invigilator typing the key. If they've left the hall, it's withheld. The exam is over.
A student who has left the room will always produce a span of inactivity. The timer notices it; the heartbeat proves it. Neither has to identify cheating — only hand the decision to the person already standing there.
Re-entry after closing the browser, and the abandoned-then-resumed-at-home session. Both without accusing anyone of anything.
How tolerant the idle window is. Shorter is stricter; longer gives students breathing room. Deliberately left to the academic, because invigilation intensity varies.
Placement was a scoping decision. The invigilator key sits inside the existing Access Code requirement — it depends on one, so that's where it belongs.
Existing behaviour, unchanged. The cohort code starts the first session only.
One key auto-generated when the toggle is switched on — no blank field to fill in. Backups can be generated and deleted; all keys refreshed at once.
Defaults to 30 minutes, editable. Sits below the invigilator key because it answers the second scenario, not the first.
Diagram of the specified settings hierarchy and its dependency rules — not a screenshot of the shipped UI. Codes shown are illustrative.
Auto-generate, don't ask. A teacher toggling an integrity setting shouldn't then have to invent a code. And put the guidance in the setting — both toggles carry an inline note, written with our content lead.
Auto-generated key with backups · refresh all · inline guidance on both settings · 30-minute editable default · key-entry modal at re-entry · attempt count in the progress view · consistent in and out of the LDB.
Per-student key-entry counts in the Activity Report. Useful for an investigation, not needed to prevent the behaviour — named as a follow-up rather than absorbed into the appetite.
A student reading the key over the invigilator's shoulder. Written in as a known non-goal — keeping the key private is the invigilator's job, and pretending otherwise adds machinery for no gain.
Settings lock once students have started — no mid-exam mutation. The user stories were written twice, once per environment, enumerating every combination of the three settings — because “consistent in both” is a claim you have to actually check.
The honest version of an integrity pitch names what it doesn't stop. Claiming a lock is airtight is how you lose trust the first time it isn't.
One invigilator to fifty students, and every legitimate re-entry — bathroom, accidental close, glitch — queues behind them. The pitch leaves this to the institution. It's the weakest point in it.
A determined student could keep a session alive by faking activity. Doing that while walking out of an exam hall is conspicuous and cognitively demanding — a real barrier, not a perfect lock. Stated as such.
Evasions available in a normal browser aren't in a locked one. Accepted under a stated threat model: the feature is platform-wide, its strength isn't.
The session clock starts at access-code entry — deliberate, so nobody burns a code and parks an immortal session. But during reading time no activity fires, so an idle timeout shorter than reading time kills the session before writing begins. Setup now validates one against the other.
Not a security hole — a configuration a well-meaning teacher could set and only discover was wrong mid-exam. Individually sensible, jointly broken: the class of bug a spec review catches and a demo never does.
enterprise tenants have it live — all five that run lockdown-browser exams, every tenant the re-entry gate can apply to. Now the first thing Support reaches for on an integrity escalation, replacing a bespoke workaround with a documented setting.
If the vulnerability was suppressing confidence in LDB exams, closing it should show up as institutions running more of them.
The outcome that actually matters, and the slower one — integrity cases surface well after the exam they came from.
I named the invigilator-bottleneck risk, then handed it to the institution. A rate of legitimate re-entries per exam was knowable before launch — from the same session logs that surfaced the problem. With it I could have shipped a staffing recommendation instead of a caveat.
The success metrics are both slow and confounded. Neither isolates this feature from everything else moving in the same period.
Two things.
The trigger was one browser; the fix is platform-wide at no extra cost. Scoping to the trigger would have guaranteed a rebuild.
Naming the bypasses and accepting them under a stated threat model makes the rest of the claim credible — and turned “isn't the access code enough?” into something I could argue rather than assert.