CT-Ops
CT-Ops Agents
Create, configure, install, verify, update, and remove CT-Ops agents.
Agents are the host-side CT-Ops process. They register with ingest, hold a local identity, heartbeat continuously, report host telemetry, run checks, stream inventory, execute approved tasks, and apply agent updates.
How agent enrolment works
- An admin creates an enrolment token in CT-Ops.
- The agent is installed with that token and an ingest address.
- The agent connects to ingest over TLS on
host:9443. - The agent creates or reuses its local identity under
data_dir. - Ingest validates the enrolment token and issues the agent identity.
- If the token is auto-approve, the host becomes active immediately. Otherwise an admin approves it in CT-Ops.
- The agent opens the heartbeat stream and starts sending telemetry.
The enrolment token is only for registration. After registration, the agent uses
its local keypair, certificate material, and JWT state from data_dir.
Create an enrolment token
- Sign in as an administrator.
- Open Administration -> Agents -> Enrolment.
- Click New Token.
- Give the token a label that describes the rollout, such as
production-linuxorbranch-office-servers. - Choose expiry and usage limits that match the rollout window.
- Enable Auto-approve agents only when the token is distributed through a trusted deployment channel.
- Add tags if all hosts installed with the token should start with the same metadata.
- Click Create Token.
- Copy the generated agent join details immediately. CT-Ops does not show the full token value again.
After the token is created, CT-Ops provides both:
- a full agent join URL that already includes the ingest host and enrolment token, intended to be copied from CT-Ops and pasted directly into the target host
- the plain enrolment token, for operators who prefer to manually type or script the join command and supply the ingest address themselves
Use the full URL for normal manual installs because it avoids transcription
errors. Use the plain token only when your deployment tooling already controls
the target ingest address or you are building a custom ct-ops-agent --install
command.
Use short-lived, single-use or low-use tokens for manual installs. Use longer-lived tokens only for controlled automation where the token can be protected and revoked.
Installation methods
| Method | Best for | Notes |
|---|---|---|
| One-command installer | Connected Linux and macOS hosts | Downloads the right binary from CT-Ops and runs --install. |
| Offline install bundle | Air-gapped, change-controlled, or Windows installs | Includes binary, config template, checksum, and install script. |
| Manual binary install | Development or custom packaging | You provide the binary and run ct-ops-agent --install. |
| Development foreground run | Local testing | Runs the agent in a terminal without creating a service. |
Debian and Ubuntu
The built-in Linux installer works on Debian-based systems that use systemd.
sudo apt-get update
sudo apt-get install -y ca-certificates curl
export CT_OPS_ENROLMENT_TOKEN="<token-from-ui>"
curl -fsSL "https://ct-ops.example.com/api/agent/install" | sh
When ingest is not on the default address inferred by CT-Ops, download the
binary and install manually with --address.
export CT_OPS_ENROLMENT_TOKEN="<token-from-ui>"
curl -fsSL "https://ct-ops.example.com/api/agent/download?os=linux&arch=amd64" -o ct-ops-agent
chmod +x ct-ops-agent
sudo -E ./ct-ops-agent --install --address "ct-ops.example.com:9443"
The installer writes:
| Path | Purpose |
|---|---|
/usr/local/bin/ct-ops-agent | Agent binary. |
/etc/ct-ops/agent.toml | Agent configuration, mode 0600. |
/var/lib/ct-ops/agent | Agent identity and runtime state. |
/etc/systemd/system/ct-ops-agent.service | systemd unit. |
Check the service:
systemctl status ct-ops-agent
journalctl -u ct-ops-agent -f
Red Hat, RHEL, Rocky, AlmaLinux, Fedora
The agent uses the same systemd install path on Red Hat based distributions.
sudo dnf install -y ca-certificates curl
export CT_OPS_ENROLMENT_TOKEN="<token-from-ui>"
curl -fsSL "https://ct-ops.example.com/api/agent/install" | sh
On older hosts that use yum:
sudo yum install -y ca-certificates curl
If SELinux policy or local hardening blocks service startup, confirm the binary and config paths are readable by root and inspect the audit log. The default agent service runs as root because checks, package inventory, service tasks, patch status, and process actions may need host-level privileges.
Windows
Use the offline install bundle for Windows because the /api/agent/install
shell endpoint is for Unix-like hosts.
- In CT-Ops, open Administration -> Agents -> Enrolment.
- Click Download Install Bundle.
- Select
windowsand the target architecture, usuallyamd64. - Choose whether to embed a token or require the operator to provide
CT_OPS_ENROLMENT_TOKEN. - Download and transfer the zip to the Windows host.
- Open PowerShell as Administrator.
- Extract the zip and run:
.\install.ps1
If the bundle does not embed a token:
$env:CT_OPS_ENROLMENT_TOKEN = "<token-from-ui>"
.\install.ps1
The Windows installer writes:
| Path | Purpose |
|---|---|
C:\Program Files\ct-ops\ct-ops-agent.exe | Agent binary. |
C:\ProgramData\ct-ops\agent.toml | Agent configuration. |
C:\ProgramData\ct-ops\agent | Agent identity and runtime state. |
CtOpsAgent | Windows Service Control Manager service. |
Application Event Log provider CtOpsAgent | Agent service logs. |
Check the service:
sc.exe query CtOpsAgent
Get-WinEvent -LogName Application -FilterXPath "*[System/Provider/@Name='CtOpsAgent']" -MaxEvents 20
Agent command-line options
| Option | Applies to | Detail |
|---|---|---|
-config <path> | normal run | Path to TOML config. Default on Unix is /etc/ct-ops/agent.toml; Windows service install uses C:\ProgramData\ct-ops\agent.toml. |
--install | install mode | Installs the current binary as an OS service, writes config, starts the service, then exits. Requires --token or CT_OPS_ENROLMENT_TOKEN. |
--uninstall | uninstall mode | Stops and removes the service, binary, config, and data files for the current OS. Requires root or Administrator. |
--token <token> | install or normal run | Enrolment token. Overrides config and CT_OPS_ENROLMENT_TOKEN. |
--address <host:port> | install or normal run | Ingest gRPC address. Overrides config and CT_OPS_INGEST_ADDRESS. IPv6 must be bracketed, for example [2001:db8::10]:9443. |
--tls-skip-verify | install or normal run | Disables TLS certificate verification. Development only. |
--tag <key=value> | install or normal run | Applies a registration tag. Repeat for multiple tags. key:value is also accepted. |
--version, -v | any | Prints the agent version and exits. |
Do not use --tls-skip-verify in production. Prefer a proper certificate or
ca_cert_file.
Agent TOML reference
The installed config is TOML. On Linux it is /etc/ct-ops/agent.toml; on
Windows it is C:\ProgramData\ct-ops\agent.toml.
[ingest]
address = "ct-ops.example.com:9443"
ca_cert_file = ""
tls_skip_verify = false
[agent]
enrolment_token = ""
data_dir = "/var/lib/ct-ops/agent"
heartbeat_interval_secs = 30
tags = ["environment=production", "role=web"]
| TOML key | Default | Detail |
|---|---|---|
ingest.address | localhost:9443 | Host and port of the CT-Ops ingest gRPC service. This is not a URL and must not include https://. |
ingest.ca_cert_file | empty | PEM certificate file used to verify ingest TLS. Leave empty when ingest uses a publicly trusted certificate. Set this for private CA or self-signed deployments. |
ingest.tls_skip_verify | false | Disables TLS verification. Use only for temporary development. |
agent.enrolment_token | empty | Token used for registration. It can be omitted after the agent has registered, but keeping it may allow re-registration if the host record is deleted and the token is still valid. |
agent.data_dir | /var/lib/ct-ops/agent | Directory where the identity keypair, server cert pinning state, and JWT state are stored. Back it up only as part of whole-host recovery; do not copy it to another host. |
agent.heartbeat_interval_secs | 30 | Normal heartbeat cadence. Very low values increase ingest and database load. |
agent.tags | empty | Tags applied during registration. Entries may use key=value or key:value. |
On Unix, the agent refuses to read a config that grants group or other access, and it must be owned by the user running the process, normally root.
Environment overrides
| Environment variable | Overrides |
|---|---|
CT_OPS_INGEST_ADDRESS | ingest.address |
CT_OPS_INGEST_CA_CERT | ingest.ca_cert_file |
CT_OPS_ENROLMENT_TOKEN | agent.enrolment_token |
CT_OPS_DATA_DIR | agent.data_dir |
Command-line flags override both config and environment values where a matching flag exists.
Tags and global agent options
Agent tags can come from enrolment-token tags, install-bundle tags,
agent.tags in TOML, repeated --tag flags, instance-wide defaults, and tag
rules configured in CT-Ops.
Use global defaults for metadata every host should receive, such as business unit or deployment environment. Use enrolment-token or bundle tags for rollout-specific values, such as site, cluster, or owner. Use host-specific tags only when the value truly differs per machine.
Global agent behavior is managed from the CT-Ops administration pages, including enrolment tokens, agent defaults, tag settings, and software inventory settings. Those settings are enforced by CT-Ops after registration and are separate from the local TOML file.
Manual development run
For local development, build the binary and run it in the foreground.
make agent
cp agent/examples/agent.toml /tmp/agent.toml
Edit /tmp/agent.toml.
[ingest]
address = "localhost:9443"
ca_cert_file = "deploy/dev-tls/server.crt"
[agent]
enrolment_token = "YOUR_ENROLMENT_TOKEN"
data_dir = "/tmp/ct-ops-agent"
heartbeat_interval_secs = 30
Run:
./dist/agent -config /tmp/agent.toml
Expected log lines include agent identity ready, registration response, and
heartbeat stream opened.
Verify in CT-Ops
Open Hosts after installation.
| State | Meaning | Action |
|---|---|---|
| Online | Agent is approved and heartbeating. | No action needed. |
| Pending | Agent registered but token did not auto-approve. | Approve it from the pending panel. |
| Offline | Agent has stopped heartbeating or cannot connect. | Check service status, logs, network reachability, and ingest health. |
Useful host-side checks:
systemctl status ct-ops-agent
journalctl -u ct-ops-agent -n 200
nc -vz ct-ops.example.com 9443
curl -vk https://ct-ops.example.com/api/agent/latest
sc.exe query CtOpsAgent
Get-WinEvent -LogName Application -FilterXPath "*[System/Provider/@Name='CtOpsAgent']" -MaxEvents 50
Test-NetConnection ct-ops.example.com -Port 9443
Invoke-WebRequest https://ct-ops.example.com/api/agent/latest
Updates
The agent reports its version during heartbeat. CT-Ops and ingest use the server-side latest-version endpoint to determine whether an update is available. When an update is applied, the service manager restarts the agent so it re-execs the updated binary.
Keep AGENT_DOWNLOAD_BASE_URL correct and reachable from agents. A bad download
URL prevents self-update even when heartbeats continue to work.
Uninstall
Linux:
sudo /usr/local/bin/ct-ops-agent --uninstall
Windows, from elevated PowerShell:
& "C:\Program Files\ct-ops\ct-ops-agent.exe" --uninstall
Uninstall removes the service, binary, config, and local data. Removing local data also removes the agent identity; reinstalling later creates a new identity and requires a valid enrolment token.