# Replica: a white-label AI chatbot platform for agencies

> Replica's build reached a point where making a final gate green would have restored a security flaw already proven closed. The correct artifact was a documented red result, not compliance.

Source: https://saascode.ai/inside/road-to-replica · Published: 2026-09-01 · Section: builds · Product: Replica (https://saascode.ai/products/replica)

---
Replica's build reached a point where making a final gate green would have restored a security flaw already proven closed. The correct artifact was a documented red result, not compliance.

Replica is a white-label AI chatbot platform with self-contained retrieval-augmented generation, built for an agency to operate branded chatbots for its clients. The product separates platform administration, agency work, client access, and the anonymous visitor widget. This build story follows how those boundaries were designed, measured, broken, and repaired.

## Starting point

White-label software becomes difficult at the boundary between branding and authority. Changing a logo is straightforward. Deciding which person may see which client, which knowledge base may answer which visitor, and which system identity may cross those lines is the actual product.

Replica began with a multi-organization model and five roles. Platform administrators retain the cross-organization view. An agency owner and the agency's operators work inside the agency workspace. An end client gets a narrower portal. Anonymous visitors reach only the published chatbot widget. The unusual detail is that an agency's staff and its end clients share an organization identifier. Organization scoping alone therefore cannot distinguish the people operating the service from the customers they serve.

That fact shaped the whole build. The client portal could not be a cosmetically restricted copy of the agency dashboard. It needed role-aware guards at the application layer and narrower policies at the database layer. The widget needed another boundary again: it runs without a signed-in user, but still has to retrieve the right bot configuration, keep one visitor from replaying another visitor's token, and avoid disclosing the tenant behind the experience.

The scope stayed deliberately narrower than the category could have become. Voice and call handling, native mobile applications, automatic certificate provisioning for custom domains, usage-based billing automation, and external chatbot-provider integrations were left outside the build. The system focused on the web product an agency can operate: branded bots, knowledge ingestion, conversations, handoff, analytics, and a client-facing view of the work.

## Reading the market

The build record does not support a story about feature-count competition, so this one does not make that argument. Its useful category distinction is operational. A chatbot demo can stop at a prompt box and a plausible answer. An agency platform has to survive the parts around that answer: client separation, document ingestion, anonymous delivery, human escalation, usage accounting, and a way to see where the knowledge base is failing.

Replica treats those concerns as one system rather than a collection of integrations. Retrieval is part of the product's own data path. The public widget is a separately built artifact, not the authenticated application exposed with fewer buttons. Deflection is defined behaviorally — a conversation ends without handoff or a later support event — rather than inferred from retrieval similarity. Similarity says whether a passage was close to a query; it does not say whether the visitor's problem was resolved.

This framing also explains the role model. The agency is not merely another tenant using a chat tool. It operates the service for multiple clients, while each client needs a view that does not reveal the agency's other work. The product's central market bet is therefore inseparable from its central engineering risk: a lower-trust population lives inside the same organizational boundary as the operators.

## The decisions that shaped it

**Role became a business boundary, not a label.** The end-client role received its own portal guard and permission checks. Agency-only actions — bot administration, knowledge writes, staff access, plan configuration — stay on the operator side. Cross-organization pages remain reserved for the platform administrator. This made authorization more verbose, but it prevented the interface hierarchy from pretending that one organization identifier expressed every boundary the business required.

**The widget became its own program.** Replica builds the loader as a small browser script that opens a cross-origin iframe. Its public requests are authorized by the bot's public key, an allowed-domain check, and a visitor identity, with rate limiting keyed to both the network source and bot. That design keeps the anonymous surface outside the signed-in application while still giving it a narrow path to configuration, messages, and handoff status.

**Retrieval kept its provenance.** Knowledge documents are parsed and ingested asynchronously, split into overlapping chunks, embedded, and indexed for vector search. The embedding model identifier is stamped at ingestion so a later model change cannot silently mix incompatible vectors. The search function runs with elevated database privileges only behind an explicit organization predicate; filtering by bot identifier alone was rejected because possession of an identifier is not tenancy.

**Outcome measurement stayed separate from retrieval quality.** The system records message usage and conversation outcomes, then derives deflection from what happened after the answer. Gap analysis works over stored message embeddings and labels the resulting topics, but the similarity score never becomes a proxy for resolution. This distinction matters because a confident retrieval can still end in handoff, while a modest match can still answer the visitor's question.

