Skip to content

Security and privacy ​

An assistant inside a business application touches three sensitive things: the data of the user, an API key, and — once it can act — the application itself. Here is exactly what HelpChatAI does about each, so you can decide what to allow.

What leaves the application ​

When a question is sent to a provider, this is everything that travels:

What
The questionWhat the user typed
The conversationThe previous messages, up to HistoryMaxMessages
The screenFour fields only: name, label, class and help keyword
The documentationExcerpts of the pages your index matched (GroundingMaxPages, GroundingMaxChars)

Nothing reads your data. Not the grids, not the fields, not the database. The component never inspects the content of your forms — only the help properties you declared.

If a screen label can contain a customer name or an order number, blank it in OnGetContext:

pascal
procedure TMainForm.HelpChatGetContext(Sender: TObject; var AContext: THelpChatContext);
begin
  AContext.ScreenLabel := 'Documento';   // not 'Fattura 2026/0142 - Rossi S.p.A.'
end;

With stub or docsearch, nothing leaves the machine at all: there is no network call.

The microphone ​

Dictation only happens if you ask for it, and only while the user keeps the microphone on. Nothing is recorded, nothing is stored, nothing is sent anywhere by the component.

Where the voice goes depends on the engine. hveSystemDictation hands the microphone to the dictation of Windows, the one Win+H starts, which types into the box like a keyboard: the component never sees the audio and never sees the text. hveRecognizer uses the speech recognition of Windows, whose free dictation goes through Microsoft's online service, so the voice does leave the machine — to Microsoft, not to us, and only under a consent the user gives in the Windows settings.

That consent is theirs alone. The component reads whether it was given, explains what is needed and opens the settings page; it never writes that setting, because accepting to send one's voice to Microsoft is not a decision an application takes on someone's behalf. Refuse it and dictation does not start. VoiceEngine := hveNone removes the microphone button altogether.

The API key ​

On a desktop, a key in a file is recoverable by whoever owns the machine. HelpChatAI does what it can — the key is never in your source, never in what the installer packages, and read from a per-user file outside the installation folder — but the honest statement is: a key deployed to a client machine is a key you have given away.

When that matters, run the engine on a server. The clients then hold an application key, which grants nothing but the right to ask questions and which you can change in a configuration file the day it leaks. Per-user control goes through OnAuthenticate on the server.

Model output is untrusted content ​

A reply is text produced by a model and rendered inside a browser that sits in your process. It is treated as hostile input:

  • Markdown in safe mode: active HTML is escaped, so a reply cannot inject a <script> or an <iframe>.
  • URL schemes restricted to http(s), mailto, ftp and relative paths: javascript:, data:, vbscript:, file: are dropped. Bare URLs written as plain text are turned into links, in text nodes only, never inside code or an existing link.
  • A Content-Security-Policy on the page: it may talk to its own API and, when there is one, to the loopback host channel — nothing else, no external script, no remote image.
  • The browser is confined to the panel origin: any other navigation is cancelled and handed to the system browser, so a link in a reply opens outside the application.
  • User text and error messages never go through Markdown at all: they are HTML-encoded.

The local server ​

The transport that serves the page binds 127.0.0.1 only, on a free port, and every API call must carry a secret generated per process that only the page knows (it receives it in its URL). Another process on the machine cannot drive the assistant without that secret, and nothing is reachable from the network.

The same holds for the loopback host channel used with a remote engine, which additionally restricts CORS to the panel origin — never * — and answers the private-network preflight explicitly.

Actions ​

An assistant that can act is a different risk from one that answers. The design is deliberately narrow:

  • only the actions you registered exist; there is no generic entry point;
  • each one has the parameters you declared, and reading them never raises;
  • anything that changes data can require an explicit confirmation before it runs;
  • ActionsEnabled := False takes them all away at runtime — for a read-only mode or a user profile without the right to act.

Keep destructive operations (delete, post, send money) out of the registry, or behind Confirm and a handler that applies your own policy. The model decides what to ask for; your application decides what is allowed.

The conversation on disk ​

With PersistConversation (the default) the conversation is saved in %APPDATA%\<YourApp>\helpchatai-conversation.json and discarded after ConversationMaxAgeDays. On a shared or kiosk machine, set it to False. On a server, Sessions.Storage = memory keeps nothing after the last session ends.

A checklist before you ship ​

  • [ ] No helpchatai.json with a key in your installer.
  • [ ] OnGetContext blanks anything identifying in the screen label.
  • [ ] Destructive actions are not registered, or require confirmation.
  • [ ] PersistConversation matches how the machine is used.
  • [ ] If the application is installed at customers: the engine is on a server, or you accept that the key lives on their machines.
  • [ ] Your users know there is an assistant and what it sends — the same way you would tell them about any other cloud feature.

Released under the Apache License 2.0