Azure DevOps lets you attach checks to environments, service connections, agent pools, repositories, variable groups and secure files. How would you decide which of those resources should carry a given gate?
answer
- gate the capability, not the convention
- ask what using it lets you do
- a skipped environment skips its gate
- the credential is harder to route around
- every added gate is another prompt
basics
~20 sAttach the gate to the resource that is the thing you actually want to restrict access to. Gate the credential on the service connection, the destination on the environment, and shared build capacity on the agent pool.
solid answer
~50 sAsk what the gate is protecting, then attach it to the resource that grants that capability. A rule about *where* a change lands belongs on the **environment**, so every pipeline deploying there inherits it. A rule about *what may use production credentials* belongs on the **service connection** — that is stronger, because it also covers pipelines that never declare an environment. A rule about *who may run on trusted hardware* belongs on the **agent pool**. Rules about specific secrets belong on the **variable group** or **secure file** that holds them. The practical test is coverage: a gate on the environment is bypassed by a pipeline that skips the environment, whereas a gate on the credential cannot be bypassed by anyone who needs that credential. In regulated setups you place both, accepting that a stage using several protected resources waits for the union of all their checks.
go deeper
Know that checks belong to a resource rather than to the pipeline file, so an approval on the production environment applies to any pipeline that deploys there.
Be able to name the protected resource types and say which policy naturally fits each — destination rules on environments, credential rules on service connections, hardware rules on agent pools.
Show the coverage argument: a gate on the environment is bypassed by a pipeline that never declares one, while a gate on the credential is not. Recommend layering enforcement and audit trail deliberately.
Own the whole placement decision, including who administers each resource. Put non-negotiable controls on resources the gated team does not own, keep human approvals scarce so they stay meaningful, and push anything catchable earlier out of the pipeline entirely.
## The model, then the judgment Azure DevOps has an unusually general protection model. Checks are not a property of pipelines; they are a property of *resources*, and a stage that consumes a protected resource waits for its checks. Because several resource types can be protected, the same policy can often be expressed in more than one place, and choosing badly produces gates that are either bypassable or maddening. ## Start from the capability, not the workflow The reliable question is: **what does using this resource let you do?** Gate the capability at its source. - **Service connection** — grants cloud credentials. This is the strongest attachment point, because the credential is the capability. Any pipeline that wants to touch production Azure must go through it, whether or not it declares an environment. Branch control and required-template checks here are hard to route around. - **Environment** — names a destination, and carries the deployment history. Approvals here read naturally to auditors: *who signed off on this change to production?* But an environment gates only pipelines that declare it. - **Agent pool** — grants execution on particular machines. Protect a pool that has network reach into a sensitive segment, or self-hosted hardware you do not want arbitrary pipelines running on. - **Repository resource** — governs pipelines pulling in code from another repo, which is a supply-chain concern. - **Variable group / secure file** — governs one specific set of secrets or one file. Narrow and precise; useful when a credential is shared by pipelines that have nothing else in common. ## The coverage test Here is the failure this framing prevents. A team puts an approval on the `production` environment and considers production gated. Someone writes a pipeline that runs an Azure CLI deployment from an ordinary `job:` with no `environment:` at all, using the production service connection. No environment, no check, no approval — and it deploys. The environment gate was a gate on *a convention*, not on *a capability*. Put the branch-control and approval checks on the production service connection and that pipeline stops, because it cannot obtain credentials without passing them. Keep the environment approval too, for the readable audit trail. The two are complementary: one is enforcement, the other is the record. ## Duplication has a cost Because the checks of every protected resource a stage uses are combined and all must pass, over-attaching produces stages that wait on three approvals from overlapping groups of people. Approval fatigue is real: people who approve five prompts a day stop reading them, at which point the control has been converted into a delay. Two heuristics keep this in hand. First, prefer one *human* approval per stage and let the other resources carry automated checks — branch control, business hours, required template — that cost nobody an interruption. Second, split into more stages only when a genuinely different decision is being made, since each gated stage is another prompt. ## Scope follows organisational ownership Resources are project-scoped objects with their own permissions, so the attachment point also decides *who administers the gate*. A check on a service connection owned by the platform team is administered by the platform team; a check on an environment owned by the product team is theirs to change. When a control must be non-negotiable for the product team, put it on a resource the product team does not administer. This is often the deciding factor and gets overlooked because it is an org-chart question wearing a YAML costume. ## What does not belong here Some policies are cheaper elsewhere. Requiring code review before merge is a branch policy on the repository, not a pipeline check — gating at deploy time means the work was already done before anyone objected. Preventing a bad artifact from existing is a build-stage concern. Checks are the right tool for *use of a privileged resource*, and a poor tool for anything you could have caught earlier. ## A workable default For a typical production path: an approval and branch control on the production **environment** for the audit narrative; branch control and a required-template check on the production **service connection** so the capability itself is fenced; an exclusive lock on the environment so concurrent runs cannot interleave deployments; and nothing on the agent pool unless the hardware is genuinely sensitive. Then look at the resulting wait time on a real change and remove whatever is duplicative.
- A team gated the production environment, yet a pipeline deployed to production without an approval. How?It never declared the environment. A plain `job:` using the production service connection with an Azure CLI step reaches production while touching no gated resource. The environment check gated a convention rather than a capability. Moving branch control and approval onto the service connection closes it, because credentials cannot be obtained without passing them.
- When is the agent pool the right place for a check?When execution on those machines is itself the privilege — self-hosted agents inside a sensitive network segment, or hardware with cached credentials and local state. Gating the pool stops arbitrary pipelines from running code there at all, which is a different and broader control than gating any single deployment target.
- How do you keep layered checks from turning into approval fatigue?Aim for one human approval per stage and let the other resources carry automated checks — branch control, business hours, required template — which enforce continuously and interrupt nobody. Add a stage only when a genuinely different decision is being made. Approvers who clear five prompts a day have stopped reading them, and the control has become a delay.
- Should a code-review requirement be enforced as a pipeline check?No. That belongs to branch policy on the repository, enforced at merge time. Enforcing it at deploy time means the change was already written, merged and built before anyone could object, so the feedback arrives at the most expensive moment. Checks are for governing use of a privileged resource, not for catching what earlier controls should have caught.
saying these in an interview costs you the question
- Assuming an environment gate covers pipelines that skip the environment
- Attaching every check to every resource "to be safe"
- Ignoring that a stage waits on the union of all checks
- Placing gates on resources the gated team administers themselves
- Using deploy-time checks to enforce code-review policy