Build1 distinct publisher3 min readUpdated
A children's story app encrypted what parents write about their kids before opening the doors. The classification call came first, and the hardening pass that followed broke performance.
The Engineer · Build desk

Compiled by The EngineerSomething wrong?How this is made
The number that decides whether this is affordable is a count of field categories, not a key length. Four go through the cipher: the child's profile including name, traits, worries and what excites them; the contents of private stories; the free-text context an adult writes when ordering a custom story; and the notes a family keeps on what the product calls personalized moments [7]. One stays in the clear, the public catalogue, on the stated grounds that it uses fictional characters and holds nobody's real data [8]. Four in, one out [1].
The master key stays inside Google Cloud KMS and never leaves it [5]. Each user gets a data key that the master wraps, stored encrypted alongside that user's records in Firestore; the client fetches it once per session and then encrypts and decrypts field by field in memory, so Firestore sees ciphertext [5][6]. Unwrap traffic therefore scales with sessions rather than with rows or fields read [2], which is the part that makes per-user keys survivable for a small team. The bill lands elsewhere. For those four categories the database holds ciphertext only [6], so any filter, sort or index you wanted over that data has to live in whatever you left readable. That is why the product argument came before the cryptography, in what the author describes as a grilling session on the design [10].
The rule they settled on is that the channel decides, not the content: public means plaintext, private means encrypted, and a remix of a public story is born encrypted because it arrives through the private path [9]. A flat list of sensitive fields does not settle that case; a rule about where data enters does.
The account is staged in three phases: the encryption core, an adversarial audit that forced several hardening changes, and then a performance incident [15] that the standfirst attributes to that same hardening [16]. The material supplied here stops before the postmortem, so the mechanism is not available to check. The sequence is: build, get audited, harden, break. All of it ran in very early beta with the author's own account as the only real user in the database [12], on the reasoning that doing the same work later, with families' data already in production, would have been considerably more expensive and riskier [13].
Priced that way, the outage cost one account. The stack choice supports the same instinct: Firestore for data, Cloud Functions for server logic, Cloud KMS for the master key, and no home-grown key management [11]. The article also declines to publish resource names, repository paths or the exact details that would help someone attack the data [14], which is defensible and also the reason nobody outside can audit the hardest parts. What travels is the ordering, and the ordering is cheap only while the user count is one.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
Cuentopia generates personalized AI stories for children; to personalize, a parent describes the child's character, what frightens them, and what is happening at home.
The author writes that, seen all at once, what was in the database was the emotional diary of a lot of minors.
The solution is field-level encryption at rest using envelope encryption: a master key lives in Google Cloud KMS and never leaves it, and each user has their own data key, wrapped by the master key and stored encrypted alongside their data in Firestore.
The client requests its key once per session, uses it in memory to encrypt and decrypt field by field, and Firestore only ever sees ciphertext.
Encrypted: the child's profile (name, traits, what worries them, what excites them), the content of private stories, the free-text context the adult writes when requesting a custom story, and the notes for the personalized moments a family documents.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Single self-reported build log, details withheld
All claims come from one first-person post by the product's own builder. The architecture description is internally coherent and specific enough to evaluate as a pattern, which lifts it above pure assertion, but the author explicitly withholds resource names, paths and exact formats, no code or configuration is shown, the cited external audit is unnamed and its findings absent from the supplied text, and there are no measurements of any kind. Nothing is independently corroborated.
Pre-launch beta, one real account
Adoption is close to zero by the author's own disclosure: very early beta with his own account as the only real user and no family data in the database. The only other verifiable adoption fact is the team's use of existing managed services (Firebase, Firestore, Cloud Functions, Google Cloud KMS), which reflects vendor dependence rather than uptake of anything described here. No third party is reported using this pattern.
Mildly overstated: strong security narrative, negligible operating history
The piece is unusually candid for a vendor-authored security post — it names its threat model, flags what it will not disclose, and admits hardening carried a hidden bill — which keeps the gap small. It still tilts positive: a comprehensive privacy posture is presented as settled while the system has never operated with real family data, the audit that validates it is unnamed and unquoted, the compliance framing is self-assessed, and the retrofit-cost counterfactual is asserted without numbers. The framing serves a product trust page it links to.
Founder marketing own product's trust story
The author is building and promoting Cuentopia and writes in the first person plural about 'our' data, pointing readers to a family-facing trust page on the product domain. The article's persuasive function is to establish that a paid children's app handles minors' sensitive data responsibly, ahead of opening to users. Mitigating factors: it credits third-party managed services rather than claiming proprietary crypto, and it explicitly says honest security includes admitting where the team chose not to go.
Confident about the design as described, not about outcomes
Confidence is moderate-low. What the author designed and why is clearly stated and self-consistent, so the pattern-level claims can be reported with reasonable assurance. Everything about effectiveness, compliance and operational cost rests on one interested source with no measurements, an unnamed audit, and a body of text that stops before the audit and performance-incident sections, leaving the cluster's most operationally interesting claims unexamined.
build
Angular's compiler already knows the line number. Nothing ships it to the browser1 distinct publisher
build
Portable Or Native: The Endpoint Choice Is A Runbook Decision, Not An SDK Preference1 distinct publisher
build
"The model does not retain training data" is a testable claim, and someone else runs the test1 distinct publisher
build
App Review rejections are design decisions you made six weeks earlier1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 23, 2026