burrow

module
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 1, 2026 License: Apache-2.0

README ΒΆ

Burrow

The Burrow mascot, a vigilant groundhog standing watch

For developers moving fast with AI who don't want to break things

Production grade self hosting for your apps, operated by your AI agent, with guardrails. Point Claude Code, Cursor, Codex, or bring your own at your Kubernetes cluster. It deploys, scales, debugs, and ships your apps to a URL over MCP. You own the infrastructure and the control plane that drives it, and every change the agent makes is gated by a guardrail, so it can't break prod.

It is not another git deploy host. Vercel and friends run your app on their platform; Burrow operates your cluster (real Kubernetes, done right), and goes past the app to the whole stack. The agent writes the integration code, and Burrow stands up and runs the backing service behind the same guardrails.

Why Burrow

  • Own your infrastructure, no lock-in. The control plane is yours. It self hosts in your own cluster, holds the cluster credentials, and is open source (Apache-2.0). No vendor platform sits in the path, and there is nothing to migrate off of later.
  • Production grade by default. It is real Kubernetes done right: self-healing workloads, rolling deploys, ingress and TLS, in-place upgrades, with sane defaults, so the hard parts are handled rather than left as homework.
  • A guardrailed agent, safe enough for prod. The agent is a tool you drive, not an autonomous operator turned loose on a cluster. It proposes, you approve, and every mutating operation passes the control-plane guardrails and lands in an audit trail. Secrets never travel over MCP. That control model is what makes letting an agent operate production acceptable.

Talk to your agent

What you can say today (βœ…), and where it is headed (πŸ”­):

  • βœ… "Deploy ghcr.io/me/app:1.4 and serve it at example.com over HTTPS." The image, ingress and TLS, and the DNS record, from one ask.
  • βœ… "Roll back the last release." Β· "Scale web to 3." Β· "Show me the logs." Β· "Is my app reachable? If not, what's broken?"
  • βœ… "How is my app doing?" Β· "Why is it slow?" β†’ Burrow installs logs (VictoriaLogs) on your cluster, or connects to the logs and metrics you already run (Loki, Prometheus), and your agent queries them and answers in plain language: answers, not dashboards.
  • βœ… "My site is slow, add a cache." β†’ your agent writes the ValKey integration; Burrow deploys ValKey to your cluster and wires it in.
  • πŸ”­ "Autoscale web on load." Β· "Show me this month's cluster spend." β†’ autoscaling and cost controls are on the roadmap.

The pattern is the same every time: the agent writes the code; Burrow provisions the vetted, permissively-licensed building block, wires it in with sane defaults, and operates it, with every change gated by the control-plane guardrails. The βœ… items work now, and the πŸ”­ items are the roadmap. The version table never lags the code.

Built for day two

The hard part of Kubernetes isn't the first deploy β€” it's everything after. The recurring complaint from small teams is the day-two tax: upgrades that break prod, certs and ingress that drift, and "why is my app slow?" debugging across a stack nobody has time to master. That second day is Burrow's job:

  • Upgrades in place β€” burrow upgrade rolls the control plane forward without losing state.
  • Reachability you can reason about β€” reachability walks the whole chain (controller β†’ ingress β†’ TLS β†’ DNS) and names the one broken link, so "it's down" becomes "the cert hasn't issued yet."
  • Operate by talking β€” status, logs, rollback, scale β€” the agent does the work, the guardrails keep it on the rails.
  • "How is my app doing?" β€” the agent installs logs on your cluster, or connects to the logs and metrics you already run, and answers in plain language (shipped in v0.4).

And every change is gated: the agent proposes, you approve, it executes β€” with the deploy record as the audit trail. That human-in-the-loop step is what makes letting an agent operate production actually acceptable.

How it works

Four layers (architecture):

  1. Your agent β€” any MCP client, not ours.
  2. The MCP server β€” thin, agent-neutral, holds no cluster credentials. The remote control.
  3. The control plane β€” the product: deploy, rollout and rollback, status and logs, scaling, reachability, the guardrails, and the record of who did what. Holds the cluster credentials; the only layer that talks to Kubernetes.
  4. Kubernetes β€” your cluster.

Two invariants keep it safe and fast: code never travels over MCP β€” only tool calls and small metadata; the built image moves through a container registry (ADR-0004) β€” and guardrails live in the control plane, between your agent and your cluster, returning a structured result the agent can reason over (ADR-0006). It is fully self-hostable: the single-tenant control plane, the MCP server, and the CLI run entirely on your own cluster.

