Data Handling & Privacy
This page is the honest inventory: what personal data AVA stores, where it
lives, which third parties it reaches and why, what retention levers exist
today, and what that means for GDPR-style obligations. It describes the
shipping v1.6.3 codebase. How the system is built and secured is covered in
architecture-security.md.
The one-sentence summary: AVA is single-tenant and self-hosted — every byte
lives on infrastructure the deploying MSP controls, and data leaves that
host only for the integrations the MSP itself configures (AutoTask, an AI
provider, email, reCAPTCHA, optionally NinjaOne).
Where data lives
| Location | What's there | Who controls it |
|---|---|---|
SQLite database (Docker volume, e.g. ava-data) | Sessions, transcripts, survey ratings, engineer accounts, canned responses | You (the deploying MSP) |
Uploads directory (Docker volume, e.g. ava-uploads) | Chat file attachments, per-session, under UUID filenames | You |
| Host-side env file (mounted read-only) | All credentials and configuration | You |
| Your AutoTask instance | Tickets, contacts, notes, transcripts, time entries, attachments | You, under your existing AutoTask agreement |
| Your AI provider (Anthropic / OpenAI / Google / OpenRouter — your choice, your key) | Transcript-derived text at specific call sites (detailed below) | You, under your provider agreement |
| SMTP2GO (or your SMTP relay) | Outbound emails in transit | You, under your SMTP agreement |
| Google reCAPTCHA | Bot-detection signals from the public chat page | Google, per reCAPTCHA terms |
| NinjaOne (optional) | Hostname/username lookup queries; device telemetry read back | You, under your NinjaOne agreement |
There is no vendor-operated backend in any path: the product vendor (Aixtek
Automation Labs) receives no telemetry, no analytics, and no customer data
from your deployment.
What AVA stores locally
Chat sessions (SQLite, Session table)
Session table)Captured from the public contact form and the chat lifecycle:
- Client first name, last name, email address, phone number.
- Company name/domain (derived from the email domain's AutoTask match).
- The issue description as typed by the client.
- AI triage output: priority (P1–P4), AutoTask issue-type classification, and
a one-line topic summary derived from the issue description. - AutoTask linkage IDs (ticket, company, contact) — numeric references, not
copies of AutoTask data. - Optional device-lookup hints (hostname, username, domain) if the client
arrived via an RMM systray link that supplied them. These are sanitized,
length-capped, used only as lookup keys, and scrubbed from the browser URL
immediately after capture. - Wrap-up fields: the engineer's closure notes draft, resolution choice, and
step-completion checkpoints. - Timestamps (created, closed, updated) and the assigned engineer.
Transcripts (Message table)
Message table)Every message in every chat — client, engineer, and system lines — with
sender, content, and timestamp. Anything a client types into the chat is
stored verbatim, so transcripts can contain whatever personal data clients
choose to share. Attachment references are stored as message metadata.
Attachments (uploads volume)
Files uploaded by either side of a chat, stored under
uploads/<sessionId>/<uuid> — the client's original filename is kept only as
display metadata, never as a filesystem path. Subject to the retention job
described below.
Survey ratings (SurveyRating table)
SurveyRating table)An optional post-chat rating (1–5 stars) and free-text comment, at most one
per session, linked to the session.
Engineer accounts (Engineer table)
Engineer table)Work email, display name, role, an AutoTask resource-ID mapping, and an
offboarding timestamp. Populated from Entra ID sign-in — no passwords are
ever stored (authentication is delegated to Microsoft).
Client browser storage
The chat page keeps its state (session token, contact info for reconnect,
device hints) in the browser's sessionStorage/localStorage for the
duration of the visit. No third-party analytics or advertising trackers are
present on either the client page or the dashboard.
What is written to AutoTask
AutoTask is where a chat becomes a permanent operational record. On session
start, AVA:
- Matches the client's email domain to one of your AutoTask Companies
(falling back to your configured catchall company for personal domains). - Finds or creates a Contact — writing the client's name, email, and
phone into your AutoTask instance if no contact exists yet. - Opens a Ticket carrying the client's issue description and the triage
classification (priority, issue type, summary), using your configured
default status/queue/source/type values.
On close (the engineer's wrap-up), AVA writes to the ticket:
- A time entry (engineer-reviewed billed hours, attributed to the
engineer's mapped AutoTask resource). - A client-facing note and an internal note, both engineer-authored
(optionally AI-drafted, always engineer-reviewed before submit). - The full chat transcript as its own note — sender labels, timestamps,
and message content verbatim. - Any chat attachments, uploaded to the ticket.
- The resolution field and the final ticket status.
Once data is in AutoTask it is governed by your AutoTask instance's own
retention, access control, and data-processing terms — AVA does not manage it
further. If you handle an erasure request, remember the AutoTask copy exists
alongside the local one.
What reaches the AI provider
AI calls go to whichever provider you configure (LLM_FAST / LLM_QUALITY),
directly, using your API key — there is no intermediary. Prompts also include
your configured company name/descriptor/profile (branding, not client data).
The exact data scope per call site:
| Call site | When it fires | Data sent to the model |
|---|---|---|
| Triage | Automatically, once per new chat | Client's name, the email domain only (not the full address), the issue description, and your live AutoTask issue-type picklist labels |
| Field summarizer (wrap-up "draft with AI" buttons) | Only when an engineer clicks it | The session transcript — sender roles + message content, capped at ~24k characters (most recent kept). No client contact fields are attached, but the transcript itself contains whatever was typed in chat |
| Transcript summarizer (quality tier) | When a long-form summary is generated | Same transcript scope and cap as the field summarizer |
| Similar resolutions | Engineer's context panel during a chat | The current issue text plus titles, descriptions, and resolution notes of recently closed AutoTask tickets (count- and length-capped) |
| Ticket trends | Engineer's context panel during a chat | Metadata of the client company's recent AutoTask tickets — number, title, capped description, status, type, dates |
Honest notes:
- Transcript-derived calls can carry any personal data a client typed into
the conversation. If a client pastes a password into chat, that text is in
the transcript, and the transcript is what gets summarized. (The default
welcome message warns clients not to share passwords, and you can
customize it.) - All inputs are length- and count-capped; model outputs are
schema-validated where they drive ticket fields; failures degrade to
non-AI fallbacks. See
architecture-security.md. - Whether the provider retains or trains on API traffic is governed by
your agreement with that provider — review your chosen provider's API
data-use terms as part of your own compliance work. Switching providers is
an env-var change, so you can standardize on whichever provider your
privacy posture requires.
What reaches other services
- Email (SMTP2GO or your relay). Three outbound paths, all
operator-configured, all fail-closed when unconfigured (the send is
skipped, never redirected to a default address): the after-hours
email-a-ticket form (client name, email, phone, and message → your
configured support mailbox), engineer feedback submissions
(FEEDBACK_EMAIL), and the weekly survey report (REPORTS_EMAIL— note
this report contains personal data: per-rating lines naming the client,
their company, the engineer, the ticket number, and any comment text, plus
the aggregates). - Google reCAPTCHA v3. The public chat page loads reCAPTCHA, so Google
receives the bot-detection signals that service inherently collects from
visitors; the server then verifies the token with Google. This is the only
third-party script on the client page. Publish this in your own privacy
notice. - Microsoft Entra ID. Engineer sign-in only. No client data flows to
Microsoft. - NinjaOne (optional, off by default). When configured, AVA sends the
session's hostname/username hints (and the client email's local part as a
last-resort search key) to your NinjaOne tenant to find the device, and
reads back telemetry for display. The credential you create is
monitoring-scope (read-only). No chat content is ever sent to NinjaOne.
IP addresses
Client IPs are used for in-memory rate limiting (session starts, uploads) and
are not persisted to the database. The nginx access logs on your host do
record client IPs, subject to the built-in log rotation (10 MB × 3 files per
service); the provided log format omits URL query strings.
Retention & erasure levers
What exists today, honestly labeled:
| Data | Mechanism | Default |
|---|---|---|
| Attachments | Automatic: an in-process retention job deletes each closed session's upload directory once closedAt is older than the window — regardless of whether the AutoTask upload succeeded | On; 30 days (UPLOAD_RETENTION_ENABLED, UPLOAD_RETENTION_DAYS, UPLOAD_RETENTION_INTERVAL_HOURS — every 6 h) |
| Attachments (earlier) | Automatic: on a fully successful wrap-up, local files are purged as soon as every attachment is confirmed uploaded to AutoTask | Always on |
| Sessions, transcripts, survey ratings | Operator-managed: rows persist in SQLite indefinitely. There is no built-in retention window or self-service erasure UI today | — |
| AutoTask copies | Governed by your AutoTask instance | — |
| Backups | Whatever your backup tooling retains | — |
To honor an erasure request for the local copy, delete the session's rows
directly (children first — messages and any survey rating, then the session),
remove its upload directory if one still exists, and handle the AutoTask
ticket/contact side in AutoTask itself. For example, against the database
file with the sqlite3 CLI:
-- Replace :sid with the session id
DELETE FROM Message WHERE sessionId = :sid;
DELETE FROM SurveyRating WHERE sessionId = :sid;
DELETE FROM Session WHERE id = :sid;Stop the container (or take the write briefly offline) before editing the
database file directly, and take a backup first.
Backup implications
The two Docker volumes — the SQLite database and the uploads directory — are
the complete local data set, and both contain personal data. Practical
consequences:
- Backups of those volumes inherit every transcript and attachment; encrypt
them at rest and give them a retention period consistent with your privacy
commitments — an erasure performed on the live database does not reach
last month's backup unless your process says it does. - The host-side env file contains all credentials. Back it up separately
from and more restrictively than data backups (it is deliberately not in
the repository or the image), and keep itchmod 600— the app warns at
boot if it is group- or world-readable. - A consistent SQLite backup is easiest taken while the container is
stopped, or via SQLite's online-backup tooling; a plain file copy of a
database under active write can be torn.
GDPR / privacy FAQ
Who is the data controller?
You, the deploying MSP. AVA is self-hosted, single-tenant software; the
product vendor operates no service in the data path and receives no personal
data from your deployment. You remain controller (or processor for your own
clients, per your MSA) exactly as you are for the rest of your stack.
Who are the sub-processors?
Only the services you configure: your AutoTask instance, your chosen AI
provider, your SMTP provider, Google (reCAPTCHA), Microsoft (engineer SSO),
and optionally your NinjaOne tenant. Most MSPs already have agreements with
most of this list. There are no hidden ones.
Where does the data physically reside?
Wherever you run the container. Nothing constrains hosting region — an
EU-resident deployment on an EU host keeps the local data set in the EU;
integration traffic goes wherever your configured providers operate.
Can I answer a data-subject access request?
Yes — everything local is in two well-defined places (the SQLite tables
described above, plus the session's upload directory), keyed by the client's
email address on the Session table. Remember the AutoTask copy.
Can I honor an erasure ("right to be forgotten") request?
Yes, but it is operator work today: SQL deletion for the local rows, file
deletion for any remaining uploads, and AutoTask-side cleanup — see
Retention & erasure levers. There is no
one-click erasure feature yet.
Is chat data used to train AI models?
AVA itself does no training and keeps no vendor-side copy. Whether your AI
provider retains or trains on API traffic is set by your agreement with that
provider — check its API data-use terms and pick your provider accordingly.
What cookies does it set?
The dashboard sets one first-party, HttpOnly session cookie for signed-in
engineers. The client chat page uses browser session storage (not cookies)
for its own state, plus whatever reCAPTCHA sets under Google's terms. There
are no advertising or cross-site tracking cookies.
How long are clients' IP addresses kept?
In the application: only in memory, for rate limiting — never written to the
database. On the host: in rotated nginx access logs (bounded at roughly
30 MB per service by the shipped log-rotation config).
What should my client-facing privacy notice cover?
At minimum: that chat contents become part of the support ticket in your PSA;
that AI assists triage and summarization (naming your provider if your
notice style requires it); reCAPTCHA's presence on the chat page; and your
retention periods for transcripts and attachments.
What to read next
architecture-security.md— how these flows
are secured.configuration.md— every retention, email, AI, and
integration variable named above.white-label.md— customizing the welcome message and
client-facing copy (including the don't-share-passwords warning).
Updated about 1 hour ago