practice

Policy as Code

also called Compliance as Code, Automated Control, Executable Policy

Expressing controls as executable rules evaluated automatically against real system state, so that compliance is demonstrated continuously over the whole population rather than asserted in a document and sampled once a year.

governancegatesautomationevidenceguardrails

Most controls exist as documents: a standard describing what should be true, a process describing who should check it, and an audit that samples the population once a year and infers the rest.

Policy as code makes the control executable. The rule is written in a form a machine evaluates — against a deployment request, an infrastructure state, a pull request, a running configuration — and the result is a decision plus a durable record.

Why it matters

Three properties change at once, and each is significant on its own.

Coverage becomes the whole population. The assertion moves from "twenty-five sampled changes complied" to "100% of changes in the period were evaluated and complied" — a materially stronger claim, produced at lower cost than the sample.

Evidence becomes a by-product. The policy evaluation result is the evidence, generated whether or not anyone asks, rather than assembled by engineers during an audit at a cost of weeks.

Feedback moves to the moment of the change. A developer who learns in thirty seconds that their configuration is non-compliant makes a different choice; one who learns in a quarterly review has already built on it, and the conversation is now about a sunk cost.

And writing the rule forces the policy to be precise enough to execute — which frequently reveals that the documented standard was ambiguous, and that different people had been interpreting it differently.

Implementation patterns

  • Evaluate at the points that matter: in the pull request, at admission to the platform, and continuously against running state — since configuration drifts after deployment and a one-time check does not detect it.
  • Start by asserting the current state, then tighten. A rule set that fails on day one is disabled on day one.
  • Deterministic rules only for hard gates. Anything heuristic belongs as a warning, because a gate that is frequently wrong trains everyone to override it, after which it is a delay rather than a control.
  • A documented exception path with a named approver and a mandatory expiry, since a rule with no exception path is deleted the first time it is genuinely wrong — and a visible exception is far better than an invisible workaround.
  • Track the override rate, which is the honest signal: a rule overridden routinely should be fixed or demoted to a warning.
  • Version-control the policies and review them like code, with the same discipline applied to the rules as to what they govern.
  • Test the policies themselves, because a broken check that passes everything silently is the most dangerous failure in the practice — it produces confident false assurance.
  • Prefer generated compliance to checked compliance: a golden path producing the correct configuration removes the need for the check entirely.

Industry example

The approach underpins modern platform governance — admission controllers evaluating policy in Kubernetes, infrastructure-as-code scanners in pipelines, provenance verification at deployment, and architecture fitness tests failing builds on forbidden dependencies. Its adoption has been driven as much by audit economics as by engineering: continuous evaluation over the full population is accepted by auditors as stronger evidence than sampling, and it moves their work from testing the population to testing the monitoring.

The complementary lesson comes from incidents rather than audits. The controls that would have prevented several large public outages — staged rollout, validation against the real consumer, blast-radius limits, local revert — are all expressible as automated policy, and their absence was a matter of nobody enforcing them rather than nobody knowing them.

Failure scenarios

  • Policies written and never verified, so a broken rule passes everything.
  • Aspirational rules that fail immediately and are disabled.
  • Heuristic rules as hard gates, producing false failures and trained-in overrides.
  • No exception path, so the rule is deleted rather than exempted.
  • Evaluated once at deployment, missing drift in running state.
  • Only the easily-automated controls covered, with the hard ones left manual and unmeasured — and the hard ones usually matter most.
  • Emergency bypass used routinely, removing the control in practice while retaining it in documentation.
  • Rules that go stale as the architecture evolves, blocking legitimate work and losing credibility.

Trade-offs

Policy as code only covers what is expressible as a property of an artefact or a configuration. It cannot assess whether the boundaries are in the right place, whether the design fits the problem, whether the complexity is justified, or whether a human can operate it at 3am — and an organisation that automates the checkable and stops there has industrialised the easy half of governance.

It also creates real friction when wrong, and the rules require ongoing ownership: an architecture that changes needs its policies to change with it, and nobody is naturally accountable for that.

The trade is rule-maintenance effort and occasional false friction in exchange for continuous, complete, low-cost enforcement of everything that can be checked mechanically. The value is greatest when it is used to free human review for the judgements only humans can make — which is the argument for it, and the thing most implementations forget to actually do.

Interview question

"We have a twenty-page architecture standard and no way to know whether anyone follows it. Tell me which parts you would turn into automated checks, which parts you could not, and what you would do with the review time the automation frees up."