What "guardrails" mean

Letting an agent operate a cluster is only acceptable if it cannot do something you did not approve. In Burrow, guardrails are policy that lives in the control plane, not in the agent, so the agent can't bypass them or change its own limits. Every mutating operation passes through them and gets one of three dispositions:

  • allow: the operation runs.
  • confirm: it is held until you approve. The agent gets back a structured "needs confirmation" result, not a success, so it has to ask first.
  • deny: it is blocked outright.

You set the policy from the CLI. There is deliberately no MCP tool for it, so an agent can never loosen its own guardrails:

burrow guard list                       # every guardrail and its current disposition
burrow guard set app.delete deny            # never let the agent delete an app
burrow guard set app.scale_to_zero confirm  # scaling to zero needs your sign-off
burrow guard set app.expose_public confirm  # putting something on the public internet needs approval

Guardrails cover the operations that carry risk: deleting an app, scaling to zero, exposing a service publicly, DNS changes, installing or removing add-ons, restoring a database, rolling back. Every attempt and its outcome (allowed, held, denied, executed) lands in an append-only audit log you read with burrow audit. And secrets never travel over MCP at all: the agent references them by key, you set the values, and they are written straight into a Kubernetes Secret.

Guardrails can be set per environment, so prod can be locked down while staging stays permissive. Add --env <name> to scope an app-level guardrail to one environment; an environment with no override of its own inherits the global policy:

burrow guard set --env prod app.delete deny      # lock prod: the agent can never delete a prod app
burrow guard set app.delete allow                # ... while staging and the rest stay permissive
burrow guard list --env prod                     # prod's effective policy, marking env-specific vs inherited

The app-level guardrails (deploy, scale, expose, delete, rollback) are environment-scopable. The cluster-level ones (DNS changes, add-on install or removal) act on the whole cluster, so they are set globally without --env.

Try it

You need a cluster you can reach with kubectl (DigitalOcean is the reference target). Three commands get you from nothing to an agent operating your cluster:

brew install burrow-cloud/tap/burrow     # installs burrow and burrow-mcp
burrow install <context>                 # control plane into the named kube context (run `burrow install` to list them)
burrow mcp claude install                # connect your agent (or: cursor, codex, copilot, opencode)

Then just talk to your agent ("deploy this and serve it at example.com over HTTPS"), or drive Burrow directly with burrow app deploy web --image nginx:alpine and burrow app status web.

See docs/getting-started.md for the full walkthrough, including the complete list of supported agents and how to connect any other MCP-capable tool.

Prefer to build from source? go build -o burrow ./cmd/burrow && go build -o burrow-mcp ./cmd/burrow-mcp.

burrow upgrade rolls the control plane forward in place, preserving your state.

Shell completion

burrow ships completion for bash, zsh, fish, and PowerShell. Load it for your shell:

source <(burrow completion bash)                                  # bash (current shell)
burrow completion zsh > "${fpath[1]}/_burrow"                     # zsh
burrow completion fish > ~/.config/fish/completions/burrow.fish   # fish
burrow completion powershell | Out-String | Invoke-Expression     # PowerShell

Run burrow completion <shell> --help for how to install it permanently.

Version status

Burrow follows semver from v0.1 toward v1.0. This table never lags the code (ADR-0009).

