Yago Marinho
Back to the articles
  • AI
  • LLM
  • LGPD
  • Privacy
  • Architecture

AI on WhatsApp and privacy law: serving customers without leaking sensitive data

How I put an AI agent to answer MSI Informática's customers on WhatsApp without handing any sensitive data to third parties, using an open-weight model, envelope encryption and Brazil's data protection law (LGPD) as an architecture requirement.

Photo of Yago MarinhoBy: Yago MarinhoLast updated on:
💡
This article covers a project I build for MSI Informática, a Brazilian IT company. I talk about the problem, the decisions and the stack; the internal details of the implementation, the infrastructure and the model stay out, out of respect for the client.
When a customer messages a company on WhatsApp, they are not sending "data". They are sending their name, their phone number, their delivery address, the problem they have at home, sometimes an invoice, sometimes a photo of an ID. They do it because they trust that the conversation stays between them and the company.
Putting an AI to answer those messages has become easy. The hard part, and the one almost no tutorial discusses, is what happens to that trust when the conversation leaves the company to be read by a third party's language model.
At MSI Informática, the answer had to be simple: no customer's sensitive data leaks, in any way. This article is about how that became architecture.

Table of contents

The real problem: the customer's conversation is not yours to hand over

The most common way to put AI into customer service is to send the conversation history to an LLM provider's API and return the answer to the customer. It works, and it is fast. But from the point of view of the person who trusted the company with their data, this is what happens:
  • the whole conversation, with everything the customer said, now exists on another company's servers;
  • it may be kept in logs, request histories and monitoring systems, for a period you don't control;
  • and, depending on the contract, it may be used to train someone else's model.
The customer was asked about none of this. They wrote to solve a problem with MSI, not to feed an AI provider.
This is not just common sense. It is a legal matter.

What Brazil's data protection law says about it

💡
I am not a lawyer. What follows is the engineering reading that guided the decisions; the legal assessment of each case belongs to the company's legal team.
Brazil's General Data Protection Law (LGPD, Law 13,709/2018), close in spirit to Europe's GDPR, makes the company that serves the customer the controller of their data. Sending the conversation to an AI provider means sharing that data with a third party that processes it on the company's behalf. Several points of the law weigh directly on this:
  • Purpose and necessity (art. 6). The data was given for customer service. Using it for anything else, such as training a vendor's model, or exposing more than necessary, breaks the law's principles.
  • Transparency (art. 9). The data subject has the right to know who their data is shared with and why. An AI that sends the conversation to a third party without that being clear in the privacy policy is hidden sharing.
  • Security by design (art. 46). The company must adopt technical and administrative measures to protect data from unauthorized access, and the law asks for them from the design of the product onward, not after the incident.
  • International transfer (art. 33). Processing personal data outside Brazil is only allowed in specific cases, with safeguards, and most AI infrastructure is outside the country.
  • Liability (arts. 42 and 44). Processing that doesn't provide the expected security is irregular, and whoever processes the data is liable for the damage it causes.
  • Incidents and penalties (arts. 48 and 52). A relevant breach must be reported to the national data protection authority (ANPD) and to the data subjects, and fines reach 2% of revenue, capped at R$ 50 million per violation, not counting the damage to reputation.
In other words: sending the customer's conversation to a third party, without technical safeguards, without a proper contract and without transparency, is irregular processing of personal data. It is not an improvement to leave for later. It is a requirement that shapes the architecture.

The question that changes the design

The natural question would be "which AI provider do I trust?". It leads to comparing retention policies, reading terms of service and hoping nothing changes next quarter. The customer's privacy rests on a promise.
The question I started asking was a different one: "how do I build this so that no third party needs to be trusted?"
It changes the criterion. Instead of "who promises to keep less", what matters is "who can see less". And, taken seriously, it decided three things: where the model runs, how the text travels and what can show up in a log.

What was left behind

Two alternatives looked reasonable and were discarded:
  • A commercial LLM API. The best answer quality for the least effort. But the conversation arrives in plain text at a service we don't control, and the only protection is the contract. It was the first version of the design, and it was replaced before going to production.
  • Masking personal data before sending it. It looks elegant: replace name, phone and address with placeholders and send the rest. In practice, no algorithm reliably recognizes every piece of personal data in free text. A "I live across from Mr. John's bakery" slips past any filter. A protection that fails silently is worse than none, because it gives the feeling that the problem is solved.

