They solved all doubts immediately and without delay.
Built In 24 Days So That The Whole Country Can Check Their Records
Montenegro's 2023 census results could not be published until every person counted had a way to inspect the four identity answers recorded about them, so Parliament legislated the service and we built it without ever needing to know who anyone was.

Project snapshot
- Location
- Montenegro
- Industry
- Services provided
- Development period
- 23 Jul – 16 Aug 2024
- Public window
- 1 – 7 Oct 2024
Project
MONSTAT is Montenegro's Statistical Office, the body responsible for producing official statistics for the country and for reporting them internationally.
In 2024 it had to publish something it had never published before: a service that let members of the public read back part of their own census record. Not a report, not aggregate tables, an individual lookup, open to anyone, running for a fixed window. We designed and built it, and it was live to the public from 1 to 7 October 2024.
The challenge
In November 2023 the Parliament of Montenegro amended the census law. It did so because the census had become contested: there were public allegations that enumerators had not recorded people's answers objectively, and the four questions in dispute were the ones that decide how a country describes itself. National or ethnic identity. Religion. Mother tongue. The language a person normally speaks.
Parliament's answer was to legislate the software into existence. Article 26a required the state to establish a system so that every person covered by the census could inspect those four answers as recorded. Article 26b limited each person to their own record and nothing beyond it. The same law required the government to form a commission to oversee the build, and to procure an independent code audit from an IT company based in an EU member state. MONSTAT put the work out to open public procurement, and we won it.
That produced an unusual engineering constraint. The system had to satisfy people who had already decided not to take the state's word for it, which meant it could not ask to be trusted. It had to be checkable instead: checkable by citizens, who needed to see their own answers and be certain nobody could see theirs, and checkable by outsiders, who would read the source code line by line and try to break the running system. Meanwhile the data it served was among the most sensitive a state holds, and the deadline was set by law rather than by us.

Design and UX
One screen, two steps, large fields.
The audience for this interface was everybody. Not a segment, not a persona, everybody who had been counted, including people who had never used a government service online and would arrive once, on a phone, holding a paper questionnaire.
So the interface does one thing. A single screen, two steps, large fields, and nothing else competing for attention: no navigation, no account, no marketing, no cookie theatre. The paper questionnaire stayed in the user's hand, so the form asks for the codes in the order they appear on it, with the label wording taken from the questionnaire itself rather than from the database schema. Errors say which code was wrong and what to do next, and the support phone numbers and email sit on every state the application can reach, including the blocked ones. An accessibility widget runs on every page.
Two codes, no identity
Show me my record. Prove you cannot show me anyone else's.
The lookup takes two things. First a statistical ID, a nine-character code printed on a sticker on the person's own copy of the questionnaire. Then one of four further codes from the same sheet: municipality, enumeration area, dwelling or person. Both must match the same record before anything is returned, and the record returns exactly four fields, the four the law named.
What the system never asks for is who you are. There is no login, no account, no email, no name, no national identification number, no date of birth. The database it queries holds nothing that identifies a person, only randomly assigned codes and the four answers. That is what makes the design defensible: even a full compromise of the running system yields a set of answers attached to codes, and the sheet that connects a code to a human being was never in it.
- Statistical ID
- Municipality code
- Enumeration area code
- Dwelling code
- Person code
- No login
- No name
- No national ID

The system could show you your own record. It could never show you anyone else's.
Twelve languages, two scripts
A service about identity should not be available in one identity's language.
The questions being verified were about ethnicity, religion and mother tongue. A verification tool for those questions, offered only in the majority language, would have undercut its own purpose for exactly the communities most likely to want to use it. The application shipped in twelve fully translated locales: Montenegrin in Latin and Cyrillic, Serbian in Latin and Cyrillic, Bosnian, Croatian, Albanian, Turkish, Romanian, Russian, Ukrainian and English. Every string, not a partial translation with fallbacks, including error messages, blocked-state pages and the support notice.










Rate limiting as a privacy control
Three looks at a record. Then that record closes for the day.
Throttling here is not about server load, it is about what an attacker with a stolen list of codes could accomplish. Each statistical ID can be checked three times in twenty-four hours, and after that the record itself is closed regardless of who is asking or from where. A single address gets five attempts a minute at validating an ID before it is held off, and twenty requests a minute overall before it is served a block page with a countdown instead. reCAPTCHA sits in front of the form, and Cloudflare sits in front of the application.
Each of those limits was written into the tender, and each one costs a legitimate user something. Three checks a day is enough for a person confirming their own record and not enough to walk a list. That trade was the point.
- 3 checks per record per day
- 5 ID attempts per minute per address
- 20 requests per minute per address
- reCAPTCHA
- Cloudflare