Version Scope Status
v0.1 Install into a cluster Β· connect an agent over MCP Β· deploy by image reference Β· status Β· logs Β· rollback Β· scale Β· in-place upgrade βœ… shipped (v0.1.1)
v0.2 Reach an app at a URL: shared-ingress routing Β· publish + cert-manager TLS Β· reachability surface Β· DNS automation (DigitalOcean / Cloudflare) Β· ingress install Β· configurable guardrails βœ… shipped (v0.2.1)
v0.3 Operability + agent-experience hardening: CLI grouped by task (app/config/system) Β· app list Β· account-scoped Cloudflare tokens Β· public-DNS reachability Β· request log βœ… shipped (v0.3.0)
v0.4 Agent-provisioned building blocks: install logs (VictoriaLogs) / metrics (VictoriaMetrics + vmagent) β€” or connect the logs/metrics you already run (Loki, Prometheus) β€” and query them to answer "how is my app doing?" Β· cache (ValKey) Β· app delete Β· tunable rollback guardrail βœ… shipped (v0.4.0)
v0.5 App config, secrets, credentials, and the audit log: app config / app secret lifecycle (deploy takes no config) Β· secrets & vendor/connected-backend credentials flow through the control-plane API, never MCP, never logged Β· burrow audit trail of guarded operations Β· apps default to a dedicated burrow-apps namespace βœ… shipped (v0.5.0)
v0.6 First backend building block, agent-native onboarding, and the Apache relicense: Postgres add-on (addon install/attach postgres, a per-app database + role, generated DATABASE_URL wired into the app) Β· pg_dump/pg_restore backups behind a confirm guardrail Β· read-only burrow_audit MCP tool Β· agent-native onboarding (cluster-capability detection, cost-aware ingress/TLS provisioning with a LoadBalancer-vs-NodePort choice, a verified "live at https://…" check) Β· dotted guardrail codes (app.delete) Β· whole repository relicensed to Apache-2.0 βœ… shipped (v0.6.0)
v0.7 Environments and a self-contained, kubectl-free CLI: cluster-per-env via kubeconfig-context routing (--context, per-call agent routing) and namespace-per-env via a burrowd registry (burrow env add), with per-environment guardrails that gate prod while staging stays permissive (burrow guard set --env prod app.delete deny) Β· one burrow env surface over named local handles that follows the kube context by default (use/follow/list/rename/scan), resolving both CLI and agent operations through the active environment (retires burrow context) Β· intent-based --help groups, explicit burrow install <context> that names the environment, a first-run banner, shell completion, system folded into cluster Β· burrow no longer needs kubectl (client-go server-side apply) Β· the app envβ†’app config rename βœ… shipped (v0.7.0)
v1.0 Production self-host: the deploy-and-operate core and common day-two building blocks, hardened planned (roadmap)

Documentation

  • docs/getting-started.md β€” set up Burrow on your cluster and connect your agent, start to finish.
  • docs/ARCHITECTURE.md β€” the system design: the four layers, the invariants, and the request paths.
  • docs/HARDENING.md β€” keep the control plane the agent's only path to the cluster, so the guardrails actually bound it.
  • docs/ROADMAP.md β€” version milestones, v0.1 β†’ v1.0.
  • docs/PLAN.md β€” the current execution plan.
  • docs/adr/ β€” Architecture Decision Records: every load-bearing decision, with its reasoning and rejected alternatives.
  • CLAUDE.md β€” the contributor and agent guide.

License and contributing

How the code is licensed (LICENSING.md, ADR-0033):

  • All of Burrow's code in this repository is Apache-2.0 β€” the CLI, the MCP server, the control plane, and the operator. Read, modify, self-host, and integrate against it freely.
  • Burrow is open core: the managed cloud and the enterprise tier (SSO, teams, compliance, support) are separate, proprietary products β€” see COMMERCIAL.md.

Contributions are welcome β€” open an issue or a discussion. Bug reports, ideas, and design feedback are the best way to help and to shape where Burrow goes. Commits are signed off under the Developer Certificate of Origin (git commit -s). See CONTRIBUTING.md.

Directories ΒΆ

