Skip to content

Releases

v0.17.0: hosts over SSH, an installer and a live demo

Choose a tag to compare

@github-actions github-actions released this 11 Nov 20:12
v0.17.0
91ce2c4

Linux hosts over SSH with nothing installed on them, binaries and a one-line installer for servers without Docker, and a live demo that runs in the browser. Nothing changes for an existing installation until you add a host.

Added

  • SSH hosts: add any Linux machine by its address and a user in Settings → SSH hosts. dash signs in with its own key, runs one fixed read-only script and shows the machine on the new Hosts page: live CPU, memory, network and disk charts, temperatures and fans, file systems, disks and ZFS pools, containers (docker or podman) and systemd services. A full file system, a failed unit, a pool that is not online and a host that went away become attention items on the Overview. Nothing is installed on the host, dash holds no password and never writes there (the SSH hosts page).
  • Pinned host keys: dash connects to a host only after an administrator has trusted the fingerprint it shows, and refuses a host whose key changed. Hosts set in the config file carry their key as hostKey.
  • Release binaries: every release now has dash_<version>_<os>_<arch>.tar.gz for Linux and macOS on amd64 and arm64, a checksum file and a build provenance attestation.
  • Installer: curl -fsSL https://dash.techdufus.com/install.sh | sudo sh installs the binary as a hardened systemd service, creates its secret key and prints the setup link. Run it again to upgrade (the binary guide).
  • Live demo: the live demo is the real web UI on recorded demo data, hosted as static files. It is read-only; the container's demo mode still answers actions.
  • Getting started: an Overview with nothing connected yet points administrators at adding a host.

Security

  • SSH hosts need DASH_SECRET_KEY and a writable data directory: dash's SSH private key is sealed with it in credentials.yaml. Give dash a dedicated unprivileged user on each host and add its key with restrict. The security model and ADR 0003 say what dash runs, what it stores and what viewers see.

Upgrade notes

  • No step needed. The ssh plugin stays off until plugins.ssh.hosts names a host.
  • Rolling back after adding hosts: remove plugins.ssh from the config file and unset every DASH_PLUGINS_SSH_* variable first, since an older release refuses a key or a variable it does not know. The older release drops dash's SSH key at its next write of credentials.yaml, so after upgrading again every host needs the new public key.

v0.16.1: usage figures stay in their cards

Choose a tag to compare

@TechDufus TechDufus released this 11 Nov 04:42
v0.16.1
3ade973

The Hardware page's memory and root-disk figures stay inside their cards, and dash is built with Go 1.27.4 for a net/http security fix. A patch; nothing to change.

Fixed

  • Hardware fleet cards: in a narrow card, a machine's "used / total %" memory and root-disk figures ran past the card's edge. They now wrap (the percentage first, then the total) and never split a number from its unit. The same holds for every usage bar in dash.

Security

  • Go 1.27.4: fixes GO-2026-6859, an HTTP/1 server crash from a header race in net/http's MaxBytesReader, which dash's server and clients reach.

Upgrade notes

  • No step needed. Rolling back to v0.16.0 is safe, but brings the vulnerable Go back.

v0.16.0: Hardware fleet

Choose a tag to compare

@TechDufus TechDufus released this 10 Nov 20:53
v0.16.0
c441dd3

