---
description: >-
  Review self-hosted Watcher data collection, storage, network connections, telemetry, auditing, and retention.
---

> Part of the Watcher docs. Index of all pages, with summaries: https://watcher-docs.apolloresearch.ai/llms.txt
> Before upgrading Watcher, read the release pages and full changelogs for every version crossed: https://watcher-docs.apolloresearch.ai/releases/index.md
> Found an issue with this page? Report it: https://github.com/ApolloResearch/watcher-bin/issues/new?title=Docs%20feedback%3A%20Security&body=Page%3A%20Security%0AURL%3A%20https%3A%2F%2Fwatcher-docs.apolloresearch.ai%2Fself-hosting%2Fsecurity%2F%0A%0A

# Security

This page describes a self-hosted Watcher deployment's data flows, for
security and compliance review.

## What is collected

The [Watcher client](../client/index.md) records coding-agent
[sessions](../concepts/sessions-and-trajectories.md). A recorded session
contains:

- The full conversation: user prompts, assistant replies, the system prompt,
  and tool calls with their arguments and results. Tool results include
  whatever the agent read or produced, so transcripts can contain source
  code, file contents, and any secrets the agent encountered.
- Which agent produced the session ([Claude Code or Codex](../supported-agents.md)), timestamps, and
  the developer's identity. In proxy mode this is the identity header your
  proxy injects; in SSO mode it comes from the SSO sign-in. See
  [authentication mode](setup.md#choose-an-authentication-mode).
- [Blocking review](../concepts/blocking-and-trailing-review.md) decisions:
  the tool context, score, and outcome for each reviewed call.
- Grades: the scores, explanations, and summary text produced by
  [graders](../concepts/graders.md).

Watcher does not record the screen, keystrokes, or terminal contents; the
client captures only terminal identifiers (terminal program, tty, session
IDs) so its UI can focus the right window. It records what the agent did,
not what the developer did outside the agent.

## Where it is stored

The durable copy of the recorded sessions, decisions, and grades lives in
your deployment's Postgres database, the bundled Docker Postgres or the
managed Postgres you configured. The terminal-focus identifiers stay on the
client and are not uploaded. [Operations](operations.md#backups) covers server
backups; the state on each developer's machine is covered on the
[client page](../client/index.md#per-machine-settings).

## Which LLM providers are called

All LLM grading runs from your Watcher deployment, never from developer
machines. Blocking review's triage and deep review send the transcript
excerpt under review from the client to your deployment, which calls the
grading model;
[trailing review](../concepts/blocking-and-trailing-review.md) grades
server-side the same way.

The API makes provider calls. The grading scheduler triggers server-side
grading and needs database access, but it does not hold provider keys.

The scheduler does hold database credentials. Each pass connects to Postgres
to list the organizations to grade, then calls the API for each one; it reads
no session content. Include it when you inventory which containers receive
database credentials, and allow it a route to Postgres when you restrict
network or database access. If a policy blocks that connection, the scheduler
logs `async grading sweep failed` and retries on the next interval, and
trailing review stays stopped until you restore access.

The `xylon-retention-cleanup` container also holds database credentials and
runs the `xylon-api` image with a dedicated entrypoint. It contacts no LLM
provider. It connects to Postgres to delete expired unlinked grader inputs and
to enforce any enabled organization session-content retention policy. That
policy is disabled by default. Organization administrators configure it through
the Analyzer's [Data Retention controls](../concepts/organization-settings.md#data-retention)
or the organization settings API. If the worker cannot reach Postgres, it logs
the failed sweep and retries on the next interval.

The default [managed monitors](../concepts/graders.md#monitors) use all three
providers. Triage uses OpenAI's `gpt-5.6-luna`, Gateway uses Anthropic's
`claude-opus-4-7`, Deep Review uses Anthropic's `claude-sonnet-5`, and session
summaries use Google's `gemini-2.5-flash`. Obtain access to these exact models
before setup. They are Watcher's recommended and tested configuration.

What a grading call sends to the provider is session content: prompts, agent
output, and tool results. You supply the provider API keys, so provider choice,
accounts, and data-processing terms are yours. You can override monitor models
in `server-config.yaml` when your deployment uses a different provider set.
Alternative models are not Watcher's recommended, currently tested
configuration and may impede monitor performance. A missing key or unavailable
model makes the affected grading path fail; Watcher does not select another
model automatically.

## Self-hosted Watcher does not phone home

The stack sends no usage analytics, error reporting, or other telemetry to
Apollo. It makes these outbound connections when configured:

- **LLM APIs:** grading sends session content to the configured model providers.
- **WorkOS:** in [SSO mode](setup.md#sso-mode), the API uses WorkOS for sign-in,
  token management, and organization membership. Proxy mode does not use it.
- **Slack:** if an administrator configures a webhook, notifications send the
  grader's finding, scores, and an Analyzer link. Blocking-review alerts can
  also contain tool arguments, paths, or secrets.

Installation and upgrades pull server images from a container registry and
client files from a public release or internal mirror. These requests contain
no session data. See [Supply chain security](supply-chain.md) for internal
mirror options.

The Watcher client sends session data only to the backend recorded during
installation. The [deployment example](deployment-example.md) shows these
connections.

## Admin access auditing

Admins can see every user's sessions through the
[Analyzer](../concepts/analyzer.md), so the deployment keeps the reciprocal
record: an [admin audit log](operations.md#admin-audit-log), on by default,
appending one JSON line for each read of another user's session data,
each session list or search request, user-directory reads, and
organization-level settings writes. Session-content scrubs are always
recorded. Administrator actions carry the actor's email; automatic retention
uses `retention-policy` as the actor and `system` as the authentication method.
Records carry resource identifiers, never session content. The file stays on
the deployment host in a Docker volume, is not collected by the support
bundle, and is itself personal data to handle accordingly.
[Operations](operations.md#admin-audit-log) covers enabling, reviewing,
and pruning it.

## Retention and deletion

By default, Watcher retains session content indefinitely. An administrator can
remove the stored content of one session with
`DELETE /api/v1/sessions/{session_id}/content`. The operation removes the
session's messages, tool-call records, and linked blocking-review decisions
and grades from the active Postgres database, leaving only the content-free
record described below.

The server also supports an organization-level inactive-session retention
policy. It is disabled by default, so session content is retained indefinitely.
Organization administrators can enable it from the Analyzer's
[Data Retention controls](../concepts/organization-settings.md#data-retention)
or with `PATCH /api/v1/organization/settings`. The configured inactivity period
must be between 7 and 365 days; setting it to `null` disables the policy. The
always-on retention worker removes content from sessions whose latest recorded
activity is at least the configured number of days old. The worker runs
immediately at startup and every 24 hours thereafter.

The scrub retains the session record, its historical activity dates and
message count, trajectory grades, notifications, content-free activity
history, and one content-free fact per tool call: when the call happened,
what Watcher decided about it (allowed, denied, or escalated to a person, and
under which enforcement mode), and the numeric scores that decision was based
on, which are recorded on the fact as the call is decided and so outlive the
grades they came from. The fact never carries the tool's name, its arguments,
or any prose. Those facts are
what keeps tool-call counts, filters, and severity accurate for a scrubbed
session in the [Analyzer](../concepts/analyzer.md). A later full upload of the
same session can restore its messages and reconnect retained trajectory
grades, so a scrub is not a tombstone that blocks re-upload.

A blocking-review grade whose corresponding decision has not yet arrived is
removed by the scrub when the grade recorded which session it was graded for,
which grades written by current Watcher clients do. Unlinked grades without
that session reference (from older clients, or graded before the session's
first upload) cannot be removed by this session-specific operation; Watcher's
always-on retention worker makes these unlinked grader inputs eligible for
deletion after eight days, then deletes them on its next sweep. Linked grades
and session content outside an enabled policy remain until an administrator
scrubs the session. Scrubbing and the retention worker do not alter source
files, client-local state, external copies, or existing backups.

Saved
[managed client settings](../concepts/organization-settings.md#managed-client-settings)
documents are also retained as an append-only version history.

Retention beyond these session-content and orphan-grade policies is yours to
implement with standard database tooling. Backups remain under your control
(see [Operations](operations.md#backups)).

On developer machines, `watcher uninstall` removes the hooks and the binary
but intentionally keeps the local state under `~/.apollo_monitor/`,
printing a reminder to remove it manually. Uninstalling a client never
touches the data already uploaded to the deployment.