Path Synopsis
cmd
burrow command
Command burrow is the Burrow CLI: the human-facing way to operate Burrow.
Command burrow is the Burrow CLI: the human-facing way to operate Burrow.
burrow-mcp command
Command burrow-mcp is the Burrow MCP server: the thin, agent-neutral control surface that exposes Burrow's tools to any MCP client and translates tool calls into control-plane API calls (ADR-0003).
Command burrow-mcp is the Burrow MCP server: the thin, agent-neutral control surface that exposes Burrow's tools to any MCP client and translates tool calls into control-plane API calls (ADR-0003).
burrowd command
Command burrowd is the Burrow control plane: the component that holds the cluster credentials, runs the deploy/rollout/rollback/logs/scale orchestration, enforces the guardrails, and records who deployed what (ADR-0002).
Command burrowd is the Burrow control plane: the component that holds the cluster credentials, runs the deploy/rollout/rollback/logs/scale orchestration, enforces the guardrails, and records who deployed what (ADR-0002).
Package connect reaches the in-cluster Burrow control plane from a developer's machine using their ambient kubeconfig and the Kubernetes API server's service proxy β€” no port-forward, no ingress (ADR-0014).
Package connect reaches the in-cluster Burrow control plane from a developer's machine using their ambient kubeconfig and the Kubernetes API server's service proxy β€” no port-forward, no ingress (ADR-0014).
Package controlplane is the Burrow control plane: the product.
Package controlplane is the Burrow control plane: the product.
api
Package api is the control plane's HTTP front end: it exposes the deploy engine's operations over JSON and authenticates its callers with a bearer token (ADR-0005).
Package api is the control plane's HTTP front end: it exposes the deploy engine's operations over JSON and authenticates its callers with a bearer token (ADR-0005).
dns
Package dns is the production controlplane.DNSFactory and the per-vendor DNS adapters (ADR-0018, ADR-0023).
Package dns is the production controlplane.DNSFactory and the per-vendor DNS adapters (ADR-0018, ADR-0023).
e2e
Package e2e holds end-to-end tests that drive the deploy engine through its real adapters β€” the client-go Kubernetes adapter against a live cluster and the registry resolver against a real registry β€” proving the whole vertical slice composes (ADR-0010).
Package e2e holds end-to-end tests that drive the deploy engine through its real adapters β€” the client-go Kubernetes adapter against a live cluster and the registry resolver against a real registry β€” proving the whole vertical slice composes (ADR-0010).
internal
Package internal holds the control plane's implementation guts: the deploy state machine, the Kubernetes/registry/database seam adapters, and the guardrail policy.
Package internal holds the control plane's implementation guts: the deploy state machine, the Kubernetes/registry/database seam adapters, and the guardrail policy.
internal/fake
Package fake provides in-memory implementations of the control-plane seams (controlplane.Clock, Kubernetes, Registry, Database) for tests.
Package fake provides in-memory implementations of the control-plane seams (controlplane.Clock, Kubernetes, Registry, Database) for tests.
kube
Package kube is the production controlplane.Kubernetes adapter, built on the official client-go SDK (ADR-0011).
Package kube is the production controlplane.Kubernetes adapter, built on the official client-go SDK (ADR-0011).
logs
Package logs holds the production controlplane.LogsQuerier adapters β€” the seam burrowd uses to query an installed or connected logs backing service (ADR-0026).
Package logs holds the production controlplane.LogsQuerier adapters β€” the seam burrowd uses to query an installed or connected logs backing service (ADR-0026).
metrics
Package metrics holds the adapters that query a metrics backing service (an installed or connected add-on) for the agent's metrics-query path (ADR-0026).
Package metrics holds the adapters that query a metrics backing service (an installed or connected add-on) for the agent's metrics-query path (ADR-0026).
postgres
Package postgres is the production controlplane.Database adapter, backed by Postgres running in the cluster (ADR-0012).
Package postgres is the production controlplane.Database adapter, backed by Postgres running in the cluster (ADR-0012).
registry
Package registry is the production controlplane.Registry adapter.
Package registry is the production controlplane.Registry adapter.
sys
Package sys holds the production implementations of the control plane's system seams β€” the wall Clock, a crypto/rand ID source, and the DNS Resolver β€” the concrete values cmd/burrowd injects in place of the test fakes (ADR-0010).
Package sys holds the production implementations of the control plane's system seams β€” the wall Clock, a crypto/rand ID source, and the DNS Resolver β€” the concrete values cmd/burrowd injects in place of the test fakes (ADR-0010).
Package internal is the root of Burrow's module-private shared helpers, licensed Apache-2.0.
Package internal is the root of Burrow's module-private shared helpers, licensed Apache-2.0.
Package localconfig models Burrow's client-side selector state: the human-edited ~/.burrow/config file that names environment handles and records which one a command targets (ADR-0036).
Package localconfig models Burrow's client-side selector state: the human-edited ~/.burrow/config file that names environment handles and records which one a command targets (ADR-0036).
Package mcp is the Burrow MCP server: the thin, agent-neutral control surface (ADR-0003) that exposes Burrow's operations as MCP tools to any MCP client and translates tool calls into control-plane API calls.
Package mcp is the Burrow MCP server: the thin, agent-neutral control surface (ADR-0003) that exposes Burrow's operations as MCP tools to any MCP client and translates tool calls into control-plane API calls.
Package operator is the Burrow Kubernetes operator: the CRD types and the reconcile loops that drive the cluster toward the control plane's desired state.
Package operator is the Burrow Kubernetes operator: the CRD types and the reconcile loops that drive the cluster toward the control plane's desired state.
internal
Package internal holds the operator's implementation guts: the reconcile loops and their helpers.
Package internal holds the operator's implementation guts: the reconcile loops and their helpers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL