v0.18.0 · self-hosted · Kubernetes-first

Run a fleet of Grafana Alloy collectors from one place.

Shepherd is a self-hosted, Kubernetes-first fleet manager for Grafana Alloy. Install it with Helm, build pipelines visually or in Git, merge and validate them against a real Alloy binary, and serve them to every collector over Alloy's native remotecfg protocol — before anything reaches production.

180+ Alloy components in the palette
3 validation stages before serving
PAT · SSH · App Git auth for GitOps sync
amd64/arm64 container images, one binary

// what it does

Everything a fleet manager needs, nothing it doesn't.

Shepherd is a Go backend and React SPA shipped as one binary. It speaks Alloy's agent protocol directly, so collectors need no extra sidecar to be managed centrally.

Fleet management over remotecfg

Alloy agents poll Shepherd with their native remotecfg block. Shepherd resolves each collector by (cluster, role), and unchanged config is skipped over content-hash / not-modified responses — no polling overhead for a quiet fleet.

collector.v1 · Connect RPC

Visual pipeline builder

A schema-driven canvas covering every registered Alloy component. Drag components onto the canvas, wire them by typed ports, and undo/redo freely — the graph compiles to deterministic Alloy config through the same gate as everything else. Pipelines written as text, by a wizard or in git — grafana/k8s-monitoring output included — open in a read-only graph view that draws every wire and shows Alloy modules as groups.

drag-to-wire · undo/redo · graph view

Merge engine & validation gate

Pipelines target collectors with Alertmanager-style matchers, and every config passes a three-stage gate — syntax, alloy validate against a pinned real Alloy binary, and a full merge dry-run — before it can ever be stored as servable.

never serve unvalidated config

GitOps from any git server

Point a repo link at a directory of .alloy files on any git host. Authenticate with a personal access token, HTTPS basic auth, an SSH deploy key, a GitHub App installation or an Azure DevOps service principal — synced files pass the same validation gate before they're servable.

PAT · SSH · GitHub App · Azure DevOps

Sandbox simulation

Run a candidate pipeline against synthetic sources in a network-contained sandbox and inspect the captured series before it ever reaches a collector. Enabled by default as of v0.0.1 — a default-deny NetworkPolicy contains it, proven with in-cluster probes; turn it off per-deployment with simulator.enabled=false.

enabled by default

RBAC, orgs, and an audit log

Multi-tenant by design: application admins manage orgs and set each one’s tenant identity, org admins manage their own collectors and pipelines, org editors author what an org runs without being able to change where its telemetry ships, teams get scoped write over the pipelines they own, and viewers get read-only access. Roles come from your identity provider’s groups or from local accounts — Shepherd runs with or without an IdP. Every mutating action is written to the audit log.

org-scoped roles

A receiver for your apps, one tenant per route

An optional OTLP/HTTP endpoint behind your Gateway API gateway. Shepherd applies a route per tenant that sets the tenant header — a client can never choose its own tenant — and shows whether the gateway attached it. Each active OTLP route comes with ready-to-paste SDK and IaC snippets for connecting an app. Off by default; turn it on with receiver.enabled.

opt-in · Gateway API

A beacon, not a survey

Every claimed collector is served a small baseline pipeline that reports which components it is actually running, and whether they are healthy. Component names only — never config text, never raw samples. The collector you know nothing about is the one that would never have opted in — so it is on by default, with a single chart value to turn it off.

inventory + health

An agent interface that cannot apply

An MCP server exposes the fleet to AI agents in read-plus-propose mode. The limit is enforced by the credential, not by which tools were registered: a propose-scoped service account is refused at every mutating endpoint, so a tool that does not exist yet would be refused too. A machine action records both the agent and the human it acts for. shepherd-mcp ships in the release archives for Linux, macOS and Windows.

read + propose only

// how it fits together

One merge engine, three ways in.

Pipelines written by hand, drawn on the visual canvas, or synced from Git all pass the same validation gate before they are stored. When a collector polls, Shepherd matches the stored pipelines to it by label, merges them into one config and serves it — or answers “not modified”.

WRITE & VALIDATE STORE MATCH & SERVE UI editor Alloy text Visual builder renders to Alloy Git repository PAT · SSH · GitHub App Validation gate 1 · Syntax 2 · alloy validate + wiring 3 · Merge dry-run per affected collector refused here = never stored Sandbox (optional) run a draft on synthetic data PostgreSQL pipelines, revisions, audit log Merge engine Match pipelines by label Merge into one config Hash and cache it per collector, on each poll prod-eu-1 role=metrics prod-eu-1 role=logs staging-eu-1 role=metrics collector polls (remotecfg GetConfig) its config, or “not modified”

// quick start

Deploy with Helm, point Alloy at it.

The chart and images are published to GitHub Container Registry for linux/amd64 and linux/arm64 — nothing to clone. Bring your own PostgreSQL, or let CloudNativePG provision one.

1

Install the chart

Published as an OCI artifact — nothing to clone. Bring your own PostgreSQL and a secret holding the database URL and encryption key; see Configuration. Set config.server.base_url to the address your collectors reach Shepherd at. Sandbox simulation ships enabled by default; add --set simulator.enabled=false to turn it off.

shell
helm install shepherd oci://ghcr.io/procoduck/charts/shepherd --version 0.22.0 \
  --set existingSecret=shepherd-secrets \
  --set config.server.base_url=https://shepherd.internal \
  --set "route.enabled=true" \
  --set "route.hostnames[0]=shepherd.internal" \
  --set "route.parentRefs[0].name=my-gateway"
2

Point an Alloy collector at it

Add a remotecfg block to each collector's config.alloy, using an agent token created at Admin → Agent Tokens.

config.alloy
remotecfg {
  url = "https://shepherd.internal"
  basic_auth {
    username = "<token-uuid>"
    password = "<token-secret>"
  }
  attributes = {
    cluster = "<cluster-name>",
    role    = "metrics",
  }
  poll_frequency = "60s"
}
3

Just want to look at it?

The dev stack boots the whole thing in Docker — database, seeded data, and live Alloy collectors already polling it. For trying Shepherd or working on it, not for running it.

shell
git clone https://github.com/procoduck/shepherd.git
cd shepherd
make dev          # http://localhost:8080 — admin / admin

The Quickstart installs it properly on a cluster, and the documentation covers the chart values, authoring pipelines and access control.

Read the spec, or just clone it.

Shepherd's source lives on GitHub. The full product specification, architecture notes, and a running project ledger live in docs/.