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

  1. An admin creates an enrolment token in CT-Ops.
  2. The agent is installed with that token and an ingest address.
  3. The agent connects to ingest over TLS on host:9443.
  4. The agent creates or reuses its local identity under data_dir.
  5. Ingest validates the enrolment token and issues the agent identity.
  6. If the token is auto-approve, the host becomes active immediately. Otherwise an admin approves it in CT-Ops.
  7. 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

  1. Sign in as an administrator.
  2. Open Administration -> Agents -> Enrolment.
  3. Click New Token.
  4. Give the token a label that describes the rollout, such as production-linux or branch-office-servers.
  5. Choose expiry and usage limits that match the rollout window.
  6. Enable Auto-approve agents only when the token is distributed through a trusted deployment channel.
  7. Add tags if all hosts installed with the token should start with the same metadata.
  8. Click Create Token.
  9. 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

MethodBest forNotes
One-command installerConnected Linux and macOS hostsDownloads the right binary from CT-Ops and runs --install.
Offline install bundleAir-gapped, change-controlled, or Windows installsIncludes binary, config template, checksum, and install script.
Manual binary installDevelopment or custom packagingYou provide the binary and run ct-ops-agent --install.
Development foreground runLocal testingRuns 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:

PathPurpose
/usr/local/bin/ct-ops-agentAgent binary.
/etc/ct-ops/agent.tomlAgent configuration, mode 0600.
/var/lib/ct-ops/agentAgent identity and runtime state.
/etc/systemd/system/ct-ops-agent.servicesystemd 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.

  1. In CT-Ops, open Administration -> Agents -> Enrolment.
  2. Click Download Install Bundle.
  3. Select windows and the target architecture, usually amd64.
  4. Choose whether to embed a token or require the operator to provide CT_OPS_ENROLMENT_TOKEN.
  5. Download and transfer the zip to the Windows host.
  6. Open PowerShell as Administrator.
  7. 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:

PathPurpose
C:\Program Files\ct-ops\ct-ops-agent.exeAgent binary.
C:\ProgramData\ct-ops\agent.tomlAgent configuration.
C:\ProgramData\ct-ops\agentAgent identity and runtime state.
CtOpsAgentWindows Service Control Manager service.
Application Event Log provider CtOpsAgentAgent service logs.

Check the service:

sc.exe query CtOpsAgent
Get-WinEvent -LogName Application -FilterXPath "*[System/Provider/@Name='CtOpsAgent']" -MaxEvents 20

Agent command-line options

OptionApplies toDetail
-config <path>normal runPath to TOML config. Default on Unix is /etc/ct-ops/agent.toml; Windows service install uses C:\ProgramData\ct-ops\agent.toml.
--installinstall modeInstalls the current binary as an OS service, writes config, starts the service, then exits. Requires --token or CT_OPS_ENROLMENT_TOKEN.
--uninstalluninstall modeStops and removes the service, binary, config, and data files for the current OS. Requires root or Administrator.
--token <token>install or normal runEnrolment token. Overrides config and CT_OPS_ENROLMENT_TOKEN.
--address <host:port>install or normal runIngest gRPC address. Overrides config and CT_OPS_INGEST_ADDRESS. IPv6 must be bracketed, for example [2001:db8::10]:9443.
--tls-skip-verifyinstall or normal runDisables TLS certificate verification. Development only.
--tag <key=value>install or normal runApplies a registration tag. Repeat for multiple tags. key:value is also accepted.
--version, -vanyPrints 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 keyDefaultDetail
ingest.addresslocalhost:9443Host and port of the CT-Ops ingest gRPC service. This is not a URL and must not include https://.
ingest.ca_cert_fileemptyPEM 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_verifyfalseDisables TLS verification. Use only for temporary development.
agent.enrolment_tokenemptyToken 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/agentDirectory 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_secs30Normal heartbeat cadence. Very low values increase ingest and database load.
agent.tagsemptyTags 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 variableOverrides
CT_OPS_INGEST_ADDRESSingest.address
CT_OPS_INGEST_CA_CERTingest.ca_cert_file
CT_OPS_ENROLMENT_TOKENagent.enrolment_token
CT_OPS_DATA_DIRagent.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.

StateMeaningAction
OnlineAgent is approved and heartbeating.No action needed.
PendingAgent registered but token did not auto-approve.Approve it from the pending panel.
OfflineAgent 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.