Gaming anti-cheat
The game a visitor plays for a few seconds is the part you see. Underneath it is the anti-cheat system that makes the game count as proof of a human. Caputchin borrows the playbook competitive multiplayer games use against cheaters: the server is authoritative over every round, the game runs in a locked-down sandbox, and the outcome is re-derived by replaying the player's inputs. The game can be played, not faked.
This is the third verification gate, stacked with proof of work and instrumentation. It is configured per key on the Security page.
The lifecycle
A round moves through three phases: set up on the server before play, run sandboxed in the browser during play, and re-verified on the server after play.
Before the round: server-authoritative setup
Everything that decides what the round is happens on the server, never in the browser. This is the "never trust the client" principle from multiplayer anti-cheat: the client sends intent, the server decides reality.
- A signed, single-use ticket mints the round. It is short-lived and can only be spent once. A captured ticket cannot be replayed into a second pass.
- The game and its random seed are chosen server-side and carried in the ticket. The browser cannot pick an easier game or a friendlier seed, because it never makes that choice.
- A different game from the eligible pool each time. A solver never knows which game it will face, so it cannot pre-train on a single static target. Operators can narrow the rotation, but the server always picks from the allowed set. The pool itself only contains games that passed an index-time conformance check. See build a marketplace game.
During the round: a sandboxed game
The game runs in the visitor's browser, but inside a boundary that protects both the visitor's site and the integrity of the round.
<caputchin-game> mounts each game in an isolated iframe with no same-origin access, so the game has an opaque origin and cannot reach the host page's cookies, storage, DOM, or same-origin network. Its inline content-security-policy pins the script to exactly the game's bundle and blocks outbound network calls, and the bundle is checked against a known hash before it runs (a mismatch fails closed). The host page's own security policy is untouched. The precise sandbox and policy shape is documented in how Caputchin sandboxes games.
The takeaway: the game is untrusted-by-default and contained. It cannot exfiltrate anything, and it cannot tamper with the page it is embedded in.
After the round: deterministic replay
When the visitor finishes, the browser submits the recorded input trace. The server does not take the browser's word for the result. It re-runs the trace.
- The round is re-simulated on the server under the same server-derived seed, in a sealed isolate with no network access and a hard time budget. This is the same property deterministic lockstep relies on in strategy games: identical seed plus identical inputs reproduce identical play. A trace that did not really clear the game does not reproduce a passing outcome.
- Pass or fail is taken from that replay, never from a number the browser reported. A client cannot claim a score it did not earn.
- A signed token is issued only if the replay confirms the play. That token is itself single-use when your backend later confirms it at verification time.
What Caputchin does not do
Most game and interactive CAPTCHAs lean on behavioral signals: mouse-path entropy, tap timing, device telemetry fed to a classifier that guesses bot-versus-human. Caputchin deliberately does not. It collects no behavioral profile of the player. Instead of guessing how the inputs were produced, it re-derives whether they actually clear the game from first principles. This is both a privacy stance and a security one: there is no behavioral model to fool, only physics to reproduce.
An honest limit
The gate is only as strong as the game. The anti-cheat machinery proves a round was genuinely played and not faked, but it cannot make an easy game hard. A trivial game (a static board, the winning move readable in the DOM, "click the red dot to pass") is cheap for a script to solve, and the deterministic replay will faithfully confirm those scripted inputs win, because they do. Resistance to bots comes from the game itself being hard to solve programmatically: fast, sensory, split-second reactions, with no solution sitting in the DOM. The anti-cheat layer guarantees the play was real; the game's design decides whether real play was hard to automate. Choose and build games with that in mind, see build a marketplace game.
Pass or fail is decided by each game's own logic; the server faithfully re-runs that logic but does not second-guess what a given game considers a win. Gaming anti-cheat is strongest composed with proof of work, instrumentation, and the rest of a key's security settings.