Skip to main content
Working with an agent? Give them a link to this page as markdown.

Client deployment

The Watcher client runs on each developer machine. It sends coding-agent sessions to your self-hosted backend.

EnvironmentInstallation path
Individually managed machineRun the installer as the developer
Ephemeral development VMBake the client into the VM image
Persistent managed fleetFollow the MDM rollout

Install for one user​

Run the installer as the developer account and specify the self-hosted URL:

curl -fsSL https://github.com/ApolloResearch/watcher-bin/releases/latest/download/install.sh \
| bash -s -- --watcher-api-url https://watcher.example.com

Installation is per user. The installer records the backend and installs the coding-agent hooks. Run watcher afterward to start the client, then follow First run and sign-in to finish setup.

See Supply chain security for internal mirrors.

Sending additional headers​

In proxy authentication mode, set one WATCHER_HEADER_* environment variable for each header the client must send:

export WATCHER_HEADER_X_FORWARDED_USER=adrian@veidt.ent
export WATCHER_HEADER_X_AUTH_PROXY_TOKEN=RAMESESII

The suffix becomes the header name. Underscores are replaced by hyphens. The installer stores the values in an owner-only file under ~/.apollo_monitor/.

To rotate them, re-run watcher hooks install. To remove them, unset the variables and run watcher hooks clear-headers.

The server may start rejecting a client's requests. This can happen due to:

  • A gateway misconfiguration
  • An identity-provider outage
  • A rotated proxy token

When this happens, the client backs off to periodic retries. It disables its coding-agent hooks. Sessions stop being recorded and graded. Each agent's own permission prompt gates tool calls in the meantime.

The client does not fall back to another identity after rejection. The identity the server trusts is whatever reaches it in the headers. A client that kept its hooks running would be grading against a backend that answers 401. An organization whose settings allow tool calls through on a grading failure would have them allowed unreviewed.

Run watcher doctor on the machine to see the rejection details. It shows the server's message and the request ID to look for in your server logs.

Where to fix this depends on which headers carry the identity.

For headers your reverse proxy injects, fix the proxy. That is the whole job. No client-side action is needed. The next accepted request restores normal traffic and re-enables the hooks on its own.

For the WATCHER_HEADER_* values above, the client sends the copy stored in its own file. A value that changes server-side strands every machine holding the old copy until each is updated. A rotated WATCHER_PROXY_AUTH_TOKEN is the common example. To fix each machine:

  1. Set the new value in the environment
  2. Re-run watcher hooks install
  3. Restart Watcher

Recovery is per machine. A rotation across a fleet is a rollout, not a server-side switch.

Renewable proxy tokens​

When the gateway requires short-lived bearer tokens, configure an external credential helper on each machine. Watcher calls the trusted CLI, reuses its token briefly, and renews it. The gateway still validates the token and supplies the authenticated identity. Do not capture the same Authorization header with WATCHER_HEADER_* or combine the helper with stored Watcher SSO credentials or an API key.

Helper errors use safe categories instead of gateway response text. Run watcher auth helper check to diagnose acceptance, or complete company sign-in externally and run watcher auth helper refresh to force renewal.

Bake the client into a VM image​

Install Watcher while building the image, as the account developers will use:

curl -fsSL https://github.com/ApolloResearch/watcher-bin/releases/latest/download/install.sh \
| bash -s -- --watcher-api-url https://watcher.example.com

~/.local/bin/watcher autostart install
~/.local/bin/watcher autostart enable

Repeat this for each account on a multi-user VM.

In proxy mode, set that user's WATCHER_HEADER_* values while running the installer or watcher hooks install. The command captures them in an owner-only file. Later launches read that file.

In SSO mode, each developer signs in from the Watcher menu bar on macOS, at http://localhost:8228, or with watcher login, which also works on a VM they reach over SSH. See Signing in without a browser for details.

Client updates​

Clients started by the login agent update automatically. They update to a release matching the server. Foreground and mirror-backed clients require an explicit update. See Update Watcher.