Every real setup ends up with at least two places to run an app: somewhere loose where you try things and break them cheaply, and somewhere serious where breaking things has consequences. Staging and prod, by whatever names you use. The trick is running both without maintaining two separate mental models, two separate toolchains, and two separate sets of habits. Burrow's environments give you one workflow across both, with the safety turned up exactly where it should be. This guide shows how.
The core idea: same commands, different temperature
The commands you run against staging and prod are the same. What changes between them is how much friction each one earns. Staging lets risky actions just happen, because the blast radius is a throwaway. Prod holds or refuses those same actions, because a mistake there is real.
You are not choosing between a "safe mode" and a "fast mode" as one global switch. You are saying, once, that prod is where you slow down and staging is where you do not, which is what you already believe. Then Burrow enforces it.
Two ways to have environments
Burrow supports two shapes, and you pick based on how much separation you want.
Separate clusters. Staging on one cluster, prod on another. This is the strongest isolation: different machines, no chance of one spilling into the other. You point Burrow at each and give them local names.
One cluster, separate spaces. Staging and prod as isolated sections of the same cluster. Lighter weight and cheaper, since you are not paying for two clusters, while still keeping the apps and their data apart.
Both give you the same thing to work with: named environments you select between, with their own guardrails. Start with whichever fits your budget and your need for isolation. You can grow from one to the other later.
Which shape should you pick?
For most solo developers and small teams, separate spaces on one cluster is the sensible starting point. You get real separation between staging and prod, the apps and data are kept apart, and you are not paying for a second cluster to run a handful of test deploys. It is the cheap, pragmatic default.
Reach for separate clusters when the isolation genuinely needs to be physical: when you want zero chance of a staging experiment touching prod's machines, when the two have very different scaling needs, or when you simply want prod on hardware that nothing else shares. The good news is you do not have to decide perfectly up front. Because the workflow is identical either way, moving from one shape to the other later does not change how you operate day to day. It changes where the environments live, not how you drive them.
Setting them up
Getting your environments in place is a one time bit of setup. Which command you reach for depends on the shape you picked.
For one cluster, separate spaces, you add each environment as a named space on the cluster you are already pointed at:
burrow env add staging
burrow env add prod
Each name becomes a handle you can select between, and each keeps its apps and data in its own space. Apps land in a burrow-apps space by default, and the environment keeps them apart from there.
For separate clusters, each environment lives behind its own cluster connection, and you route to it by naming the cluster context. If you already have contexts set up for each cluster, you can point a command straight at one:
burrow app status web --context prod-cluster
You can also let Burrow discover what you already have. If you keep several clusters configured, burrow env scan looks at what you are set up to reach and helps you register them as environments, and burrow env follow ties the current environment to the cluster you are pointed at, so switching clusters brings the environment along. The details differ by setup, but the idea is constant: give each place a name, and select by name from then on.
Selecting an environment
You work in one environment at a time, and Burrow keeps track of which. To see your environments and which one is current:
burrow env list
To switch:
burrow env use prod
From then on, your app commands act on prod until you switch again. By default Burrow can also follow the cluster you are pointed at, so if you are already set up to work against a given cluster, the environment comes along with it. The name of the game is that there is always a clear answer to "which environment am I about to affect," and you can see it before you act.
The payoff: per environment guardrails
Here is where environments earn their place. Guardrails, the rules about what is allowed to happen, are set per environment. So you lock prod down and leave staging open, with the same actions treated completely differently in each.
Lock prod down:
burrow guard set --env prod app.delete deny
burrow guard set --env prod app.deploy confirm
burrow guard set --env prod app.rollback confirm
Now, in prod, deleting an app is simply off the table, and a deploy or a rollback pauses for your sign off before it runs. Leave staging loose:
burrow guard set --env staging app.delete allow
In staging, the same delete just runs, because it is a throwaway and speed is the point. Same commands, same apps, wildly different consequences, exactly as it should be.
Why this is the thing that makes agent operation safe
This per environment split is what lets you actually hand work to an AI agent without losing sleep. You want the agent moving fast, and staging is where it should move fast: deploy freely, tear things down, experiment. Prod is where you want it bounded.
Because the guardrails live in the part of Burrow that holds your credentials, the agent cannot route around them. It runs the same commands you do. In staging those commands fly. In prod, a delete is refused and a deploy holds for your approval, whether a human or an agent asked. The agent proposes, you decide, and the boundary is enforced in code, not in an instruction you hope it follows.
So the mental model for delegating is simple: let the agent own staging, and keep prod as the place where the risky moves come back to you. You set that up once, per environment, and it holds.
A day of it, in practice
Here is how a normal change flows through two environments.
You are working on a feature. You point at staging and let it rip:
burrow env use staging
burrow app deploy web --image ghcr.io/you/web:1.6.0-rc1
burrow app logs web
It looks good. You promote the same image to prod, where the deploy holds for your sign off because you set it to confirm:
burrow env use prod
burrow app deploy web --image ghcr.io/you/web:1.6.0
Note that you deployed the exact same image reference to prod that you tested in staging. That is the clean version of promotion: the artifact you proved in staging is the byte for byte artifact that goes to prod, no rebuild in between to introduce surprises. The only thing that changed between the two deploys is which environment you were pointed at, and how much that environment made you slow down.
If the prod release misbehaves, rollback is right there, subject to whatever policy you set for prod:
burrow app rollback web
A starting set of guardrails
If you are not sure where to set the dials, here is a reasonable default that a lot of people converge on. In prod, deny the truly destructive actions outright and hold the rest for a sign off:
burrow guard set --env prod app.delete deny
burrow guard set --env prod app.deploy confirm
burrow guard set --env prod app.rollback confirm
Deleting a prod app is almost never something you want to happen quickly, so denying it means an accidental or overeager delete simply cannot land, and if you genuinely need to remove something, you change the policy deliberately first. Deploys and rollbacks hold for confirmation, so changes to prod are always a decision you actively made rather than something that slipped out.
In staging, open things up, because the whole point of staging is to move fast where mistakes are cheap:
burrow guard set --env staging app.delete allow
burrow guard set --env staging app.deploy allow
Tune from there to taste. The shape that matters is the asymmetry: prod earns friction, staging does not, and the same commands respect both. This is the concrete version of "lock prod down, stay loose in staging," and it is the single most useful thing to set up once you have two environments.
Keeping your environment list tidy
Environments are local handles, and you can manage them like any list. Rename one, or drop a stale one you no longer use:
burrow env rename old-staging staging
burrow env remove old-prod
Removing a handle clears it locally and cleans up its scoped access, so you are not carrying around pointers to clusters you retired.
The safety of always knowing where you are
There is a subtle but important safety property in how Burrow handles environments, worth calling out because it prevents a genuinely scary class of mistake. When you have more than one environment registered, a mutating action that does not clearly name its target does not just guess and pick one. It refuses, and tells you the environments it could mean, so you can say which you meant.
That sounds like a small thing until you imagine the alternative: an operation meant for staging quietly landing on prod because the tool assumed. Burrow will not do that. A deploy, a scale, a rollback, a delete either goes to the environment you are clearly working in, or it stops and asks. And it never wanders: if the environment you named is unreachable for a moment, Burrow does not helpfully retry against a different one, it tells you the target is unreachable and names the others so you can redirect deliberately. Your target is explicit and sticky, so a mutating operation cannot silently end up somewhere you did not intend. That guarantee matters most exactly when an agent is driving, because "it deployed to the wrong cluster" is precisely the kind of confident mistake you want made structurally impossible.
Scaling belongs to the environment too
Guardrails are the headline, but the same "same command, different setting per environment" idea runs through scaling. Your environments almost never want the same size: staging runs lean because it is a place to try things, and prod runs bigger because real traffic hits it. Because scaling is its own concern, separate from deploying, you set each environment's size where it lives and it stays put.
burrow env use prod
burrow app scale web 3
That sets prod's web to three replicas. A later deploy does not quietly reset it: deploying no longer touches the replica count, so promoting a new image to prod keeps the size you chose. Staging can sit at one replica the whole time, and the two never fight over a shared number.
If prod's load moves around, you can hand the sizing to autoscaling instead of picking a fixed number:
burrow app autoscale web
Now prod scales itself within bounds as traffic rises and falls, while staging stays deliberately small. Turn it back off when you want a fixed size again:
burrow app autoscale web off
The pattern is the same one guardrails follow: the command is identical across environments, and the setting is per environment, so each place gets the behavior it should have without you carrying a second mental model.
What can go wrong, and how it is handled
A few things surprise people the first time, and each has a deliberate answer.
"Which environment am I in?" This is the question that causes real accidents, so Burrow makes it answerable at any moment: burrow env list shows your environments and marks the current one, and the current environment is sticky, it does not drift between commands. When more than one environment is registered, a mutating action that does not clearly name its target does not guess. It stops and names the environments it could mean, so an operation meant for staging cannot quietly land on prod.
A named environment is unreachable for a moment. Burrow does not helpfully retry against a different one. It tells you the target is unreachable and names the others, so you redirect on purpose rather than having an operation wander somewhere you did not intend.
A guardrail held your deploy. That is the system working. In prod, a deploy or rollback set to confirm pauses for your sign off, and a delete set to deny is simply off the table until you change the policy deliberately. When an agent hits one of these, it comes back to you rather than routing around it, because the guardrails live in the layer that holds your credentials.
You want to see the current rules before acting. Check the dispositions rather than guessing at them. Your agent reads them with burrow-agent guard, and you set them with burrow guard set, scoped per environment with --env. Knowing the current setting before you act is the whole point of having it explicit.
A few common questions
Do I have to decide on separate clusters versus separate spaces up front? No. Separate spaces on one cluster is the sensible, cheap default for most solo developers and small teams. Because the workflow is identical either way, moving to separate clusters later changes where the environments live, not how you drive them day to day.
Can I promote the exact thing I tested? Yes, and you should. Deploy the same image reference to prod that you proved in staging, so the artifact that ships is byte for byte the one you tested, with no rebuild in between to introduce surprises. The only thing that changes between the two deploys is which environment you are pointed at.
Can I keep prod locked while an agent works freely in staging? That is exactly the intended split. Let the agent own staging, where risky moves just run, and keep prod as the place where the risky moves come back to you for a decision. You set that asymmetry once, per environment, and it holds whether a human or an agent is asking.
The takeaway
Environments in Burrow are not a heavyweight feature you configure and forget. They are the simple, load bearing idea that lets you keep one workflow across a fast place and a safe place. The commands stay the same everywhere. The guardrails change per environment, so prod stays locked while staging stays loose. And that split is exactly what makes it safe to let an agent do the busy work in staging while the decisions in prod stay with you. One workflow, two temperatures, no second brain to maintain.