---
description: >-
  Control the client and server artifacts used by a self-hosted Watcher deployment.
---

> 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%20Supply%20chain%20security&body=Page%3A%20Supply%20chain%20security%0AURL%3A%20https%3A%2F%2Fwatcher-docs.apolloresearch.ai%2Fself-hosting%2Fsupply-chain%2F%0A%0A

# Supply chain security

A self-hosted deployment receives artifacts through two paths:

| Artifact | Default source | Internal control |
| --- | --- | --- |
| [Watcher client](../client/index.md), installer, and checksums | Public `ApolloResearch/watcher-bin` releases | `WATCHER_DOWNLOAD_BASE` |
| Analyzer, API, and bootstrap images | Apollo's container registry | `WATCHER_IMAGE_REGISTRY` |

The self-host bundle is published with the client release. Approve the bundle,
client, and server images together. Do this even if you import them through
different systems.

## Verify release files

Download the self-host bundle and `checksums.txt` from the same
[Watcher release](https://github.com/ApolloResearch/watcher-bin/releases).
Verify the bundle before unpacking it:

```sh
grep " watcher-self-host-<version>.zip$" checksums.txt \
  | shasum -a 256 -c -
```

Use `sha256sum -c -` on systems with GNU coreutils. The installer performs the
same checksum check for the client archive. A checksum detects corruption. It
does not detect a compromised release channel. Use your normal approval and
scanning process before copying artifacts into an internal mirror.

## Keep releases compatible

Use the deployment definitions and server image tag from the same release. This
includes the Helm chart for Kubernetes. Upgrade the server before the client
fleet. The public installer selects a client supported by the configured server.
For an internal mirror, choose a client release the server supports.

## Use internal mirrors

For the client, mirror the installer, `checksums.txt`, and the platform archives
you use. Keep their published filenames. Set `WATCHER_DOWNLOAD_BASE` while
running the installer. Mirror-backed clients do not update automatically.
Replace the approved files and redeploy the client through your fleet tooling.

For the server, import the `xylon-api`, `bootstrap`, and `analyzer`
repositories. Preserve their suffixes. For Kubernetes, configure the registry
prefix and pull credentials through
[Helm values](kubernetes-infrastructure.md#2-configure-the-helm-release). For
Docker Compose, set the registry and tag in `.env`:

```sh
WATCHER_IMAGE_REGISTRY=registry.example.com/security-approved
WATCHER_IMAGE_TAG=<tag>
```

The system that performs the import needs read access to the release images. It
also needs write access to the internal registry. It can run outside the Watcher
network. Complete that approval and import before setup. The Watcher host itself
needs access only to the internal registry.

Run `docker compose config --images` before deployment. Check that every Watcher
image uses the internal registry. Apply your registry's normal signing,
scanning, digest, and immutability controls.

The bundled [Terraform module](aws-infrastructure.md) configures Apollo registry
authentication by default. This includes an IAM policy on the host role and a
systemd timer that refreshes the registry login every eight hours. For a
mirror-only host, disable both. Set this module input and authenticate through
your own registry tooling:

```hcl
configure_apollo_ecr = false
```

The bundled Postgres image comes from Docker Hub. Mirror it separately when the
host cannot reach Docker Hub. Use the override in
`compose.override.yml.example`. Do not change the Postgres major version for an
existing data volume.

See [Update Watcher](updates.md) for server and client updates. See
[Automate Analyzer updates](automatic-updates.md#internal-registries-and-restricted-networks)
for connecting release imports to your deployment pipeline.
