Watchlight AI Beacon — Installer
Self-contained installer for the Watchlight Beacon stack. Deploys all services on any Linux or macOS host with Docker — no repo clone needed.
There are two installers:
| Installer | Purpose |
|---|---|
| Beacon Installer | Full control plane (Registry, Discovery, secret management, TLS) |
| Standalone Discovery Scanner | Deploy additional scanners on remote Docker hosts that report to a central Beacon |
Beacon Installer
Services
| Service | Purpose | Default Port |
|---|---|---|
| caddy | TLS reverse proxy (optional — eval and production-caddy profiles only; not used in production profile) | 8443 |
| openbao | Secret management (optional — eval profile only; production profiles use AWS Secrets Manager or env vars) | 8200 |
| postgres | Database (optional — eval profile only; production profiles use BYO database) | 5432 |
| wl-registry | AI Agent & MCP server catalog | 8080 |
| wl-registry-frontend | Registry dashboard | 3000 |
| wl-discover | Network scanner + agent detector | — |
| wl-apdp | Agentic Policy Decision Point | 8081 |
Use the --services flag to select which services to install (default: all). See Service Selection.
Quick Start
# Download the installer
curl -fsSL https://docs.watchlight.ai/install-beacon.sh -o install-beacon.sh
chmod +x install-beacon.sh
# Install all services (prompts for configuration interactively)
./install-beacon.sh --ghcr-token <token>
# Or with a custom domain
./install-beacon.sh --domain beacon.company.com --ghcr-token <token>
# Install specific services only
./install-beacon.sh --services registry,discover --ghcr-token <token>
Prerequisites
- Docker 24+ with Compose v2
curlandopenssl- GHCR access token (provided by Watchlight AI)
Deployment Profiles
The installer supports three deployment profiles:
| Profile | TLS | Database | Secrets | Best For |
|---|---|---|---|---|
eval (default) | Caddy auto-TLS | Embedded PostgreSQL | OpenBao (embedded) | Evaluation, development, demos |
production | Service-level TLS (BYO certs) | BYO PostgreSQL | AWS Secrets Manager or env vars | Enterprise production |
production-caddy | Caddy auto-TLS | BYO PostgreSQL | AWS Secrets Manager or env vars | Smaller production deployments |
# Evaluation (default)
./install-beacon.sh --ghcr-token ghp_...
# Evaluation with custom domain
./install-beacon.sh --profile eval --domain beacon.company.com --ghcr-token ghp_...
# Production with service-level TLS + AWS Secrets Manager
./install-beacon.sh --profile production --tls-cert cert.pem --tls-key key.pem \
--database-url "postgres://..." --secret-provider aws --ghcr-token ghp_...
# Production with Caddy (smaller production)
./install-beacon.sh --profile production-caddy --database-url "postgres://..." \
--secret-provider env --ghcr-token ghp_...
# Frontend only (standalone dashboard)
./install-beacon.sh --frontend-only --ghcr-token ghp_...
CLI Reference
Install Flags
| Flag | Default | Description |
|---|---|---|
--ghcr-token TOKEN | (prompt) | GHCR access token |
--domain DOMAIN | system hostname | Domain name for TLS cert |
--version TAG | 0.3.0-preview | Image version |
--license-key KEY | (none) | Watchlight license key |
--log-level LEVEL | info | Log level |
--registry-port PORT | 8443 | Registry dashboard port |
--install-dir PATH | /opt/watchlight-beacon | Installation directory |
--agent-reg-mode MODE | open | open|token_required|disabled |
--tls-cert PATH | (none) | TLS certificate (PEM) |
--tls-key PATH | (none) | TLS private key (PEM) |
--frontend-port PORT | 3000 | Frontend host port |
--api-port PORT | 8443 | Registry API TLS port |
--postgres-port PORT | 5432 | PostgreSQL port |
Profile Flags
| Flag | Default | Description |
|---|---|---|
--profile PROFILE | eval | eval, production, or production-caddy |
--database-url URL | (none) | PostgreSQL connection string (production profiles only) |
--secret-provider SP | (none) | aws or env (production profiles only) |
--aws-region REGION | us-east-1 | AWS region for Secrets Manager |
--aws-secret-prefix P | watchlight/beacon | Secret name prefix |
Service Flags
| Flag | Default | Description |
|---|---|---|
--services SERVICES | all | Comma-separated list of services to install. Available: registry, discover, apdp |
--apdp-port PORT | 8081 | WL-APDP HTTP port |
Component Flags
| Flag | Description |
|---|---|
--frontend-only | Install only the frontend dashboard (no backend) |
--components MODE | all or frontend |
Operations
| Flag | Description |
|---|---|
--status | Show container states and URLs |
--upgrade | Pull new images and restart (preserves data) |
--uninstall | Stop all containers, remove volumes and install dir |
Access
| URL | Description |
|---|---|
https://<domain>:8443 | Registry Dashboard |
https://<domain>:8443/topology | Interactive Topology Graph |
https://<domain>:8443/api/v1/servers | Registry API |
http://<host>:8081/health | WL-APDP health check (when apdp service enabled) |
http://<host>:8081/authorize | WL-APDP authorization endpoint |
Service Selection
By default, all services are installed. Use --services to install a subset:
# All services (default)
./install-beacon.sh --services all --ghcr-token <token>
# Registry + Discovery only (no authorization)
./install-beacon.sh --services registry,discover --ghcr-token <token>
# Registry + Authorization only (no discovery)
./install-beacon.sh --services registry,apdp --ghcr-token <token>
# All three services explicitly
./install-beacon.sh --services registry,discover,apdp --ghcr-token <token>
| Service | Flag Value | What It Installs |
|---|---|---|
| registry | registry | wl-registry + wl-registry-frontend |
| discover | discover | wl-discover (network scanner + agent detector) |
| apdp | apdp | wl-apdp (Agentic Policy Decision Point) |
The service selection is persisted in the state file and preserved across --upgrade operations.
WL-APDP shares the same PostgreSQL database as wl-registry (in eval mode) and runs its own migrations on startup. No additional database setup is required.
How It Works
- Self-contained — all configuration files (Docker Compose, Caddyfile, entrypoint) are embedded in the script as heredocs
- Secret management — generates secrets via
openssl rand, stores in OpenBao (eval) or AWS Secrets Manager / env vars (production) - Resume-safe — re-running detects existing containers and recovers secrets automatically
- TLS by default — Caddy or service-level TLS for all external access; internal traffic uses host networking with loopback binding
- No repo required — download the single script and run it
- Auto-detect hostname — defaults domain to system FQDN (e.g., EC2 instance hostname)
- Host networking — all services use
network_mode: hostfor host-level network visibility (enables eBPF-based discovery)
Network Architecture
All services run with network_mode: host:
- Internal services (OpenBao, PostgreSQL) bind to
127.0.0.1only - Caddy (eval/production-caddy) or wl-registry (production) terminates TLS on the registry port
- Host networking enables eBPF-based discovery via kprobes on
tcp_connect/inet_csk_accept
Security Model
Secret Management (OpenBao — Eval Profile)
OpenBao runs in production mode with file-backed persistent storage:
- Encryption at rest: Secrets are stored encrypted on a persistent Docker volume
- Auto-unseal: Unseal key stored at
${INSTALL_DIR}/.openbao-unseal-key(chmod 600, root-only) - AppRole authentication: Services authenticate using non-secret
role_ididentifiers — no tokens in env vars or on disk - Per-service policies: Each service has a scoped policy with least-privilege access
- Root token: Used only during installation, then deleted from the container
Secret Management (Production Profiles)
Production profiles support two secret providers:
- AWS Secrets Manager (
--secret-provider aws): Secrets stored in AWS with IAM-based access - Environment variables (
--secret-provider env): Customer manages secrets externally
Credential Security
- Secrets are generated at install time and never written to disk (except the unseal key backup in eval mode)
- No secrets in container environment variables —
docker inspectreveals only non-secretrole_idvalues - The
.beacon-envfile stores only non-secret config (domain, version, log level)
Docker Socket
Required for container discovery by wl-discover:
- Read-only mount (
/var/run/docker.sock:ro) - Process inspection: Configurable (default: true)
- Package inspection: Configurable (default: false)
- Network filter: Only inspects containers on the beacon network
Image Verification
After pulling images, the installer verifies each image:
- Digest verification: Confirms each image has a valid repository digest (sha256)
- Cosign signature verification: Verifies the cryptographic signature on each image using cosign. If cosign is not installed, verification is skipped with a warning.
Installed Files
| File | Purpose |
|---|---|
docker-compose.yml | Service definitions |
Caddyfile | TLS reverse proxy configuration (eval/production-caddy) |
docker-entrypoint.sh | Startup script — AppRole auth + secret fetch |
openbao-config.hcl | OpenBao production mode configuration (eval) |
openbao-entrypoint.sh | OpenBao init/auto-unseal script (eval) |
bao-server.crt/key | OpenBao TLS certificate (eval) |
pg-server.crt/key | PostgreSQL TLS certificate (eval) |
beacon-ca.crt | Caddy TLS CA certificate (auto-generated) |
.beacon-env | Saved non-secret configuration |
.openbao-unseal-key | OpenBao unseal key backup (chmod 600, eval only) |
.image-digests | Pulled image digest verification |
All files are required for the stack to function. Install directory is chmod 700 (root-only).
Troubleshooting
| Issue | Solution |
|---|---|
| Services won't start | Check Docker is running and has enough resources (2GB RAM minimum) |
| GHCR auth fails | Verify your token has read:packages scope |
| TLS errors | Trust the CA cert or use curl -k |
| Port conflicts | Use --registry-port to change the default port |
| Clean restart | ./install-beacon.sh --uninstall && ./install-beacon.sh --ghcr-token <token> |
Standalone Discovery Scanner
Deploy additional discovery scanners on remote Docker hosts. Each scanner reports to your central Beacon registry.
Prerequisites
- Docker 20+ running on the host
- Network access to the Beacon registry endpoint (HTTPS)
- Scanner credentials — created by an admin via the Registry UI or admin API
Quick Start
1. Create a Scanner (Admin)
In the Registry UI, go to Scanners → Add Scanner. Copy the scanner_id and api_key.
Or via the admin API:
curl -X POST https://beacon.company.com:8443/api/v1/admin/scanners \
-H "Content-Type: application/json" \
-H "x-admin-key: YOUR_ADMIN_KEY" \
-d '{"name": "prod-host-01", "description": "Production host scanner"}'
2. Install the Scanner
# Download
curl -fsSL https://docs.watchlight.ai/install-wl-discover.sh -o install-wl-discover.sh
chmod +x install-wl-discover.sh
# Install
./install-wl-discover.sh \
--registry-url https://beacon.company.com:8443 \
--scanner-id "UUID_FROM_STEP_1" \
--api-key "API_KEY_FROM_STEP_1" \
--ghcr-token "YOUR_GITHUB_PAT"
Or run ./install-wl-discover.sh with no flags for interactive mode.
3. Verify
Check the Registry UI — your scanner should appear under the Scanners tab within 60 seconds.
./install-wl-discover.sh --status
CLI Reference
Install Flags
| Flag | Required | Default | Description |
|---|---|---|---|
--registry-url | Yes | (prompt) | Central registry HTTPS endpoint |
--scanner-id | Yes | (prompt) | Scanner UUID from admin registration |
--api-key | Yes | (prompt) | Scanner API key from admin registration |
--ghcr-token | Yes* | (prompt) | GitHub PAT for pulling image (*skipped if cached) |
--scanner-name | No | $(hostname) | Human-readable name for this host |
--ca-cert | No | system CAs | Custom CA cert for registry TLS |
--version | No | 0.3.0-preview | Image version tag |
--docker-socket | No | /var/run/docker.sock | Docker socket path |
--network-scan | No | — | CIDR/hostname targets (see below) |
--schema-mode | No | hash_only | hash_only or full |
--log-level | No | info | Log level |
--dry-run | No | — | Print docker run command only |
Operations
# Check scanner status
./install-wl-discover.sh --status
# Upgrade to new version
./install-wl-discover.sh --upgrade --version 0.3.0 --ghcr-token "ghp_..."
# Uninstall (remove container + data volume)
./install-wl-discover.sh --uninstall
Network Scanning
By default, the scanner discovers MCP servers and agents running in Docker containers on the same host. To also scan remote network targets:
./install-wl-discover.sh \
--registry-url https://beacon.company.com:8443 \
--scanner-id "..." --api-key "..." --ghcr-token "..." \
--network-scan "10.0.1.0/24,10.0.2.0/24,mcp.internal:3000-3010"
Target formats:
- CIDR range:
10.0.1.0/24— scans all hosts on default MCP ports - Host + port:
mcp.internal:3000— scans specific host and port - Host + port range:
mcp.internal:3000-3010— scans port range on host - Comma-separated: combine multiple targets
Custom CA Certificates
If your registry uses a private CA (e.g., Caddy's internal CA), provide the CA certificate:
./install-wl-discover.sh \
--registry-url https://beacon.internal:8443 \
--ca-cert /path/to/ca.crt \
...
How It Works
- No config files: The scanner uses environment variables only ("remote-first" mode)
- Docker discovery: Monitors Docker containers via the socket for MCP servers and AI agent frameworks (LangGraph, CrewAI, AutoGen, LangChain)
- Container security metadata: Collects privileged mode, capabilities, user/UID, read-only rootfs, volumes, network mode, PID mode, image digest, and lifecycle timestamps
- Multi-tier agent detection: 4-tier configurable model — (1) static metadata, (2) process inspection, (3) package inspection, (4) generic AI detection via LLM API credentials
- Remote-first config: Scan parameters, detection tier toggles, and thresholds are fetched from the registry's Config Presets API
- Non-root: The container runs as UID 10001 with
no-new-privileges
Credential Security
Scanner credentials (scanner_id + api_key) are never stored in Docker volume labels or container environment variables:
- Credentials are written to a file inside the Docker volume (
/app/data/.credentials) with mode0400, owned by UID 10001 - A volume-embedded entrypoint reads the file and exports credentials as process-level env vars at startup
docker inspectanddocker volume inspectwill not reveal the API key- Upgrades recover credentials from the volume file automatically
Troubleshooting
| Issue | Solution |
|---|---|
| Docker socket permission denied | Ensure user is in the docker group: sudo usermod -aG docker $USER |
| TLS certificate errors | Provide registry CA cert with --ca-cert /path/to/ca.crt |
| Cannot reach registry | Check URL, network connectivity, and firewall rules |
| Scanner credentials rejected | Verify scanner was created in Registry UI and credentials match |
| Container crashes on startup | Check logs: docker logs wl-discover |
Support
- Partner Portal: https://www.watchlight.ai/partner
- Documentation: https://docs.watchlight.ai
- Email: sales@watchlight.ai