**The visual system chose restraint over decorative depth.** The approved direction uses a light, flat stack of surfaces, almost-square containers, pill-shaped actions, and no shadows or gradients. Dense operational screens — conversations, knowledge, analytics, and client reporting — get hierarchy from spacing, typography, and surface contrast. The choice fit a product meant to disappear behind an agency's brand without becoming visually anonymous itself.

## What fought back

The first class of trouble was silent success. During the translation merge, a line comment contained the text `kb/*`. The merge script treated the slash-star inside that line comment as the start of a block comment and classified everything after it as commented out. It exited successfully while dropping 358 translation tuples — the entire client-portal namespace. A syntax check passed because the output remained valid SQL, and the database reconciliation passed because both the seed and the database were missing the same rows. Only an independent code-to-seed check supplied the denominator the parser could not supply for itself.

The role boundary then failed in two different layers. Application routes for the client portal correctly rejected sibling-client access, but direct database reads still exposed data protected only by organization scope. A separate user route had an authentication check and therefore passed the guard-presence test, even though an authenticated end client could read the agency's staff roster. The fix was not “add authentication”; authentication was already there. The route needed a role-discriminating operator guard, and the database policies needed the same distinction.

Security remediation produced the build's sharpest reversal. One finding involved an outbound signing secret stored in plaintext. The first repair encrypted the value at one writer and taught the consumers to decrypt it. A second writer still produced plaintext. Its first row would throw during decryption outside the per-item error boundary, abort every later delivery in the batch, and leave the delivery log empty. The security repair had closed the disclosure and introduced an outage. The corrected version aligned both writers with the consumer and contained a malformed row to its own delivery.

Another repair was valid SQL and ineffective security. A column-level revoke attempted to remove access inherited from a table-level grant. The database accepted the migration, advanced the ledger, and changed no privilege. Live privilege queries — not the migration exit code — caught the no-op. The working sequence removed the table grant and then granted back only the public columns, after which the attack battery was repeated against the deployed database.

That left the conflict from the opening. A later ownership gate saw the modified administrative webhook files and prescribed restoring the official versions. Those official versions were the ones that stored the secret in plaintext. Following the gate would have reopened the closed finding; moving the repair to a renamed route would have left the vulnerable route live. The build kept the repaired files, retained the red gate with its evidence, and recorded that the template needed to catch up with the product.

The recorded phase measurements reflect how much of the work lived in verification and re-verification. Across those phases, elapsed time sums to exactly 1,497 minutes 25 seconds. Phases that exposed usage recorded 3,293,059 tokens and 1,274 tool uses. The elapsed figure includes long idle windows and a stop-and-resume, while the token total is partial by design; neither is presented as hands-on labor.

## What shipped

Replica now joins the four surfaces the build set out to separate: a public product and widget experience, an agency workspace, a narrower client portal, and cross-organization administration. Its knowledge path ingests documents and searches them within the bot and organization boundary. Its conversation path supports anonymous chat, human handoff, outcome measurement, and gap reporting. Its interface carries the approved flat, light design across those roles rather than treating the client portal as an afterthought.

The final security verdict recorded zero unwaived critical findings after two blocking findings were fixed and independently re-verified. That sentence is a gate result, not a claim of exhaustive assurance. The same record keeps an authenticated-client metadata boundary open, states that the automated check for this product shape remained inactive, and lists database policy classes that were not covered table by table.

The visual result carries the same discipline. The measured pass fixed unreadable public surfaces caused by a stylesheet-layer collision, but it left a team-invite overlay in the wrong shape and identified an incomplete password-reset path. One data-dependent conversation route could not be rendered because the demo contained no conversation, so no visual verdict was claimed. Responsive and mobile layouts were not measured in that pass. Those limits are part of what shipped because a build log that turns “not measured” into “passed” would repeat the exact mistake this build spent its hardest hours removing.

## See it

[See Replica →](https://replica.saascode.ai)

## Related reading

- [Replica vs Stammer AI: deploy the platform or rent the operating layer?](https://saascode.ai/inside/replica-vs-stammer-ai-deploy-or-rent.md)
- [White-label AI chatbot platforms for agencies in 2026: choose by who runs the control plane](https://saascode.ai/inside/white-label-ai-chatbot-platforms-for-agencies-2026.md)
