skip to content

Egress Control

Few builds are hermetic, so egress becomes the control: default-deny outbound, one proxied path for packages, no secrets in the job that runs install hooks. Interviewers ask what stops exfiltration.

on this pageshow

questions

4

What does a default-deny outbound network policy on a build job actually prevent?

level: juniorimportance: must knowfreq 60%

answer

  1. assume hostile code already runs here
  2. cut the channel, not the code
  3. loot out, second stage in
  4. artifact integrity is a different control
  5. DNS still counts as outbound

basics

~20 s

Default-deny outbound stops build-time code reaching unapproved hosts: no exfiltrating secrets or source, no pulling a second-stage payload. It does not make a malicious dependency safe - the code still runs and can still corrupt the artifact.

solid answer

~50 s

A build job executes a lot of code nobody reviewed - install hooks, plugins, generated test fixtures - while holding source, publish tokens and often a cloud identity. Default-deny egress means the job can only reach destinations you explicitly allowed, so that code has no channel to send what it stole and no channel to fetch a second stage, which is how most build-time payloads actually arrive. Routing through a proxy rather than dropping silently also gives you a log, and a denied connection from a build is a very high-signal alert because legitimate builds talk to a small, stable set of hosts. What it does not do: it does not stop the malicious code running, it does not clean the artifact you publish, and it leaks through anything you had to allow - including DNS resolution, which is itself an outbound channel.

go deeper

for a junior

Be ready to say in one breath what the control blocks: unapproved outbound connections from a build job, which means no sending secrets out and no fetching a payload in.

for a middle

Explain the mechanics - the job runs with no route by default, an allowed set is named explicitly, and traffic goes through a proxy so attempts are logged rather than silently dropped.

for a senior

Show where you would apply it first and what it misses: the install stage needs almost nothing, the artifact can still be backdoored, and any allowed host plus DNS remain viable channels.

for a principal

Own the framing that this is containment rather than prevention, and be able to argue what it is worth relative to the ongoing cost of maintaining allow-lists across an estate.

## What the control actually is A build job runs a great deal of code that nobody on your team wrote or reviewed: dependency install hooks, build plugins, code generators, test fixtures, container entrypoints. Default-deny outbound means the job starts with **no route off the machine**. Every destination it is allowed to reach is named explicitly - normally by forcing all traffic through an egress proxy or by attaching a network policy to the job's namespace - and everything else is refused. The mental model that makes this click: **assume the build is already running hostile code and ask what that code can do next.** ## The threat it answers Once arbitrary code executes on a runner, it can read whatever the job can read. In a typical pipeline that is a lot: the checked-out source, the environment (publish tokens, registry credentials, a short-lived cloud identity), the runner's disk, and the link-local instance-metadata endpoint that will hand out the host's cloud role to any local process. Having read all that, the attacker needs a channel. Two directions matter: - **Outbound** - get the loot off the box. Credentials, source, signing material, customer data present in test fixtures. - **Inbound over an outbound connection** - fetch a second stage. A very common pattern is that the published package is boring and small, and the real payload is downloaded at build time from an attacker-controlled host. This keeps the malicious code out of the artifact anyone can inspect. Default-deny closes both. It also closes long-lived command-and-control, and it closes the sloppier category of unpinned installers that fetch a script from a random host mid-build. ## What it does not prevent - this is the part interviews probe - **The dependency is still malicious and still runs.** Egress control is containment, not prevention of compromise. The hostile code executes on your runner with the job's privileges. - **The artifact can still be corrupted.** An implant compiled into the binary leaves your network through your own approved channel - the registry push you obviously allow. Nothing about egress policy detects that; that is what provenance, reproducible builds and review are for. - **Allowed destinations remain open.** If the internal package index is allow-listed and the job can publish to it, a secret can be smuggled out inside a package. If a public source-code host is on the list, a repository there is a perfectly good drop point. - **DNS is an outbound channel.** If the job can resolve arbitrary names through a resolver that talks to the internet, data can be encoded into query names and the lookup alone carries it out, even when the connection that follows is blocked. So the honest framing is: default-deny egress **reduces the blast radius and buys you evidence**. It does not make untrusted code safe to run. ## Preventive plus detective Route the traffic through a proxy rather than silently dropping packets, because the log is half the value. A legitimate build talks to a small, stable set of destinations, so a **denied connection attempt from a build job is unusually high-signal** - far better than most alerts a security team gets. The deny is the preventive half; the log line is the detective half, and it is what lets you answer later which build, which stage, and how much data moved. ## Where to apply it first Egress policy does not have to be uniform. The stage that runs the most untrusted code is dependency resolution and install, and it is usually also the stage that has no legitimate reason to talk to anything except the package proxy. Tightening that one stage, and leaving the deploy stage with its broader list, gets most of the value without a month of breakage. ## What a strong answer sounds like Something close to: the build is a place where third-party code executes with production-adjacent credentials; default-deny egress means that code cannot phone home with what it stole or pull down what it still needs, and every attempt it makes is logged. It does not stop the code running, it does not clean the artifact, and it leaks through any destination you had to allow - including DNS.

  • If the malicious dependency runs anyway, what have you actually gained?
    Blast radius and evidence. The code executes but cannot ship credentials or source anywhere, and the common loader pattern - a benign-looking package that downloads its real payload at build time - simply fails. You also get a log line for every attempt, which turns an invisible compromise into an alert and gives you something to scope from later.
  • Does a strict egress allow-list stop a compromised build from shipping a backdoored artifact?
    No. The implant travels out through a destination you obviously allow - the registry you publish to. Egress control is about unapproved channels; artifact integrity is answered by reproducible builds, provenance and review of what the build produced, not by network policy.
  • Which outbound path do teams most often leave open by accident?
    DNS. Jobs usually keep name resolution working because nothing builds without it, and a resolver that reaches the internet will happily carry data encoded in query names even when every TCP connection is refused. Logging DNS queries, and resolving only through a controlled resolver, is the usual answer.

It is the difference between stopping a thief getting into the building and making sure that if one does get in, there is no door, no window and no phone line to get the loot back out.

saying these in an interview costs you the question

  • Claims deny-all egress makes a malicious dependency harmless
  • Thinks blocking outbound also blocks attacks against the runner
  • Forgets DNS resolution is itself an outbound channel
  • Treats egress policy as a replacement for dependency scanning
  • Assumes allowed destinations cannot be abused for exfiltration

context

open as a page

Your build runners now deny all outbound traffic - what belongs on the egress allow-list?

level: middleimportance: should knowfreq 47%

basics

~20 s

The package proxy, the image registry, source hosts, the CI control plane's log and artifact endpoints, identity and secret endpoints, telemetry, plus plumbing like DNS and time sync. Scope the list per stage rather than keeping one global union.

open as a page

How does running dependency install in a credential-less job contain a malicious package?

level: seniorimportance: should knowfreq 44%

basics

~20 s

Install runs in a job holding no cloud role, no publish token and no repo write, with egress limited to the package proxy. Hostile install code then executes with nothing worth stealing and nowhere to send it.

open as a page

An egress log shows a nightly build reached an unexpected host - how do you find which stage?

level: seniorimportance: nice to knowfreq 32%

basics

~20 s

Attribution needs a per-job egress identity - a source address or proxy credential that puts the job id in every log line - intersected with retained per-step timestamps. Bytes sent versus received then separates exfiltration from a downloaded payload.

open as a page