github Institut-du-Numerique-Responsable/perf-sentinel v0.27.0

latest release: chart-v0.27.0
3 hours ago

What's new in v0.27.0

v0.27.0 is about reading behind a key. The daemon can now refuse every read of its query API that comes without one, every reader the binary ships learns to send one, and the CLI signs a terminal in to PerfSentinelHub 0.4.0 to read findings through it. With require_read_key off, the default, the daemon answers, exports and counts as 0.26.2 did, and no detector, normalizer or signature changes.

The daemon can gate its reads

[daemon] require_read_key = true puts every GET and HEAD of the query API behind [daemon] read_api_key, sent as X-API-Key or Authorization: Bearer. Each route also accepts the write key its own handler already takes: [daemon.ack] api_key on the findings, explain, correlations, export, acks, status, config and energy routes, [daemon.incidents] api_key on GET /api/incidents. Without one of them the route answers 401 with the usual error body. Writes keep their own keys and still refuse the read key. /metrics, /health, OTLP ingest and the JSON socket sit outside the query API and stay open, an unknown path stays 404, and CORS preflight requests are answered before the gate.

The configuration refuses to load when the switch is on without a read_api_key (or PERF_SENTINEL_READ_API_KEY), and when it is on alongside [daemon.cors] allowed_origins = ["*"], since the read key is then compared on every request.

Every reader sends the key

perf-sentinel query --api-key-file <PATH> is now a flag of query itself, accepted before or after the subcommand, and the key it resolves (PERF_SENTINEL_DAEMON_API_KEY first, as before) goes on every request. findings, explain, correlations and status gain it, and query inspect now also sends it on the span trees, correlations and report it loads at startup. A read the daemon refuses with 401 exits 1 and names the missing key, where 0.26.2 asked whether perf-sentinel watch was running.

The live HTML report (report --daemon-url) asks for the key when the daemon refuses its /api/status read, then retries the refresh. A viewer who cancels is not asked again in that tab and keeps a readable static report under the badge Authentication required. When a read and a write both answer 401, one prompt opens.

Signing a terminal in to PerfSentinelHub

perf-sentinel login --hub <URL> runs the device flow of PerfSentinelHub 0.4.0 or later. It prints the Hub's /device address and a code to type there in a browser already signed in to the Hub, and opens nothing. The token is stored in $XDG_CONFIG_HOME/perf-sentinel/hub-token.json (else ~/.config/..., %APPDATA% on Windows), one Hub at a time, as a 0600 file in a 0700 directory. A symlinked file, a file other users can read or an expired token is refused before any request. perf-sentinel logout revokes the token on the Hub and deletes the file whatever the Hub answers.

perf-sentinel hub findings|incidents|ack|unack|analyze works through the Hub with the stored token, or with PERF_SENTINEL_HUB_TOKEN for a CI job's machine token. With no credential it sends no Authorization header, so a Hub without access control still answers. A token only travels over https or plain http to loopback, follows no redirect, and never appears on the command line or in an error. hub analyze waits for the run, saves its HTML report, and exits 1 with the run's error_code when the run fails. Text output reuses the query findings and query incidents layouts, and --format json prints the Hub's answer unchanged once it parses as JSON.

Links that follow the repository

The tool.driver.informationUri of every SARIF log, the crate's repository and homepage on crates.io, and the footer of the inspect and query inspect TUI now point at github.com/Institut-du-Numerique-Responsable/perf-sentinel.

verify-hash --verify-binary verifies binaries from either side of the repository transfer. 0.26.2 asked gh attestation verify for --repo robintra/perf-sentinel only, and releases built in the new repository are not attested there. It now tries --repo Institut-du-Numerique-Responsable/perf-sentinel first, then --owner robintra --signer-repo robintra/perf-sentinel, where v0.26.2 and earlier stay attested.

Upgrade impact

  • perf-sentinel-core breaks struct literals of DaemonConfig. The type gains the public field require_read_key and is not #[non_exhaustive], so code that builds it with a literal stops compiling, which is why this release bumps the minor. http_client::send is new, and fetch_with_body keeps its signature and its headers.
  • Turning require_read_key on cuts off every reader without the key. PerfSentinelHub needs AuthHeaderName=X-API-Key and AuthHeaderValue=<read_api_key> on the source, or its poll gets 401 and shows the source unreachable. Grafana datasources, scripts that pipe /api/export/report into perf-sentinel report, and IDEs need it too. Do not turn it on for a daemon that developers' IDEs read until the JetBrains plugin installed there sends a per-endpoint credential: earlier plugin releases send none.
  • A query read refused with 401 prints a different message. It names the missing key instead of asking whether watch is running, so a script that matched the old text needs updating.
  • A SARIF consumer that compares informationUri sees the new value.
  • No finding appears, disappears or changes signature, acknowledgments keep matching, no metric name or wire format changes, the embedded reference data keeps its vintages, and MSRV stays 1.99.0.

Full detail in CHANGELOG.md.

Verifying this release

# Binary integrity via SLSA build provenance attestation (Build Level 2)
gh attestation verify perf-sentinel-linux-amd64 \
  --repo Institut-du-Numerique-Responsable/perf-sentinel

# A periodic disclosure produced by this binary
perf-sentinel verify-hash --report perf-sentinel-report.json \
  --expected-identity "https://github.com/Institut-du-Numerique-Responsable/perf-sentinel/.github/workflows/release.yml@refs/tags/v0.27.0" \
  --expected-issuer "https://token.actions.githubusercontent.com" \
  --verify-binary ./perf-sentinel-linux-amd64

gh CLI 2.49 or newer required for gh attestation verify. Releases up to v0.26.2 were attested under robintra/perf-sentinel and keep their own --repo and identity.

Don't miss a new perf-sentinel release

NewReleases is sending notifications on new releases.