Dev.to Security 🔐 Cybersecurity 👁 0 📖 3 min read

We Checked In 5,000 People With No Network: Offline Entry With Signed QR Codes

I was the tech lead for Bitotsav '26, our college festival, and the platform had to check in around 5,000 participants. The hard constraint was not the headcount. It was the entry gate: the moment everyone arrives at onc

I was the tech lead for Bitotsav '26, our college festival, and the platform had to check in around 5,000 participants. The hard constraint was not the headcount. It was the entry gate: the moment everyone arrives at once is exactly the moment mobile data gives out. A check-in system that needs a server call per scan is a system that fails at the worst possible time.

So we designed entry to work with the server switched off.

The design: passes that prove themselves

A normal ticket is a lookup key: the scanner reads an ID, asks the server "is this valid?", and waits. A signed pass is a proof: the payload travels with its own signature, and the scanner verifies it on-device with a public key it already has.

Each pass is a small payload plus a signature:

{
  "attendee": "BT26-1042",
  "event": "bitotsav-26",
  "tier": "participant",
  "exp": "2026-03-15T23:59:59Z",
  "sig": "base64(ed25519_sign(payload))"
}

Issued once, at registration time, by the server holding the private key. Encoded into a QR code. At the gate, the volunteer's scanner app verifies the signature against the public key baked into the app. No network call, no waiting, no queue backing up because a tower is congested.

The crypto choice matters for fit: Ed25519 signatures are 64 bytes and verify fast, and compact encodings like CBOR keep the whole token small enough for a dense but still scannable QR code. Researchers have shown the same shape works generally — signature inside the code, verification against the issuer's public key, fully offline.

The problems a signature does not solve

A signature proves the pass is genuine. It does not prove it has not already been used. A screenshot of a valid pass is still a valid pass. That is the real design problem, and it has three parts:

Double entry. Each scanner keeps a local journal of scanned pass IDs. A second scan of the same pass on the same device is refused immediately. Across devices, the journals sync whenever connectivity returns, and duplicate scans are flagged for the ops desk. Perfect real-time dedup needs a network; graceful degradation needs a journal.

Revocation. A purely offline system cannot revoke a key or a pass in real time — a compromised key stays valid until the passes expire. The mitigations are short expiry windows on passes and a revocation list the scanners pull whenever they are online. Gates carry the last list they fetched.

Key rotation. Signing keys rotate, and scanners need every live and recently retired public key, not just the current one. A pass signed yesterday must still verify today.

What the online parts still do

Offline-first does not mean offline-only. Registration, team creation, the points system and the admin panel all ran on the server, with Redis in front of PostgreSQL for the hot paths — registration bursts and leaderboard reads. The entry flow was the one part designed to survive without the server, because it was the one part where failure meant a physical crowd standing in the sun.

That is the general lesson, and it is the one I keep reusing: design for the failure cases first. No network, wrong data, a plan that changes the night before. If the system handles those, the happy path takes care of itself. At a festival, the failure case is not an edge case — it is the peak moment, and it is the moment your users will remember.

If you are building any gate, checkpoint, or field workflow: ask what happens when the network is gone at the busiest minute. If the answer is "we wait", redesign until the answer is "we keep going".

📰 Read the original article on Dev.to Security

Originally published by Dev.to Security. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.