The Hardware page now shows every machine you run (#47): any number of Proxmox hosts with their full hardware detail, and machines outside Proxmox with their node-exporter figures. A minor release: hardware.hosts and the hardware attention ids change shape; one-host settings keep working.

New

  • Several Hardware hosts. plugins.hardware.hosts takes any number of hosts, each read by its nodename (its node-exporter nodename and, in a Proxmox cluster, its node). Each keeps its own bays, fan scale, sensors, pools, disks, links and Proxmox facts.
  • Hardware page:
    • a fleet grid with a card per host (health, CPU, memory, power, CPU temperature, pools, disks) and per machine;
    • the full detail of the host you pick below it, at /hardware/<host>;
    • machine cards with node-exporter stats: OS and architecture, CPU, memory, root disk, load, uptime and, where the machine reports one, its temperature (macOS memory as Activity Monitor counts it);
    • machines checked through Gatus show up or down.
  • Overview: the power KPI sums the hosts, cpuTemp is the hottest package, and each topology host carries its own power, temperature and health.
  • Attention: pool, scrub, SMART and CPU-temperature items name their host and open its page.
  • Series: host.* take a host as node; without one, host.power is the sum, host.cpuTemp the hottest, and the others draw one line per host.
  • VM sheet: links to the Hardware page of the VM's own host.

Upgrade notes

  • Settings: nothing to change for one host. To add hosts, give each a nodename; at most one may leave it empty (it takes plugins.proxmox.node). Names and nodenames must be unique, ignoring case. A host whose nodename is a node of the Proxmox cluster is that node (its Proxmox facts, shell link and place in the topology) whatever plugins.proxmox.node says, so a cluster whose hosts all have a nodename no longer needs that setting.
  • A host without name is called by its nodename (before: its Proxmox node). Where the two differ, its name, refs and attention ids change.
  • API and clients:
    • hardware.hosts is {hosts: [...]} (one HostData per host, [] when none is configured) instead of one object; each host has health;
    • attention ids carry the host (zfs:pool:<host>/<pool>, zfs:scrub:<host>/<pool>, smart:<host>/<bay>, host:cpu-temp:<host>); acknowledgements of the old ids do not carry over;
    • an unknown host in a host.* series is a 404;
    • node-exporter machines carry stats.
  • Rolling back to v0.15.0: keep one host in plugins.hardware.hosts; v0.15.0 refuses several.

See docs/upgrading.md.

v0.15.0: Proxmox clusters

Choose a tag to compare

@TechDufus TechDufus released this 10 Nov 14:41
v0.15.0
c305ef1

dash now reads your whole Proxmox VE cluster through its one Proxmox connection (#46): every node, the cluster's quorum, totals, and every guest and storage on its own node. A minor release: some payloads change shape; the settings do not.

New

  • Clusters through one connection. dash asks whichever node plugins.proxmox.url reaches for the whole cluster. A standalone server is a cluster of one.
  • VMs page:
    • a cluster summary: name, quorum, nodes online, and the CPU, memory and storage totals of the online nodes;
    • a card per node: its state, CPU, memory, uptime, Proxmox VE version, CPU model and guests;
    • each VM and template shows its node, and the activity table has a Node column.
  • Per-VM calls go to the right node. A VM's detail and console use its own node, follow a guest that just migrated, and answer at once for a guest of an offline node.
  • Storage: every node's storages, a shared one (NFS, Ceph) listed and counted once, with totals.
  • Overview: the topology draws one host per node, each VM under its node.
  • Attention: an offline node and a cluster that lost quorum are critical items.
  • Hardware page: the Proxmox facts of the host's own node.

Upgrade notes

  • Settings: nothing to change. plugins.proxmox.node no longer chooses what dash reads; it names the node the Hardware page's host is. A cluster of several nodes no longer needs it for the plugin to run, but its Hardware page does (or plugins.hardware.hosts[0].nodename).
  • Token: the cluster's name and quorum need Sys.Audit on / (PVEAuditor on / has it). Without it everything else works and the quorum reads as unknown.
  • API and clients:
    • proxmox.node is replaced by proxmox.cluster;
    • VMs and tasks carry node;
    • storage refs carry the node (proxmox:Storage/<node>/<name>; a shared one is proxmox:Storage/<name>);
    • core.overview's topology has hosts (one per node) instead of host.
  • Rolling back to v0.14.11: no settings change, but a cluster of several nodes then needs plugins.proxmox.node again.

See docs/upgrading.md.

v0.14.11: dash is public

Choose a tag to compare

@TechDufus TechDufus released this 06 Nov 18:16
v0.14.11
c8bffbc

dash is now public (#42). This is its first release published for everyone: a multi-arch image and the Helm chart on GHCR, with provenance and an SBOM attached and the image signed by cosign. It is a patch with no behaviour change; you can now install dash without building it.

New

  • Images on GHCR: ghcr.io/techdufus/dash for linux/amd64 and linux/arm64, tagged 0.14.11 and 0.14. Releases are create-only: a published version is never overwritten.

    docker run -p 8080:8080 -e DASH_DEMO=true -e DASH_SERVER_LISTEN=0.0.0.0:8080 ghcr.io/techdufus/dash:0.14.11
  • Helm chart on GHCR:

    helm install dash oci://ghcr.io/techdufus/charts/dash --version 0.14.11
  • Supply chain:

    • the image is signed keyless with cosign;
    • BuildKit provenance and an SBOM are attached;
    • GitHub build-provenance and SBOM attestations are published (gh attestation verify).

    See docs/security.md.

  • Site: a landing page at https://dash.techdufus.com.

  • Docs: the install guides use the published image and chart.

Fixed

  • A replaced credentials.yaml is always noticed. A credentials.yaml restored or replaced while dash runs was not always detected on filesystems that reuse inode numbers (ext4), so dash could write over a restored file. dash now keeps the file it last read or wrote open, so its identity can't be reused (#43).

Upgrade notes

  • No change for existing installs. If you built the image yourself before, switch to the published one, pinned by digest.

v0.14.10

Choose a tag to compare

@TechDufus TechDufus released this 06 Nov 08:53
v0.14.10
97c51ba

AI agents can now act on your lab, with your approval (#40). This release adds MCP action tools that wait for a person to approve them, the approval page and its notifications, and the guides for the Android app and MCP clients. It is a patch; with MCP off (the default) nothing changes.

New

  • Action tools for agents. With MCP on, an administrator's mcp token holding actions:<plugin> sees that plugin's actions as tools: kubernetes_restart, flux_reconcile, alertmanager_silence_create and alertmanager_silence_expire. They are listed only while the plugin is running.
  • Human approval:
    • an agent's call creates an approval request, and the agent gets a link to give you;
    • you open /approve/<id> (or the new header indicator), check the action, its target and full input, and approve or deny;
    • a protected target needs you to type its name, and the agent can never supply it;
    • the action runs once, as the requesting agent, after re-checking its token, role and scope;
    • the agent reads the outcome with dash_approval, or waits for it through URL elicitation on MCP 2026-07-28;
    • requests expire after 10 minutes, and each user can have at most 20 pending.
  • Approval notifications: a pending-approvals badge in the header, and a push to your devices that take approvals (v0.14.9).
  • Per-plugin agent policy: plugins.<id>.actions.agents, also in Settings → MCP:
    • approve (default): every call waits for you;
    • allow: runs at once, except protected targets;
    • deny: hides the tools.
  • Audit: every request, decision and run, with the requester, the approver, the target and a hash of the arguments, never their free text.
  • Guides:
    • docs/agents/mcp.md: Claude Code with a token, Claude Desktop and claude.ai through OAuth, VS Code, omp;
    • docs/agents/dash-skill/SKILL.md: an agent skill for using dash;
    • docs/clients/android.md: the contract for the coming Android app.
  • Inputs: action inputs describe themselves (required fields, allowed kinds), and silence matchers are capped in length.

Upgrade notes

  • No step needed. If you turned MCP on, an existing mcp token holding actions:<plugin> now sees that plugin's action tools, and its calls create approval requests (the approve default).

  • Rolling back to v0.14.9:

    • remove plugins.<id>.actions.agents from the config file and unset DASH_PLUGINS_<ID>_ACTIONS_AGENTS; v0.14.9 refuses both;
    • a value saved in the settings page only warns;
    • pending approvals are kept in memory and are lost at any restart.

    See docs/upgrading.md.

v0.14.9

Choose a tag to compare

@TechDufus TechDufus released this 06 Nov 05:48
v0.14.9
31c2904

dash can now notify your devices (#39). This release adds Web Push for the installed web app, UnifiedPush for the coming Android app, and attention notifications. It is a patch, and push is unavailable until dash has a writable data dir and DASH_SECRET_KEY.

New

  • Settings → Devices. "Subscribe this browser" registers the installed web app or a browser for push.
    • The device proves it can receive pushes with an 8-character code, which the page submits by itself.
    • Each device chooses its alerts: approvals, and attention at critical, warning or off.
    • It can send itself a test push.
    • Administrators can see and remove every user's devices.
    • A QR code holds the server address for the Android app (not released yet).
  • Attention notifications:
    • an attention item at or above a device's threshold that lasts 2 minutes sends one push;
    • an item escalating from warning to critical reaches critical-only devices;
    • an item pushes again only after it clears and returns;
    • at most 30 attention pushes per user per hour, with one summary for the rest.
  • One sender for Web Push and UnifiedPush:
    • RFC 8291 encryption and RFC 8292 VAPID, built on the Go standard library;
    • endpoints must be https and resolve to global addresses, checked at dial time; push.allowPrivate admits a LAN ntfy;
    • no redirects, retries with backoff;
    • fair limits per device, per user and per push service.
  • Devices follow your sessions.
    • A browser device stops receiving pushes when you log out, and comes back by itself the next time you sign in on it.
    • The Android app's device follows its OAuth grant.
    • Endpoints and keys are stored encrypted and never logged.
  • Installed web app: the service worker shows notifications and opens them only on dash's own origin.

Upgrade notes

  • Nothing to change. Without a writable data dir and DASH_SECRET_KEY, push stays off, and one INFO line at start says what is missing. Push also needs push.contact or an https server.publicURL.
  • Rolling back to v0.14.8: remove push: from the config file (the older release refuses the unknown key). v0.14.8 keeps tokens and grants and drops the push data at its next write, so devices subscribe again after a later upgrade. See docs/upgrading.md.

v0.14.8

Choose a tag to compare

@TechDufus TechDufus released this 06 Nov 03:59
v0.14.8
f71fc7c

dash can now be read by AI agents (#38). This release adds a read-only MCP server, context bundles, and "Copy context for AI". It is a patch and MCP is off by default: nothing changes until you set mcp.enabled.

New

  • MCP server at /mcp (Streamable HTTP, protocol versions 2026-07-28 and 2025-11-25), switched on and off live with mcp.enabled or in Settings → MCP.

    • Access: only bearer tokens with audience mcp: personal access tokens, static tokens, or OAuth grants.
    • Tools: dash_overview, dash_search, dash_get, dash_topic, dash_series, dash_logs (needs logs) and dash_context.
    • Resources: every topic you may read, with subscriptions.
    • Prompts: four (triage, investigate, daily digest, explain an alert).
    • Read-only: there are no action tools in this release.
  • Untrusted lab data: every result keeps logs, events, annotations and object names inside one fenced block, after a sentence telling the agent to treat it as data. Results are scrubbed of secrets and capped at 64 KiB.

  • Limits:

    • per token: 120 calls a minute (30 for logs), 8 in flight, 2 listen streams;
    • per user: 16 calls in flight, 4 listen streams;
    • in all: 64 calls in flight, 16 listen streams.

    Listen streams end within 15 s of revocation or MCP turning off. Every call is audited with surface mcp and a hash of its arguments.

  • GET /api/v1/context: a context bundle for any object a plugin can describe, as JSON or Markdown. A pod, workload, VM, host, alert, Flux object or database comes with its status, events, attention items, metric summaries and, with the logs scope, its recent log lines.

  • Copy context for AI: a button on pods, VMs, attention items and alerts puts that Markdown on your clipboard. Where the browser blocks the clipboard, it opens a dialog to copy from.

  • Settings → MCP: the switch, the endpoint (the direct URL when set), and a ready-to-paste claude mcp add command.

  • OAuth: the mcp resource now follows mcp.enabled.

  • Plugins: /api/v1/plugins says which plugins can describe objects (objects).

  • Dependencies: the official MCP Go SDK v1.8.0, plus jsonschema-go, uritemplate and segmentio/encoding. The binary grows by about 2 MB.

Upgrade notes

  • No step needed. With MCP on, dash logs "mcp: serving /mcp" at start.
  • Rolling back to v0.14.7: remove mcp.enabled from the config file first, because the older release refuses the unknown key. A value saved from the settings page or set in the environment only warns. See docs/upgrading.md.

v0.14.7

Choose a tag to compare

@TechDufus TechDufus released this 06 Nov 03:05
v0.14.7
c238634

dash can now authorize apps itself (#37). This release adds a built-in OAuth 2.1 server: apps such as the dash Android app, clients you configure, and clients that publish a metadata document can ask a signed-in user for a scoped, revocable grant. It is a patch and is off by default: nothing changes until you set auth.oauth.enabled.

New

  • OAuth 2.1 server (auth.oauth.enabled, default off):
    • authorization code with PKCE (S256 only), resource indicators, refresh tokens that rotate (reuse revokes the grant), RFC 7009 revocation, and the RFC 8414 and RFC 9728 discovery documents;
    • access tokens last 15 minutes;
    • it needs a writable data dir and a mode other than none; set DASH_SECRET_KEY so access tokens survive a restart.
  • Clients:
    • the built-in dash-android;
    • clients you list in auth.oauth.clients;
    • clients that publish a metadata document. dash fetches it only for a signed-in user, from global addresses only (unless auth.oauth.cimdAllowPrivate), and refuses a name that imitates a known client.
  • The consent screen shows the client, its kind ("Built in", "Configured by your admin", or "Unverified · metadata from <host>"), and the scopes it asks for. Only read is pre-ticked, and scopes your role can't grant are named.
  • Settings → Connected apps lists your grants: client, audience, scopes, created and last used. You can revoke them, and administrators can see and revoke every user's.
  • Logout scopes:
    • "Log out everywhere" also disconnects your apps;
    • "Sign out all users" (administrators) ends every session and grant;
    • personal access tokens are untouched.
  • Behind an identity proxy: server.directURL and the Helm chart's routes.direct give machine clients a host that skips the proxy, while sign-in and consent stay behind it. dash never trusts identity headers on that host.
  • Limits:
    • /oauth/token and /oauth/revoke are rate limited per grant, per code or per client, and can't be exhausted by invented client IDs;
    • pending authorizations are kept only for signed-in users (20 each);
    • 20 grants per user.
  • Dependencies: prometheus/common 0.73.0, and security overrides for development-only web dependencies (glob, minimatch).

Upgrade notes

  • No step needed. In proxy mode with OAuth on and no server.directURL, dash warns at start, because clients couldn't reach the token endpoint through the proxy.

  • Rolling back to v0.14.6 after using OAuth:

    • revoke every user's connected apps (Settings → Connected apps → All users);
    • then remove auth.oauth, server.directURL and the chart's routes (a helm rollback does this).

    See docs/upgrading.md.

v0.14.6

Choose a tag to compare

@TechDufus TechDufus released this 05 Nov 22:47
v0.14.6
1c0c844

dash now accepts API tokens (#36): personal access tokens for scripts, agents and apps, static tokens for GitOps installs, and Settings → Tokens to manage them. It is a patch. Nothing changes for browsers, and tokens stay off until dash has a writable data dir.

New

  • Personal access tokens. Create one in Settings → Tokens. You choose:

    • an audience: the API, or MCP for agents once the MCP server arrives;
    • scopes: read and logs, and for admins actions:<plugin>, optionally limited to namespaces;
    • an expiry from 1 to 365 days (default 30).

    The token is shown once, and dash stores only its hash. A revocation takes effect on the next request and ends open streams within one heartbeat. Each user can hold at most 50 tokens.

  • Bearer requests. Authorization: Bearer <token> works on /api/v1.

    • A token can do what its owner's role allows, narrowed by its scopes. That is worked out again on every request, so a group change at your identity provider reaches the user's tokens at their next sign-in, or at their next request behind a proxy.
    • Bearer requests skip the CSRF check. A request that carries both a token and a dash session cookie is refused.
  • Static tokens for GitOps installs. dash token generate prints a dash_st_ token and its hash, and the hash goes in auth.tokens. Edits to the config file apply without a restart.

  • CORS for browser-based clients: list their origins in server.corsOrigins. Nothing is sent by default, and Allow-Credentials never is.

  • Limits: 300 requests a minute per API token (bursts up to 300), and 10 token creations a minute per user.

  • Audit: every token request's audit record names the token.

  • Docs: docs/auth.md documents tokens, scopes, audiences and limits.

Behind an identity proxy

oauth2-proxy and similar proxies redirect requests that lack their own session, so bearer clients need a route that skips the proxy. The chart's routes.direct for this comes with the OAuth release. docs/auth.md lists what a route you set up yourself needs.

Upgrade notes

  • No change is needed. Tokens need a writable data dir in local, oidc and proxy mode. Without one, Settings → Tokens says they are unavailable.

  • Every 401 now carries a WWW-Authenticate: Bearer challenge.

  • Rolling back to v0.14.5 after creating tokens:

    • with dash stopped, remove credentials.yaml, which ends every session and revokes every token;
    • remove auth.tokens and server.corsOrigins from the config.

    See docs/upgrading.md.