Monday, December 29, 2025

Policy Belongs in the Pipeline

A practical perspective on build-time governance in CI/CD

Governance arises quickly when people discuss modern CI/CD. Compliance too. Everyone agrees it matters.

And yet, when you look at how pipelines are actually built, policy enforcement is often surprisingly thin. Not absent, but just fragile. That gap is not usually caused by bad intent. More often, responsibility simply ends up in the wrong place.

Where policy enforcement tends to drift

In many environments, policy enforcement gradually assumes familiar forms.

  • rules that live in documents instead of pipelines
  • scripts added late in the delivery flow
  • checks that only run after deployment
  • tools developers are expected to install locally

None of these is an unreasonable choice on its own. The problem is what they have in common.

When something fails, it becomes difficult to answer basic questions: where the rule was enforced, when it was evaluated, and why the pipeline made that decision.

That uncertainty is rarely a tooling problem. It is almost always an architectural one.

Stepping back from tools

At some point I stopped asking which tool would solve this best. That question tends to lead nowhere.

A more useful question turned out to be simpler: Where should policy enforcement actually live?

Not on developer machines. Not only at runtime. And not as an afterthought added to an otherwise finished pipeline.

The answer I keep coming back to is uncomplicated: policy enforcement belongs inside the CI/CD pipeline, at build time. Once you accept that, many design decisions stop being optional.

What Changes Occur When Policy is Embedded in the Pipeline

Integrating policy enforcement into the pipeline promotes transparency. Inputs must be explicit, and assumptions can no longer be relied upon. Hidden states become a liability.

Decisions must also be predictable. If the same pipeline is executed twice with identical inputs, the outcome should remain consistent. 

Moreover, when a rule is violated, the pipeline should stop immediately; no warnings, no deferrals, just a halt. This approach may seem strict, but without such clarity, governance quickly becomes negotiable.



Why local enforcement keeps failing

One pattern that repeatedly causes trouble is policy enforcement that depends on local developer setups.

Different machines behave differently. Versions drift. People work around issues “just this once”.

Over time, ownership becomes unclear. Was the rule enforced by the pipeline, by the tool, or by the developer?

By enforcing policy only inside the pipeline, those questions largely disappear. There is one execution context. One decision point. One place to look.

Developers write code. Pipelines enforce policy. That separation turns out to be surprisingly powerful.

Explainability is not a nice-to-have

Another thing that becomes obvious very quickly: pipelines that fail without explanation do not earn trust.“Policy check failed” is not an answer. It is a conversation starter, however usually an unproductive one. If work is blocked, teams need to understand why, immediately and in context. Not by reading a document. Not after escalation. But as part of the pipeline output itself.

Policy-as-code makes that possible, but only if explanation is treated as part of enforcement, not an add-on.

A deliberately small experiment

To investigate these concepts, I developed a compact reference implementation with a focused approach. This implementation enforces policy within the pipeline, necessitating clear input and designed to fail fast while providing insights into its decision-making process. It intentionally avoids attempting to be comprehensive and refrains from using abstractions that obscure the underlying processes. The primary objective was not to create a complete solution but to highlight the associated trade-offs clearly.

What stood out

Even in a limited setup, a few things became very clear.

  • pipeline tasks are stateless unless you make state explicit
  • pipeline definitions and pipeline execution are not the same thing
  • changing code does not automatically change behavior
  • governance only works when people understand it

None of this is new. But it is easy to overlook when governance is discussed in abstract terms.

Closing thought

There is a growing emphasis on the concept of "shifting left" in various discussions. However, what truly holds significance beyond mere timing is the notion of responsibility. It raises the critical question of who enforces compliance with established rules and at which stages in the process. 

If governance is truly important, it must be deeply integrated into the entire delivery process right from the outset: early, explicit, and prominently displayed for all to see. 

Moreover, Continuous Integration and Continuous Deployment (CI/CD) pipelines should not merely be viewed as mechanisms for delivering software. Instead, they should be recognized as vital governance boundaries that help ensure accountability and maintain standards throughout the development lifecycle.

The reference implementation discussed here is available as open source. Feedback and alternative perspectives are welcome. If you want to contribute, I’m most interested in:

  • alternative policy examples
  • clearer policy–pipeline contracts
  • cases where this approach breaks down

Pull requests, issues, and disagreement are all equally welcome.

Repo is located at: https://github.com/mnemonic01/opa-tekton-policies.git


No comments:

Policy Belongs in the Pipeline

A practical perspective on build-time governance in CI/CD Governance arises quickly when people discuss modern CI/CD. Compliance ...