DEV Community

Protected nothing

Field notes from a proof-of-concept food-diary tool built alongside one NHS dietetic team, not an official NHS product, no patient data anywhere in it. A privacy guardrail blocked its repository from going public. Traced through the code, it protected nothing that going public would have exposed. A rule sounded exactly right, protected exactly nothing, and stood as the one thing blocking real work, until someone traced it back to what the code actually does. The rule was simple. Before the food diary's repository could go public, it needed a guardrail against identifiable data leaking through the diary's own free-text fields, chiefly a description a client might type next to a reference photo. Someone could type their own name into it without thinking, to help remember whose entry it was. That risk was real, agreed on at the time in the project's own words as "hard to guard... loose enough to say go public," and it sat there as the one condition standing between the repository and a public GitHub Pages migration everything else was ready for. The condition held for a day. Then, traced through the actual code rather than argued about again, it didn't survive the first look. Where the description actually goes The description a client types is captured in the app, stored as a note on a log entry in IndexedDB on the device, and exported into a spreadsheet the dietitian handles. It is never committed, never pushed, never served. The repository's visibility has no effect on it whatsoever, because it was never in the repository to begin with. A guardrail on that field would have protected data that going public put at no risk at all. A second, independent reason cut just as deep. The app ships with no build step at all, just straight unminified JavaScript, so its entire source has been downloaded verbatim by every single visitor to the live site since the day it launched. Repo visibility was never protecting the application code either, because the browser was already handing that code to anyone who asked. The "code stays private" preference behind two earlier hosting rejections had, for the part of the project a visitor could actually reach, never once been true. The place nobody checked If the free-text field was never the risk, going public should have been safe from day one. It wasn't, quite, and the reason was somewhere else entirely: roughly forty tracked files sitting outside the application folder, never served to a visitor and shielded from view by nothing but the repository itself being private, among them migration notes, deploy docs, session logs, and a stray config file. Grepping through all of it for anything infrastructure-shaped turned up exactly one genuinely sensitive string: a hosting-account username, and not even this project's own account. It belonged to someone else's. | In the repo | Repo privacy hides it | | |---|---|---| | Free-text descriptions | no | no | | Application source | yes | no | | ~40 files outside the app folder | yes | yes | Three things the repository question could have been about. Only the last is both tracked in the repository and hidden by nothing else, so it is the only one that going public actually exposes. The thing everyone had been scared of couldn't actually happen. The thing worth being scared of had been sitting in a folder nobody had opened, the whole time the guardrail argument was running. A fix that doesn't depend on remembering The fix that shipped doesn't ask anyone to remember anything. Rather than scrub the sensitive files out of a single shared repository and trust every future session to keep scrubbing, the project split in two: one private repository holding everything, full history intact, and one public repository synced from it that holds only the application directory's own contents. Nothing outside app/ can leak, because nothing outside app/ is ever in the public repo to begin with. Purging the sensitive files from one shared repository's history was considered and turned down on purpose. NOTES.md gets written every session, which means every future session is a fresh chance to type an identifier back into a file that's now public, and a miss like that is silent and unrecoverable the moment the repository is cloned. The split doesn't have that failure mode. There's nothing to miss, because the sensitive files are never in the repo that goes public in the first place. One faster fix was on the table too, and turned down for a completely different kind of reason. GitHub offers private-repo Pages hosting on its paid tier, for around four dollars a month, which would have made the whole question go away without touching a single file. Food diary's own author turned it down outright, on the spot, with two words: "not pro." No technical argument followed it, because none was needed. It was a spending decision, not an engineering one, and the project didn't pretend otherwise. What the guardrail actually protects now The free-text field is still a real concern. It existed before this repository was ever considered for public release, and it will keep existing after, because it's a property of what the app lets someone type, not of who can see the code. It just isn't a hosting decision, and treating it as one is the mistake this piece is actually about. It has its own design question to answer, on its own schedule, and the fix for it won't be a line in a hosting migration plan. The pattern generalises past one repository. The project specified a control against a threat that sounded exactly right and had never been traced to the actual place the data flows through. It still held up real work, however briefly. And the thing worth guarding against the whole time was sitting in plain sight, in a directory nobody had thought to check, because the argument had already used up everyone's attention on the door that was never actually open. Originally published at thekilted.dev/protected-nothing. Top comments (0)

Read on DEV Community ↗ ← Back to News

Comments

No comments yet. Start the discussion.