Verify, do not trust. That was the requirement, and it went all the way down to the footer.


An audit trail that records access, never answers
Every lookup is logged. What the lookup returned is not.
MONSTAT needed to be able to show exactly how the service had been used, both to run it and to answer questions afterwards. So every event is logged in structured form to Seq: which code was queried, from which address, at what time in local Podgorica time, and what the outcome was, categorised as success, failure, blocked, blocked attempt or error. Administrators could watch the whole thing live and query it after the fact.
What the logs do not contain is any person's answers. The four fields the service exists to display are written to the screen and nowhere else, never into a log line, never into an event property. The audit trail can prove that a record was accessed. It cannot reveal what that record said. Building it the other way round would have been easier and would have quietly turned a transparency tool into a surveillance one.
- UsersAcross the country
- HTTPS onlyEncrypted connection
- WAFWeb application firewall
- ApplicationSecure by design and by default
- DatabaseRead-only account
Hardened for a window that could not slip
One week live, on a date fixed by law, with the whole country able to arrive at once.
The application ran on infrastructure inside a government environment, published only over HTTPS behind a web application firewall with every other port closed. On the application itself: a content security policy with a per-request nonce, frame denial, content type enforcement, cookies marked secure without exception, anti-forgery tokens on every state-changing request, input sanitisation and validation duplicated on the client and the server, and a database account restricted to read-only. On the host: full disk encryption and two-factor authentication on every account.
None of it is exotic. All of it is the list you write down when you know a stranger will check, and when the consequence of getting it wrong is a headline about census data rather than a support ticket.
Shipped for a date set by law
Twenty-four days from contract to delivery.
The tender did not treat the schedule as a detail to agree later. It set a build window of twenty to thirty days from signature, made the number a scored award criterion worth ten points, and gave the most points to whoever committed to the shortest. We signed on 23 July 2024 with a delivery date of 16 August 2024. Twenty-four days to design, build and hand over a national government system holding the most sensitive answers in the census.
What followed was not a victory lap. The independent audit ran at the end of August, findings came back, and they were fixed and revalidated in early September. The service opened to the public on 1 October 2024 and closed on 7 October exactly as planned. A week later MONSTAT published the final results of the 2023 census, which it could not legally do until this step was complete.


Source code and running system reviewed by Secnora, the independent auditor the census law required.
Built to be audited
We did not ask anyone to trust the code. Someone else read all of it.
The law required an independent code audit by a firm from an EU member state, and MONSTAT procured one separately from the build. It went to Secnora, a security team based in Estonia, who read the source, tested the running system and reported to MONSTAT rather than to us. That changed how the software was written. Every control had to be legible to someone who had never met us and had no reason to be generous: no clever indirection, no undocumented behaviour, no security resting on being hard to find.
The audit ran over a week at the end of August 2024 against OWASP secure coding guidelines, combining manual review with tooling. It found four issues, two medium and two low, nothing critical or high. We fixed them, Secnora revalidated the fixes before the service opened, and the system was graded A, the auditor's highest mark, for security that exceeds industry best practice. Separately, the application prints the running build's commit hash in its own footer, so anyone could confirm that the code serving the public was the code that had been delivered and reviewed. That requirement came from the tender, and it is the small feature that carries the whole idea: verify, do not trust.
Grade A. Security grade, exceeding industry best practice
Their developers engaged constructively with our findings and moved quickly on remediation rather than treating the review as a box-ticking exercise, something that is not a given on projects of this sensitivity. … We would be pleased to work with Codepixel again.
Legislated in November, live by October
- Checked their record on the first day
- 20,684
- People counted in the census, any of whom could check
- 623,633
- Days from contract signature to delivery
- 24
- Languages the service shipped in
- 12
- Independent EU code audit result
- Grade A
- Critical or high severity findings
- 0
Links
- Websitemonstat.org
- LinkedInMONSTAT
- Instagrammonstat_me
The client says...
Ready to build a public service that has to be checkable?
Whether you're working to a deadline set by law, holding records a whole country cares about or preparing for an independent audit, we'll help you choose the smallest sensible starting point and a delivery model that fits your team.
Build faster with AI
Our playbook for integrating AI into product design and development workflows.
Download the playbook
