Installation
Installation
Install script
The primary channel. Works on macOS and Linux, including servers where Homebrew does not belong.
curl -fsSL https://raw.githubusercontent.com/cboxdk/telemetryd/main/install.sh | sh
It detects your platform, downloads the matching release, verifies the SHA-256
checksum and refuses to install on a mismatch, and places the binary in the first
writable directory on your PATH.
It never invokes sudo. If the target directory is not writable it prints the exact
command to run instead — a tool that silently escalates is one you cannot reason about.
Overrides:
TELEMETRYD_VERSION=0.20.9 sh install.sh
TELEMETRYD_INSTALL_DIR="$HOME/.local/bin" sh install.sh
Homebrew
brew install cboxdk/tap/telemetryd
The formula is generated from a published release by
scripts/publish-formula.py, so it can only ever describe a build that exists. It
carries the release's own checksums and Homebrew verifies them on install.
Debian and Ubuntu
Download the .deb for your architecture from the
releases page and install it:
sudo dpkg -i telemetryd_0.20.9_amd64.deb
sudo systemctl enable --now telemetryd
The package creates an unprivileged telemetryd user, a state directory at
/var/lib/telemetryd, and a hardened systemd unit.
There is no hosted apt repository, deliberately. Running one means running signing infrastructure and keeping it available; for a project at this scale a signed release asset carries the same guarantee with far less that can quietly break. Stated here rather than left as a gap you discover.
Verifying a release
Every release publishes SHA256SUMS and SHA256SUMS.cosign.bundle, a keyless
Sigstore signature over it, in the standardised bundle format
that cosign 2.4+, sigstore-python and sigstore-go all read. There is no public key to
fetch or trust on first use: the signing identity is the release workflow itself,
attested by GitHub's OIDC provider and recorded in the public transparency log.
Getting a verifier
install.sh verifies automatically when cosign is on your PATH, and says so when it
is not — which on a server is most of the time. Ubuntu and Debian do not package
cosign; apt-get install cosign fails, which is where most people stop.
Two ways to get one. Sigstore's own .deb, checked before it is installed:
cd /tmp
curl -fsSLO https://github.com/sigstore/cosign/releases/download/v3.1.3/cosign_3.1.3_arm64.deb
curl -fsSL https://github.com/sigstore/cosign/releases/download/v3.1.3/cosign_checksums.txt \
| grep 'cosign_3.1.3_arm64.deb$' | sha256sum -c -
sudo apt-get install -y ./cosign_3.1.3_arm64.deb
sha256sum -c fails and stops the chain if the download does not match, so apt-get
only ever sees a file that checked out. Swap arm64 for amd64 on an Intel host.
Or, without leaving Python — this verifies the same bundle, and needs no binary from another project's releases:
pipx install sigstore # or: pip install sigstore
python -m sigstore verify identity \
--bundle SHA256SUMS.cosign.bundle \
--cert-identity "https://github.com/cboxdk/telemetryd/.github/workflows/release.yml@refs/tags/v0.42.0" \
--cert-oidc-issuer "https://token.actions.githubusercontent.com" \
SHA256SUMS
This works from v0.42.0 onward. Earlier releases were signed into cosign's own older
envelope, which only cosign reads — sigstore-python rejects it as malformed, and that
is a statement about the format rather than about the file. cosign verifies every release,
old and new.
Whichever you install, you cannot verify the verifier. The checksum above protects against a corrupted or swapped download, not against the upstream release itself being bad. That is the bootstrap problem and it has no clean answer; it is worth knowing rather than assuming the chain closes all the way down.
By hand
To check with cosign:
cosign verify-blob \
--bundle SHA256SUMS.cosign.bundle \
--certificate-identity "https://github.com/cboxdk/telemetryd/.github/workflows/release.yml@refs/tags/v0.20.9" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
SHA256SUMS
Then check the archive against the verified checksums:
sha256sum --check --ignore-missing SHA256SUMS
Pin --certificate-identity. Without it, cosign accepts any valid Sigstore
signature — including one made by someone else entirely. The identity is what ties
the signature to this repository's release workflow at that tag.
The checksum file alone proves your download was not corrupted in transit. It comes from the same server as the archive, so on its own it says nothing about who produced it; the signature is what does that.
From source
git clone https://github.com/cboxdk/telemetryd
cd telemetryd
cargo build --release
Needs Rust 1.89+ and nothing else — there are no C dependencies in the tree.
Verifying what you got
telemetryd version
Prints the version, the storage format version, and the build target — which is the first question in any "it works on my machine" report about a static binary.
Every release also publishes SHA256SUMS and sbom.json, a CycloneDX 1.5 manifest of
everything linked into the binary.
Signing
Not yet in place. Releases carry checksums, which protect against a corrupted download but not against a compromised release. Named here as a known gap rather than implied to be covered by an unsigned checksum file. \n
Is there a newer one?
telemetryd version --check
Prints what you are running, then asks GitHub for the newest release and says which of the two is ahead. It is the only code path in telemetryd that contacts anything outside your infrastructure, and it runs only when you ask — no background timer, no line in the server log, nothing on start-up. A binary whose pitch is that your telemetry stays put should not be phoning anywhere on its own.
Being offline is not an error: the check says it could not reach the feed and the
command still exits 0, so putting it in a script does not make the script fail on a
box without egress.
Hand this to an agent
A self-contained brief. It names only commands and endpoints that exist, so an agent can execute it without reading the rest of this page — and without inventing the parts of the Loki and Prometheus APIs telemetryd deliberately does not implement.
# Task: install telemetryd on this machine and prove it works
telemetryd is a single statically linked binary. No runtime, no libc to match, no
sidecar, no collector. Do not install a package manager, a container runtime, or an
OpenTelemetry Collector — none is needed.
## Install
```bash
curl -fsSL https://raw.githubusercontent.com/cboxdk/telemetryd/main/install.sh | sh
```
The installer verifies the release checksum and refuses to install on a mismatch. On
macOS, `brew install cboxdk/tap/telemetryd` is equivalent.
## Run
```bash
telemetryd serve
```
That is the whole setup: no configuration file and no flags. It listens on
`127.0.0.1:4319`, stores data in `./telemetryd-data` or the platform data directory,
keeps 7 days of logs and traces and 30 days of metrics, and stays under a 10 GiB budget.
**It will refuse to start if you bind a non-loopback address with no token configured.**
That is deliberate, not a bug. Either keep it on loopback, or set
`TELEMETRYD_AUTH_INGEST_TOKEN` and `TELEMETRYD_AUTH_QUERY_TOKEN`.
## Prove it works — do all three
1. `curl -fsS http://127.0.0.1:4319/healthz` returns `ok`.
2. Send one record and read it back:
```bash
curl -X POST http://127.0.0.1:4319/v1/logs -H 'Content-Type: application/json' -d '{
"resourceLogs": [{"resource": {"attributes": [
{"key": "service.name", "value": {"stringValue": "smoke"}}]},
"scopeLogs": [{"logRecords": [{
"timeUnixNano": "'"$(date +%s)000000000"'",
"severityNumber": 17, "severityText": "ERROR",
"body": {"stringValue": "hello from the install check"}}]}]}]}'
curl -G http://127.0.0.1:4319/loki/api/v1/query_range \
--data-urlencode 'query={app="smoke"} |= "hello"'
```
The query must return the line the send step created. If it returns an empty result,
the write failed — check the response body of the POST rather than retrying.
3. `telemetryd validate` prints every resolved setting and where it came from.
## Do not
- Do not add a reverse proxy or TLS unless the port must be reachable from another
machine. On loopback it buys nothing.
- Do not write a configuration file to change defaults you have not measured a need
for. Every setting is also an environment variable, `TELEMETRYD_<SECTION>_<KEY>`.