The Challenge
Chainscript Labs needed a ticketing system for their events that went beyond the limitations of off-the-shelf platforms: full control over attendee data, the ability to integrate with their existing identity infrastructure, and a check-in experience that would hold up under the concentrated load of hundreds of attendees arriving simultaneously at an event entrance.
The security requirements were non-negotiable. Attendee PII could not leave the controlled environment unencrypted. Tickets had to be cryptographically tamper-evident — a screenshot of a QR code should not be redeemable. And the check-in system had to detect and reject duplicate redemption attempts in real time, even under concurrent scanner load.
The Solution
The system is a FastAPI backend with three distinct surfaces: a registration API for attendee self-service, an admin dashboard for event management and live check-in monitoring, and a check-in API consumed by camera-equipped scanning clients. Attendee data is encrypted at rest using Fernet symmetric encryption. Tickets are generated as cryptographically signed QR codes — the QR payload includes a ticket ID and a HMAC signature over the ticket metadata, so any tampered QR fails signature validation before redemption is attempted.
The check-in flow uses PostgreSQL row-level locking to prevent duplicate redemption under concurrent scanner load. A ticket's status transitions from ISSUED to REDEEMED inside a serialisable transaction — a second concurrent redemption attempt for the same ticket ID reads the already-committed status and returns a rejection immediately.
How It Works
Attendees register via a web form or API. The backend validates the registration, stores the attendee record with PII fields encrypted using Fernet (symmetric encryption with the key held in the server environment, not the database), and issues a unique ticket ID.
A QR code is generated for each ticket. The QR payload is a JWT-signed JSON object containing the ticket ID, event ID, and attendee reference. The JWT signature uses a server-side secret, making the QR cryptographically tamper-evident — any modification to the payload invalidates the signature.
Tickets are delivered to attendees as PDF downloads containing the QR code and event details. The PDF is generated server-side and served directly — no third-party delivery service handles the ticket data.
Check-in operators use camera-equipped devices running a lightweight web client. The client decodes the QR code and POSTs the payload to the check-in API. The API validates the JWT signature, then attempts to atomically transition the ticket status inside a serialisable transaction — preventing duplicate redemption under concurrent scanner load.
The admin dashboard receives check-in events via server-sent events (SSE). Organisers see attendance count, check-in rate, and per-ticket status in real time — with immediate visibility into any redemption rejection events (duplicate scan attempts, invalid signatures).
The full stack runs on-premises at the event venue over a local network, with HTTPS enforced using mkcert-generated locally-trusted certificates. No attendee data transits the public internet during check-in — the system operates completely offline if required.
Technical Highlights
Concurrent Redemption Safety
The check-in API uses PostgreSQL's SELECT ... FOR UPDATE SKIP LOCKED combined with a serialisable transaction to atomically read and update ticket status. This guarantees that even if three operators scan the same ticket simultaneously, exactly one redemption succeeds — the others receive an immediate, unambiguous rejection response.
Fernet Encryption at Rest
Attendee PII (name, contact details) is encrypted at the application layer using Fernet before being written to the database. The encryption key is held in the server environment, not the database — a database dump does not expose readable attendee data. Decryption happens only in the FastAPI process when the data is needed for a legitimate operation.
JWT-Signed QR Payload
The QR code payload is a compact JWT signed with a server-side HMAC secret. This means ticket data is self-contained and verifiable without a database lookup during scanning — the signature check is performed first, so invalid or tampered QRs are rejected at the edge before touching the database.
Offline-First Architecture
The system is designed to operate over a local network without internet connectivity. mkcert generates certificates that are trusted by devices on the local network without requiring a CA. This allows deployment in venues with unreliable or restricted internet access — common in event spaces.
The Stack
Outcomes
- Zero duplicate redemptions recorded across live event deployments — concurrent scanner safety held under real-world peak check-in load.
- Attendee PII remained fully encrypted at rest throughout the event lifecycle — database access without the application key exposes no readable attendee data.
- The offline-first architecture enabled reliable check-in operations in venues with no stable internet connection — a common failure point for cloud-dependent ticketing systems.
- The real-time admin dashboard gave event organisers live attendance visibility, allowing staffing decisions to be made dynamically as entry patterns emerged.