The Firewall Moved Into the Repo

The Firewall Moved Into the Repo

How GitOps-built environments changed where and how security is enforced


The firewall used to be a place

For most of my career, "the firewall" was a physical location. A box in a rack, a serial console, a change window on Thursday night, and a queue of tickets asking someone to open port 443 from one VLAN to another. Security enforcement had an address. You could walk up to it.

That model made sense when applications had addresses too. One application, one server, one VLAN, one firewall rule. The network topology was the security architecture.

Then we containerized everything, and the topology dissolved. The interesting question is not whether the old model was wrong it wasn't but where its responsibilities went when the ground it stood on disappeared.

Everything from a repo

Modern platforms are built on a simple, radical premise: the repository is the source of truth. Not the running system. Not the console. The repo.

Infrastructure as Code and GitOps take this to its logical conclusion. The cluster, the workloads, the routing, the TLS configuration, the WAF policy all of it is declared in version-controlled files. The running environment is a rendering of the repo. If reality and the repo disagree, reality is wrong and gets reconciled.

This inverts the traditional security workflow completely:

  • Change control is a merge request, not a change ticket.
  • Audit is git log, not a screenshot of a config page.
  • Rollback is git revert, not restoring a backup of a device config.
  • Drift is not a maintenance nuisance it is a security incident, because something changed the environment outside the declared truth.

We build enormous container-based environments this way now. Hundreds of services, ephemeral pods, IP addresses that mean nothing and live for minutes. There is no VLAN boundary to hang a firewall rule on. So the enforcement had to attach itself somewhere else.

Where enforcement landed: the ingress controller

Follow the traffic into a modern Kubernetes cluster and count the security functions that fire before a request reaches an application:

  • TLS termination and certificate policy cipher suites, minimum versions, mTLS to backends
  • Web application firewall OWASP CRS via Coraza compiled into the data plane, or a commercial engine like F5 WAF for NGINX running in-process
  • Authentication and authorization OIDC flows, JWT validation, external authorization services like Pomerium making per-request identity decisions
  • Rate limiting and L7 DDoS controls
  • Header sanitization, request normalization, protocol enforcement

Ten years ago, that list was a rack: a perimeter firewall, a dedicated WAF appliance, a load balancer, an authentication proxy. Today, inside the cluster, every one of those functions runs in or directly beside the ingress controller a Deployment, defined in YAML, deployed from a repo, scaled by a scheduler.

For traffic entering these environments, the ingress controller has become the policy enforcement point. It is where identity meets traffic, and it carries responsibilities that used to belong to an entire rack of purpose-built equipment. That is a remarkable consolidation and it deserves to be treated with the same seriousness we always gave the perimeter.

The org chart is now encoded in the API

The clearest evidence that ingress has become a security control plane is the Kubernetes Gateway API, which has superseded the old Ingress API for exactly this reason.

Gateway API splits routing into role-oriented resources. Infrastructure and security teams own GatewayClass and Gateway the listeners, the TLS policy, the WAF attachment. Application teams own HTTPRoute their own paths and backends, within the guardrails the platform team defined.

This is the change-request discipline of traditional network security, rebuilt as an API contract. The security team no longer processes tickets to open ports; it defines the policy attachment points and reviews the merge requests that touch them. Developers get self-service routing without ever holding the keys to the perimeter. Separation of duties, enforced by CRD schema instead of process documents.

The discipline survived. Only the medium changed.

Not a replacement a decomposition

To be precise about what happened: the firewall did not become obsolete, and the ingress controller did not replace it. The firewall's responsibilities decomposed into layered, software-defined enforcement points and different layers landed in different places:

Traditional function Software-defined equivalent
Perimeter firewall (L3/L4) Cloud/network LB, NetworkPolicy, CNI
WAF appliance In-process WAF in the ingress data plane
Auth proxy / VPN concentrator Identity-aware proxy (ext_authz, OIDC)
Internal segmentation firewalls NetworkPolicy, mesh mTLS + authz
Change control board Merge request review + CI policy tests

The ingress controller inherited the most visible and most concentrated share of that decomposition the front door for north-south traffic. East-west traffic between services is governed elsewhere: NetworkPolicy, the CNI layer, and where the operational cost is justified, a service mesh.

And in many real environments mine included a hardware perimeter still stands in front of all of it. That is not legacy debt waiting to be cleaned up. A dedicated L3/L4 and DDoS layer in front of software-defined enforcement is a legitimate architecture, and for regulated environments it may be the stable end state rather than a transition phase. The layers complement each other; they don't compete.

What this asks of security teams

If a growing share of enforcement is software deployed from a repo, security teams inherit new obligations that the appliance world never had:

1. The enforcement point has a supply chain. A WAF running in the data plane is a container image. Where was it built? Who signed it? Community ingress-nginx was retired in early 2026 teams that treated their ingress controller as infrastructure furniture suddenly discovered it was an unmaintained dependency. A software enforcement point can be abandoned upstream. That was never true of an appliance under support contract, and it changes what "vendor management" means.

2. Security policy needs a test pipeline. If WAF rules and authorization policy live in a repo, they can and must be tested in CI before they reach production. A policy you cannot test before deployment is a policy you will test in production.

3. Review the merge request, not just the ticket. The daily interface for securing these environments is the pull request that modifies a Gateway resource or a WAF policy file. A security organization that can read a diff can audit this perimeter with more precision than any appliance ever offered.

4. Protect the repo like you protected the firewall console. If the repo is the source of truth, then write access to the repo is enable-mode. Branch protection, signed commits, and reviewer requirements are perimeter controls now.

None of this devalues the competence built over decades of running perimeters. The opposite: rule hygiene, least privilege, change discipline, the instinct to ask "who can reach what, and why" that is exactly the competence the ingress layer needs, expressed in a new medium. The people best positioned to govern software-defined enforcement are the people who governed the hardware kind.

The perimeter followed the workload

Zero trust was never really about products the core idea, that no packet is trusted because of where it came from, predates the branding by decades. What containers and GitOps did was finally make the idea operational: enforcement is no longer anchored to a network location, because inside these environments there is no stable network location left. Enforcement attached itself to the workload boundary instead.

The ingress controller is where that attachment is most visible. It authenticates, it inspects, it rate-limits, it terminates trust boundaries and every one of those decisions is declared in a repo, reviewed in a diff, and deployed by a pipeline.

The firewall didn't disappear. It became software, split into layers, and moved into version control. The job is the same as it always was. Only the address changed.