Build Agent Access to Spokes¶
Pipelines that deploy to private resources need agents inside the network. This page describes a standard way to give those agents network access to the spokes without a firewall request per pipeline, and the risks that come with it.
Two kinds of agents
The platform's own job runners (Managed DevOps Pool, Container Apps) deploy the hub and the spokes. When
deployment_agents_private_network_range is set, the platform creates its own rule collection group for them (priority
8999). This page is about the workload teams' agents, which deploy workloads into spokes. Whether the platform
offers shared agents is platform-specific: see Build agents in the network and Shared services.
The problem¶
Agents live in their own spoke. By default the firewall blocks their traffic to the other spokes. As a result:
- every pipeline needs a manual firewall request for the ports it uses,
- deployments wait for approvals,
- access differs between environments, so pipelines fail in one environment and work in another,
- the problem grows with every workload that is onboarded.
Guidance¶
Create one-way rules from the agents to the workload spokes, with IP groups on both sides:
- Put the agent subnet in an IP group (for example
ipgrp-selfhosted-agents). - Put the spokes in IP groups by environment class, so you can treat risk differently:
- one group for development and test spokes,
- one group for acceptance and production spokes. Include all regions.
- Allow only the ports that deployments need. Typical: HTTPS and HTTP, SSH, and the database ports your teams use. Decide per class.
- Create two rule collections, one for dev and test, one for acceptance and production, in two files in the global
firewall folder (so they apply to every region). Name the files, collections and rules in a recognisable pattern, for
example
global_build-agent-access-devtest.jsonand a ruleAllowBuildAgent_FromAgentIPGroup_ToDevTestSpokes_HTTPS. - Apply them on every regional firewall, so agents work after a failover.
- Follow your rule organisation: place the files in the global functional range of priorities.
Risks and how to limit them¶
| Risk | Limit it with |
|---|---|
| The attack surface from the agent spoke to all spokes grows | Treat the agents as highly privileged. Update the image regularly. |
| Some workloads get more access than they need | Use separate classes for non-production and production, and open fewer ports towards production |
| A compromised agent could reach production | Use a separate agent pool for deployments to production, and keep agents short-lived |
| Credentials remain on the agent | Tear the agent down after every job, so secrets and certificates cannot stay behind |
| One team uses another team's credentials | A pipeline must be authorised to use a service connection or service principal by the owning team. The agent only acts with the identity the pipeline supplies. |
| Complex deployments need extra ports | The standard rules do not cover them. Those teams request an additional rule. |
An agent pool design that fits these limits: a scale set that builds on a regularly rebuilt image (for example weekly), agents that are removed after each use, a few agents on standby to start fast, a maximum number of machines, and a firewall rule that allows only the traffic towards Azure resources (HTTPS and the database protocols). If the weekly image build fails, the existing agents keep working; the cause is often a change in the upstream image repository.
Example: container-based agents in a spoke subnet¶
A second kind of agent pool runs on Azure Container Apps jobs, in a subnet of a spoke (see Container agent pool). The same guidance applies, and the firewall needs these decisions:
| Topic | Decision in the example |
|---|---|
| Source | The CIDR of the Container Apps subnet is added to the agent IP group. No separate rule is needed when a rule for that group already exists. |
| Outbound rule | One rule from the agent IP group allows TCP 443 to any destination (*). The agents need the Microsoft Entra sign-in endpoint, the container registry, the Azure DevOps service and the agent download host, and blob storage. |
| Port 80 | Not allowed. The container image is built with HTTPS downloads only (no apt-get). |
| Service endpoints (optional) | Microsoft.ContainerRegistry and Microsoft.Storage on the subnet take image pull and blob traffic over the Azure backbone and past the firewall. This lowers cost and pull time, and is not required. |
| Order of work | Deploy the firewall change before the agent pool. The Container Apps environment tests the registry access when a job is created, so the pool deployment fails when the subnet is not allowed. |
Check the IP group as deployed in Azure, not only in the configuration repository, when pulls fail with ImagePullFailure.
A job on this pool is stopped after 30 minutes in the example, and the image has no Docker daemon. Say so when you give teams access, and keep a VM-based pool for what does not fit.
Consequences¶
Positive:
- teams no longer request rules per pipeline,
- deployments are faster and consistent across environments,
- the rules follow the organisation described in Firewall rule organisation.
Negative:
- the agent spoke can reach all spokes, so agent security becomes critical,
- workloads may be reachable on more ports than they strictly need.
Related¶
- Build agents in the network (for workload teams)
- Container agent pool (deploy and operate the container-based pool)
- Shared services
- Design principles: guardrails for pipelines