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.