trstctl /docs GitHub ↗

Install

trstctl has two binaries you install depending on the role:

  • Control plane (trstctl) — the API, web UI, orchestrator, and event spine. In single-node mode it also supervises the isolated signing service (trstctl-signer) as a child process.
  • Agent (trstctl-agent) — runs inside your network to discover, deploy, and monitor credentials on a host.

Pick the platform you are installing on.

Docker (control plane)

The published image is distroless, unprivileged, and under 80 MB. Run it against your datastores:

docker run --rm -p 8443:8443 \
  -e TRSTCTL_POSTGRES_MODE=external \
  -e TRSTCTL_POSTGRES_DSN='postgres://user:pass@db:5432/trstctl?sslmode=require' \
  -e TRSTCTL_NATS_MODE=external \
  -e TRSTCTL_NATS_URL='nats://nats:4222' \
  ghcr.io/imfeelingtheagi/trstctl:latest

For a self-contained evaluation that brings up Postgres and NATS for you, use the Compose stack from Getting started:

docker compose -f deploy/docker/docker-compose.yml up --build

Verify a published image before you run it — its keyless cosign signature and its CycloneDX SBOM attestation — with the helper:

scripts/verify-image.sh ghcr.io/imfeelingtheagi/trstctl:<tag>

That wraps the underlying cosign check (only an image built by this repo's release workflow verifies):

cosign verify ghcr.io/imfeelingtheagi/trstctl:<tag> \
  --certificate-identity-regexp '^https://github.com/.*/trstctl/.github/workflows/release.yml@.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

See Supply chain for the full signing, SBOM, provenance, and dependency-scanning story.

Kubernetes (control plane via Helm)

The control plane installs with the Helm chart under deploy/helm/trstctl. It deploys the API/UI with the signing service isolated as a locked-down sidecar that has no network listener (it talks to the control plane only over a shared in-memory socket — AN-4), against external PostgreSQL and NATS, behind a default-deny NetworkPolicy, with TLS on by default (R1.3):

helm install trstctl deploy/helm/trstctl \
  --namespace trstctl --create-namespace \
  --set postgres.dsn='postgres://user:pass@pg-host:5432/trstctl?sslmode=require' \
  --set nats.url='nats://nats-host:4222' \
  --set kek.generate=true   # eval only; set kek.existingSecret in production
kubectl -n trstctl rollout status deploy/trstctl
kubectl -n trstctl port-forward svc/trstctl 8443:8443   # https://localhost:8443 (-k)

The release pipeline also publishes the packaged chart as a cosign-signed OCI artifact to GHCR (SUPPLY-007), so you can verify the chart's provenance before installing — the same keyless-OIDC identity that signs the image:

cosign verify ghcr.io/imfeelingtheagi/trstctl/charts/trstctl:<chart-version> \
  --certificate-identity-regexp '^https://github.com/.*/trstctl/.github/workflows/release.yml@.*' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

See deploy/helm/trstctl/README.md for the full values reference. The chart runs the signer co-located (sidecar, over an in-memory UDS) by default; set signer.mode=isolated to run it as a fully separate pod reached over mTLS (TLS 1.3, both-ways certificate pinning, SIGNER-005). A Kubernetes Operator is still planned for S15.1 — see limitations; today the Helm chart is the supported control-plane install.

Kubernetes (agent)

The trstctl agent runs as a DaemonSet so every node is covered. The manifests live under deploy/kubernetes (namespace, RBAC, and the DaemonSet):

kubectl apply -f deploy/kubernetes/namespace.yaml
kubectl apply -f deploy/kubernetes/rbac.yaml
kubectl apply -f deploy/kubernetes/daemonset.yaml

Point the DaemonSet at your control plane and provide its bootstrap token through the referenced secret; see deploy/kubernetes/README.md for the exact env and secret wiring.

Linux (control plane or agent)

Install from a release binary or build from source.

From source (requires Go 1.25+):

git clone https://github.com/imfeelingtheagi/trstctl
cd trstctl
make build           # builds ./bin/trstctl, trstctl-signer, and trstctl-agent
sudo install -m 0755 bin/trstctl /usr/local/bin/trstctl
sudo install -m 0755 bin/trstctl-agent /usr/local/bin/trstctl-agent

Run the agent under systemd so it restarts on failure and on boot. A minimal unit:

# /etc/systemd/system/trstctl-agent.service
[Unit]
Description=trstctl agent
After=network-online.target

[Service]
ExecStart=/usr/local/bin/trstctl-agent
Restart=on-failure
User=trstctl

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now trstctl-agent

macOS (agent)

Build the agent (or download the macOS release) and run it as a launchd agent.

make build
sudo install -m 0755 bin/trstctl-agent /usr/local/bin/trstctl-agent

Create a launchd job at /Library/LaunchDaemons/io.trstctl.agent.plist with a ProgramArguments entry of /usr/local/bin/trstctl-agent and KeepAlive set, then load it:

sudo launchctl load /Library/LaunchDaemons/io.trstctl.agent.plist

The agent installs certificates into the login/keychain destinations you configure and never moves private keys off the host.

Windows (agent)

On Windows the agent runs as a Service Control Manager (SCM) service and installs certificates into the Windows certificate store (CryptoAPI / CNG). Build the MSI:

make dist-windows     # cross-compiles trstctl-agent.exe and packages the MSI

make dist-windows Authenticode-signs both the .exe and the .msi when a code-signing identity is provided (SIGN_PFX/SIGN_PASS); without one it builds them unsigned and says so. The official release pipeline (the agent-windows job in .github/workflows/release.yml) signs them on every version tag and fails the release if either artifact is unsigned, so the published Windows agent is always Authenticode-signed.

Install it (elevated PowerShell):

msiexec /i trstctl-agent.msi /qn

The MSI registers and starts the trstctl-agent service. See deploy/windows/README.md for Authenticode signing and the WiX/msitools build details.

Verify the agent download

Before installing a downloaded agent, authenticate it. On Windows, confirm the Authenticode signature and inspect the signer:

Get-AuthenticodeSignature .\trstctl-agent.msi   # Status must be 'Valid'

On any platform you can also verify the published checksums against the release asset, and (when present) the signature with osslsigncode:

sha256sum -c SHA256SUMS                    # the agent .exe/.msi hashes match the release
osslsigncode verify -in trstctl-agent.msi # reports a valid Authenticode signature

The control-plane and agent container image is additionally cosign-signed; see "Verify a published image" above for scripts/verify-image.sh / cosign verify.

Verify the install

On any platform:

trstctl --version
trstctl -check-config        # prints the effective configuration; non-zero on a bad config

Next: Configuration to point trstctl at your datastores, then Getting started to issue a certificate. To remove trstctl, see Uninstall.

Rendered live from github.com/ctlplne/trstctl — found a mistake? edit this page.