The three decisions

1. An open model, running in an environment we operate

Instead of calling someone's API, the agent uses an open-weight model, with a license that allows commercial use, running in an isolated GPU environment that we operate.
No third-party AI API receives the conversation. The code that generates the answer is ours. And no customer data trains anyone's model.

2. Envelope encryption, with the key always on our side

Running the model elsewhere is not enough: the GPU infrastructure still has queues, temporary storage, logs and a network. If the text went through it in plain text, I would only have swapped one third party for another.
That is why every AI request and every answer travels encrypted with envelope encryption:
  • each answer uses its own data key, which opens no other;
  • that key is protected by a master key that lives in our account and never leaves it;
  • the process that generates the answer decrypts the request only in memory, during generation, and returns the answer already encrypted.
The result is a verifiable sentence: outside our environment, the conversation only exists in plain text in the process memory, during the seconds of generation. Anywhere else, it is a block of bytes that only our key opens.

3. Nothing from the conversation in a log, and that is tested

Encryption is useless if the text shows up in plain text in an error message.
  • Logs record only identifiers, timings and error codes. Never the text, never the exception message, which tends to carry pieces of the input.
  • There is a test that checks it: no log line may contain the input or output text. A privacy rule that is not in a test is an intention, not a guarantee.

Legal came before the code

The architecture solves the technical part, but the LGPD also asks for transparency and contracts. So, before the agent answered its first customer:
  • MSI's privacy policy started stating that answers may be generated by AI, who processes the text, why, where, and how it is protected;
  • the GPU infrastructure vendor was added to the policy as a sub-processor, and a data processing agreement and a security audit report are required from them.

What this does not protect (and why say it)

It would be easy to write "end-to-end encryption" and stop there. It would not be true, and respecting the customer includes not overstating what is promised to them.
  • WhatsApp is in the path by definition. The encryption described here protects the stretch between our environment and the AI.
  • The system's database stores the conversations, because customer service needs them. It sits on the inside, protected by access control.
  • Whoever administers the GPU machine, during generation, could in theory read its memory. No encryption solves that without confidential computing hardware. That is why the vendor's contract and audit are required, not optional.
Stating the limit is part of the solution: it tells you what to demand in a contract and what is already solved by the architecture.

The stack

The system is the foundation of MSI's CRM: an omnichannel inbox where WhatsApp messages become conversations, the AI agent answers, and any human attendant can take over the conversation at any moment.
  • Backend: TypeScript and Node.js 22, in modules split by responsibility (chat, channel and agent), talking through queues and contracts;
  • Customer service dashboard: React with React Router;
  • Database: PostgreSQL;
  • Answer generation: Python, with an open-weight model;
  • Organization: a pnpm monorepo, infrastructure as code and tests with Jest and pytest, written before the code.

The price of this choice

Calling an API would be much simpler. Running your own model has a cost:
  • Cold start: to avoid paying for idle GPUs, the first answer after a while without use takes longer, while the machine boots; when warm, the answer comes in seconds.
  • Quality: an open model of affordable size is not the best commercial model. The choice is made by measurement, not by reputation.
  • More moving parts: asynchronous generation, retries with growing backoff, a circuit breaker for when the provider goes down and a periodic sweep for the result that never arrives.
  • Two sides of the contract: what encrypts and what decrypts are written in different languages, and both are tested against the same fixed examples, so they agree byte for byte.
I paid that cost because, here, privacy was a requirement, not a differentiator.

What I take to the next project

  • The customer's data is not yours to hand over. The company receives the conversation to serve the customer, and that is the only thing it can be used for.
  • Privacy law is an architecture requirement. In this case, it decided the model, the message format and even what can show up in a log.
  • Design so you don't need to trust. Contracts and audits are still necessary, but "what can the third party see?" is worth more than "what does the third party promise?".
  • Say the limit out loud. "It only exists in plain text in memory during generation" is a verifiable sentence. "End to end" almost never is.
If you are going to put AI to answer your company's customers, the first conversation is not about which model answers best. It is about where your customer's conversation will exist in plain text, and who can see it there.
Photo of Yago Marinho
Yago MarinhoSenior Software Engineer. I build AI-powered products, from design to deploy.
See portfolio ↗