github kj187/jarvis v2.1.0

4 hours ago

What's changed

Recently resolved alerts in the Active list, comment counts and honest data-status notices, plus a broad hardening round for authentication, sessions and requests.

Breaking Changes

  • Jarvis: No breaking changes. The hardening does change behavior for existing installations, so read Upgrading from 2.0.0 before you roll it out: every session expires once and users log in again, logging out signs the account out on every device and replica, Jarvis can no longer be embedded in an <iframe>, and writes (including login and the setup wizard) answer 403 behind a reverse proxy that rewrites the Host header unless JARVIS_ALLOWED_ORIGINS is set.
  • Helm chart 2.2.0: No breaking changes. All new values (networkPolicy.*, image.digest, metrics.token, config.allowedHosts, config.trustedProxies, config.cookieSecure, config.wsMaxConnections, config.resolvedBufferTTL, auth.setupToken) are empty or off by default, so an existing release renders unchanged. The probes now use /health/live and /health/ready, so do not combine this chart with an older image.tag.

Watch the highlights

Jarvis 2.1.0 highlights (video)

A short tour of recently resolved alerts, comment counts, the data-status notices and the hardening work.

Added

  • Recently resolved in the Active list. A new toolbar toggle lists alerts that resolved within the last minutes next to the active ones, with a green "Resolved" label and a soft fill. They never count as active, and the choice is stored with your settings. The window is JARVIS_RESOLVED_BUFFER_TTL (default 20 minutes, config.resolvedBufferTTL in the chart). Requested in #271, thanks to @Matthiator for the proposal.
  • Comment counts on cards, list rows and group headers, loaded with a single request and updated live when a comment is added.
  • Honest data status. A failed first load shows an error with Retry instead of "No alerts", a failed refresh keeps the last data and says so, a stale cluster is flagged with the age of its data, and a live connection that stays down for ten seconds gets a notice. The server now reports lastSuccessfulPollAt and stale per cluster in GET /api/v1/clusters and exports jarvis_cluster_last_success_timestamp_seconds.
  • Alert metadata and fingerprint in the detail sheet.
  • Several SSO admin groups: JARVIS_OIDC_ADMIN_VALUE accepts a comma-separated list, and membership in any one grants the admin role.
  • Helm chart: optional NetworkPolicy, image.digest pinning, cluster headers stored in the chart Secret, and values for the new security settings below.
  • New security settings, all optional: JARVIS_ALLOWED_HOSTS (answers 421 for other Host headers), JARVIS_TRUSTED_PROXIES, JARVIS_COOKIE_SECURE, JARVIS_SETUP_TOKEN for the first admin, JARVIS_METRICS_TOKEN for /metrics, and JARVIS_WS_MAX_CONNECTIONS (default 500 per pod).

Fixed

  • A session now carries the account's token version and is checked against the database, so a logout, a role change or a deleted user takes effect on every replica and survives a restart.
  • Cross-origin writes are rejected, which closes login CSRF, and the security headers are stricter (frame-ancestors, X-Frame-Options: DENY, Referrer-Policy, Permissions-Policy).
  • The first admin is created in one transaction, so concurrent POST /setup requests can no longer create two (#250).
  • Failed logins are slowed down per username, and manual polls (POST /api/v1/poll) are rate-limited and need a login from write_protect upward.
  • Session JWT and OIDC login are hardened, the OIDC exchange is time-boxed, and unverified e-mail addresses no longer block a login.
  • Credentials in cluster URLs are stripped from API responses, silence IDs are validated, upstream reads are capped and composed runbook URLs are checked.
  • Liveness and readiness are split (/health/live, /health/ready), and follower pods report cluster health.
  • PostgreSQL: a blackholed leader steps down within one heartbeat timeout, the follower try-lock gives up at a deadline, a fresh leader keeps the snapshot alerts when Alertmanager is unreachable, and a pool of one connection is raised to two.
  • The WebSocket upgrade accepts the request's own host like HTTP writes do.
  • Release signatures are verified against the exact workflow identity, and make up works on a fresh clone.

Security

  • The image is built with Go 1.27.2 and golang.org/x/net 0.60.0, which fix ten standard-library advisories (net/http, HTTP/2, crypto/tls, mime/multipart) and several in x/net.

Changed

  • Jarvis warns at startup when authentication is disabled.
  • jarvis_snapshot_stale is now set on the leader too when any configured cluster is unreachable.
  • The image is built on Go 1.27.2 and Node 26, base images are pinned by digest, and third-party license notices ship in the image.

Full diff: v2.0.0...v2.1.0


Container image

docker pull ghcr.io/kj187/jarvis:2.1.0

Digest: sha256:da86a47116778776899a47522b780abfe878fa0e49f2b4e4e129fb43e2f2c639

Verify image signature (cosign)

cosign verify ghcr.io/kj187/jarvis@sha256:da86a47116778776899a47522b780abfe878fa0e49f2b4e4e129fb43e2f2c639 \
  --certificate-identity="https://github.com/kj187/jarvis/.github/workflows/release.yml@refs/tags/v2.1.0" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com"

Verify build provenance (GitHub attestation)

gh attestation verify oci://ghcr.io/kj187/jarvis:2.1.0 --repo kj187/jarvis

Helm chart

helm install jarvis oci://ghcr.io/kj187/charts/jarvis --version 2.2.0

Chart changes and breaking changes: charts/jarvis/CHANGELOG.md

Verify chart signature (cosign)

cosign verify ghcr.io/kj187/charts/jarvis:2.2.0 \
  --certificate-identity-regexp='^https://github\.com/kj187/jarvis/\.github/workflows/chart-release\.yml@refs/(heads/main|tags/v[0-9].*)$' \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com"

SBOM

The SPDX SBOM covers the image (OS packages and the Go binary's modules) and the frontend production dependencies. It is attached to this release (sbom.spdx.json) together with its keyless signature bundle (sbom.spdx.json.sigstore.json) and attested to the image digest. The image manifest additionally embeds BuildKit's own SBOM (docker buildx imagetools inspect).

cosign verify-blob sbom.spdx.json \
  --bundle sbom.spdx.json.sigstore.json \
  --certificate-identity="https://github.com/kj187/jarvis/.github/workflows/release.yml@refs/tags/v2.1.0" \
  --certificate-oidc-issuer="https://token.actions.githubusercontent.com"

gh attestation verify oci://ghcr.io/kj187/jarvis@sha256:da86a47116778776899a47522b780abfe878fa0e49f2b4e4e129fb43e2f2c639 \
  --repo kj187/jarvis \
  --signer-workflow kj187/jarvis/.github/workflows/release.yml \
  --predicate-type https://spdx.dev/Document/v2.3

Don't miss a new jarvis release

NewReleases is sending notifications on new releases.