Deploy the collector¶
The ARIS collector is a host-resident agent. Install it on each workstation or server where you want to observe supported AI tools, then connect it to the core ingest gRPC listener.
This page documents the current evaluation and small-pilot setup, where collector mTLS certificates are provisioned manually. For larger fleets, see Enterprise collector deployment for the target model before rolling out broadly.
The collector does four things:
- watches same-user supported AI processes;
- optionally tails local transcript JSONL files;
- optionally captures supported IDE SQLite stores;
- optionally accepts local OTLP/gRPC telemetry on
127.0.0.1:4317; - buffers envelopes in an encrypted local queue and forwards them to core.
Install core first
Finish Run with Docker Compose and confirm the web UI works before adding collectors. The collector forwards to core, so debugging is much easier once the identity foundation is already healthy.
1. Enable core ingest¶
Core only starts the collector ingest listener when ARIS_INGEST_GRPC_ADDR is set. In production, put the ingest listener behind a private network address or load balancer reachable only from the network segments where collector hosts run. mTLS still performs the collector authorization at the ingest layer.
The three certificate files are the server side of mutual TLS:
| Setting | Plain-English meaning |
|---|---|
ARIS_INGEST_SERVER_CERT_FILE |
Core's public certificate. Collectors use it to prove they are talking to your ARIS core, not an impostor. |
ARIS_INGEST_SERVER_KEY_FILE |
Core's private key for that certificate. Keep it secret. |
ARIS_INGEST_CLIENT_CA_FILE |
The CA certificate core trusts for collector client certificates. Any collector certificate must chain to this CA. |
The paths below are inside the core container. You still need to create the files on the Docker host and mount them into those paths.
Add these settings to the core environment:
ARIS_INGEST_GRPC_ADDR=0.0.0.0:8443
ARIS_INGEST_SERVER_CERT_FILE=/run/secrets/ingest-server.crt
ARIS_INGEST_SERVER_KEY_FILE=/run/secrets/ingest-server.key
ARIS_INGEST_CLIENT_CA_FILE=/run/secrets/collector-client-ca.crt
Generate evaluation certificates¶
For a first install, you can generate a small private CA with OpenSSL. Replace core.aris.example.com with the DNS name collectors will use to reach core, and replace eng-laptop-42.acme.internal with the first collector host identity.
mkdir -p dev-pki/core dev-pki/collectors
# 1. Create a CA that signs collector client certificates.
openssl genrsa -out dev-pki/collector-ca.key 4096
openssl req -x509 -new -nodes \
-key dev-pki/collector-ca.key \
-sha256 -days 3650 \
-subj "/CN=ARIS Collector CA" \
-out dev-pki/collector-ca.crt
# 2. Create core's ingest server certificate.
openssl genrsa -out dev-pki/core/ingest-server.key 4096
openssl req -new \
-key dev-pki/core/ingest-server.key \
-subj "/CN=core.aris.example.com" \
-out dev-pki/core/ingest-server.csr
cat > dev-pki/core/ingest-server.ext <<'EOF'
subjectAltName=DNS:core.aris.example.com
extendedKeyUsage=serverAuth
EOF
openssl x509 -req \
-in dev-pki/core/ingest-server.csr \
-CA dev-pki/collector-ca.crt \
-CAkey dev-pki/collector-ca.key \
-CAcreateserial \
-out dev-pki/core/ingest-server.crt \
-days 825 -sha256 \
-extfile dev-pki/core/ingest-server.ext
# 3. Create one collector client certificate.
openssl genrsa -out dev-pki/collectors/eng-laptop-42.key 4096
openssl req -new \
-key dev-pki/collectors/eng-laptop-42.key \
-subj "/CN=eng-laptop-42.acme.internal" \
-out dev-pki/collectors/eng-laptop-42.csr
cat > dev-pki/collectors/eng-laptop-42.ext <<'EOF'
subjectAltName=DNS:eng-laptop-42.acme.internal
extendedKeyUsage=clientAuth
EOF
openssl x509 -req \
-in dev-pki/collectors/eng-laptop-42.csr \
-CA dev-pki/collector-ca.crt \
-CAkey dev-pki/collector-ca.key \
-CAcreateserial \
-out dev-pki/collectors/eng-laptop-42.crt \
-days 825 -sha256 \
-extfile dev-pki/collectors/eng-laptop-42.ext
chmod 600 dev-pki/core/ingest-server.key dev-pki/collectors/eng-laptop-42.key
After this, the important files are:
| Host file | Mount or copy to | Used by |
|---|---|---|
dev-pki/core/ingest-server.crt |
/run/secrets/ingest-server.crt in the core container |
Core server certificate. |
dev-pki/core/ingest-server.key |
/run/secrets/ingest-server.key in the core container |
Core server private key. |
dev-pki/collector-ca.crt |
/run/secrets/collector-client-ca.crt in the core container |
Core's trust bundle for collector client certs. |
dev-pki/collector-ca.crt |
/etc/aris/collector/core-ingest-ca.crt on each collector host |
Collector's trust bundle for core's server cert. |
dev-pki/collectors/eng-laptop-42.crt |
/etc/aris/collector/collector.crt on that collector host |
Collector client certificate. |
dev-pki/collectors/eng-laptop-42.key |
/etc/aris/collector/collector.key on that collector host |
Collector client private key. |
Evaluation CA
The commands above are enough for a lab or pilot. For production, refer to Enterprise collector deployment for the enrollment path, or issue per-device certificates from your normal internal PKI with exactly one DNS or URI SAN identity per collector and track certificate expiry, rotation, and revocation.
Mount the files into core¶
For Docker Compose evaluation, add the ingest environment, mounts, and port to the core service:
services:
core:
environment:
ARIS_INGEST_GRPC_ADDR: "0.0.0.0:8443"
ARIS_INGEST_SERVER_CERT_FILE: /run/secrets/ingest-server.crt
ARIS_INGEST_SERVER_KEY_FILE: /run/secrets/ingest-server.key
ARIS_INGEST_CLIENT_CA_FILE: /run/secrets/collector-client-ca.crt
volumes:
- ./dev-pki/core/ingest-server.crt:/run/secrets/ingest-server.crt:ro
- ./dev-pki/core/ingest-server.key:/run/secrets/ingest-server.key:ro
- ./dev-pki/collector-ca.crt:/run/secrets/collector-client-ca.crt:ro
ports:
- "8443:8443"
Core runs as a non-root container user. The key file must be readable by that user and must not have group/world permission bits. On Linux Docker hosts, if core logs permission denied for ingest-server.key, use Docker secrets or change the host file owner to the container user while keeping mode 0600.
Restart core after changing these settings:
2. Issue collector certificates¶
Each collector needs its own client certificate and key. If you used the evaluation commands above, the first pair is already generated:
The client certificate must have exactly one DNS or URI SAN identity. ARIS uses that SAN as the collector host_id, and core rejects envelopes whose host_id does not match the authenticated certificate identity.
Example identity:
Use a stable identity value that your PKI or enrollment flow can issue. In secure mode the collector derives host_id from the certificate SAN; if you set host_id explicitly in collector.yaml, it must match that single DNS or URI SAN exactly. Common Name (CN)-only certificates are not accepted for collector identity.
Keep the private key private. You will copy it into the collector directory after creating the service user and directories below.
Do not reuse one client certificate across many hosts
Reusing a certificate makes every host report the same host_id. Issue one certificate per host or per managed device identity.
3. Build or install the binary¶
From the repository root, build the collector for the current host:
Install it where your service manager expects it, for example:
For Ubuntu 22.04/24.04 pilots, ARIS also has an internal Debian package builder. For RHEL 9-family pilots, ARIS has a matching RPM builder:
Both package formats install the same runtime contract under /usr/local/bin, /etc/aris/collector, and /var/lib/aris/collector. They do not ship a placeholder collector.yaml, because aris-collector enroll writes that file with exclusive-create semantics. The systemd unit uses ExecCondition=aris-collector validate-config ..., so installing the package before enrollment does not start a crash loop. Fleet tooling should place the enrollment token and CA bundles, run aris-collector enroll with --config-out /etc/aris/collector/collector.yaml, --cert-out /etc/aris/collector/collector.crt, --key-out /etc/aris/collector/collector.key, and --state-dir /var/lib/aris/collector, remove the token, fix package runtime ownership, then enable and start aris-collector.service.
After enrollment, match package runtime ownership and modes before starting systemd:
sudo chown root:aris-collector /etc/aris/collector/collector.yaml
sudo chmod 0640 /etc/aris/collector/collector.yaml
sudo chown aris-collector:aris-collector /etc/aris/collector/collector.key
sudo chmod 0600 /etc/aris/collector/collector.key
sudo chown root:aris-collector /etc/aris/collector/collector.crt
sudo chmod 0644 /etc/aris/collector/collector.crt
For managed macOS pilots, ARIS has an internal LaunchDaemon package builder:
The macOS package installs /usr/local/bin/aris-collector and /Library/LaunchDaemons/ai.ryora.aris.collector.plist, creates the _aris-collector service account, and prepares /Library/Application Support/ARIS/collector. It does not ship collector.yaml; Jamf or equivalent tooling should pre-stage the Core CA bundles, enroll with --allow-root-acknowledged I-UNDERSTAND-ROOT-MODE, --config-out, --cert-out, --key-out, and --state-dir under /Library/Application Support/ARIS/collector, repair ownership and modes, then enable and start the LaunchDaemon. The initial package uses file-backed certificate material; Keychain-backed storage remains future work.
For managed Windows pilots, ARIS has an internal WiX MSI builder:
The Windows MSI installs C:\Program Files\ARIS\Collector\aris-collector.exe, creates the demand-start aris-collector Windows Service running under NT AUTHORITY\LocalService, and prepares C:\ProgramData\ARIS\Collector. It does not ship collector.yaml; Intune, SCCM, or equivalent tooling should pre-stage the Core CA bundles, stage a one-time token file through a protected channel, enroll with package-compatible --config-out, --cert-out, --key-out, and --state-dir paths under C:\ProgramData\ARIS\Collector, remove the token, repair ACLs for the NT SERVICE\aris-collector service SID, validate the config, then start the service. The initial Windows package uses file-backed certificate material; Windows certificate store and TPM-backed key storage remain future work.
4. Create collector.yaml¶
On Linux systemd hosts, create a dedicated service user and private directories:
sudo useradd --system \
--home-dir /var/lib/aris/collector \
--create-home \
--shell /usr/sbin/nologin \
aris-collector
sudo install -d -m 0700 -o aris-collector -g aris-collector /etc/aris/collector
sudo install -d -m 0700 -o aris-collector -g aris-collector /var/lib/aris/collector
Copy the CA, collector certificate, and collector key into place:
sudo install -m 0644 -o aris-collector -g aris-collector \
dev-pki/collector-ca.crt /etc/aris/collector/core-ingest-ca.crt
sudo install -m 0644 -o aris-collector -g aris-collector \
dev-pki/collectors/eng-laptop-42.crt /etc/aris/collector/collector.crt
sudo install -m 0600 -o aris-collector -g aris-collector \
dev-pki/collectors/eng-laptop-42.key /etc/aris/collector/collector.key
Minimal production config:
paths:
state_dir: /var/lib/aris/collector
forwarder:
core_endpoint: core.aris.example.com:8443
mtls:
cert_path: /etc/aris/collector/collector.crt
key_path: /etc/aris/collector/collector.key
server_ca_path: /etc/aris/collector/core-ingest-ca.crt
server_name: core.aris.example.com
sources:
process:
enabled: true
otel:
enabled: true
transcript:
enabled: true
vscdb:
enabled: true
For a per-user collector, put state_dir under that user's home directory. transcript.enabled: true auto-watches supported transcript directories under the running user's home. vscdb.enabled: true captures supported IDE stores, including VS Code AI extensions and Cursor IDE. No per-host enumeration is required. The collector intentionally refuses to run as root unless you explicitly opt in, because a root collector can observe every user's AI activity on the host.
5. Validate the config¶
Run validation as the same user that will run the collector:
Expected output:
Validation is intentionally strict. It checks YAML keys, secure directory modes, mTLS file readability, private-key permissions, and the client certificate SAN/host_id relationship.
6. Run the collector¶
Foreground test:
In another shell:
You should see queue, source, and forwarder state. A healthy forwarder has last_err=none and increasing sent / acked counts once AI-tool activity is observed.
For long-lived use, wrap the same command in your service manager. The collector handles SIGINT and SIGTERM with a graceful shutdown that stops sources, drains accepted envelopes into the queue, and then closes the forwarder and queue.
Example systemd unit:
[Unit]
Description=ARIS collector
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=aris-collector
Group=aris-collector
ExecCondition=/usr/local/bin/aris-collector validate-config --config /etc/aris/collector/collector.yaml
ExecStart=/usr/local/bin/aris-collector run --config /etc/aris/collector/collector.yaml
Restart=on-failure
RestartSec=10s
[Install]
WantedBy=multi-user.target
ExecCondition makes a missing or invalid config skip service start instead of crash-looping. Alerting should treat repeated condition skips as unhealthy during rollout, because systemd does not mark them the same way as a failed ExecStart.
7. Configure AI clients¶
The collector's OTLP receiver listens on loopback by default:
Once the collector is healthy, configure Claude Code on the same host to export to it. The exact environment variables, MDM-distributable settings, and privacy gates are covered in Configure → Claude Code. Leave the receiver on loopback unless you have a specific LAN collection design; LAN binding requires mTLS on the collector's OTLP listener.
VS Code AI extensions such as GitHub Copilot, Codex, Claude Code, Gemini, and Kimi do not need client-side configuration. See Configure → VS Code AI extensions.
Development loopback¶
For local development only, the collector can forward without mTLS to a loopback core endpoint:
This mode only accepts loopback IP literals. It is not for production and cannot be pointed at a hostname or remote address.