Engineers

Policy as code for AI governance

How to turn your AI usage policy into executable rules: risk classification, attribute-based authorization, guardrails and CI tests.

e.works Labs TeamTechnology · Innovation · Automation4 min read

The executive article "AI committee: who decides, who approves, who answers" defines the decision structure. This piece addresses the next problem, the one that typically stalls companies that already have a committee: how to turn what was decided into something the system actually enforces, without relying on team training and good intentions.

Why a policy document isn't enough

An AI usage policy written in a PDF defines rules but doesn't enforce them. The gap between "it is written that" and "the system prevents" is where most AI governance incidents happen: someone uses an unapproved model, an agent takes an action without human approval, a high-risk use case reaches production without the review the committee required.

Policy as code closes that gap: policy becomes an executable, testable, versioned rule, evaluated at runtime or in a CI pipeline, held to the same rigor as production code.

Risk classification per use case as a rule

The first policy-as-code artifact is risk classification. Instead of a manually maintained spreadsheet, the use case declares its attributes and a rule determines the category:

use_case: "resume-screening"
attributes:
  decides_about_person: true
  reversible: false
  sensitive_data: ["employment_data"]
  monthly_decision_volume: 4200
classification_rule:
  - if: decides_about_person == true and reversible == false
    then: risk = "high"
  - if: sensitive_data contains "health" or "biometric"
    then: risk = "high"
  - default: risk = "medium"

This rule runs automatically when a new use case is registered, and recalculates the classification if attributes change — for example, if decision volume grows enough to cross a risk threshold.

Attribute-based authorization (ABAC)

Role-based access control (RBAC) isn't granular enough for AI: the same person may be authorized to use a model for one use case but not another, depending on risk, data type and time of day. Attribute-based authorization (ABAC) solves this by combining attributes of the user, the resource, and the context:

allow IF
  user.role == "credit_analyst"
  AND resource.use_case.risk IN ("low", "medium")
  AND resource.data.classification != "restricted"
  AND context.pending_human_approval == false

The advantage of expressing this as a rule, rather than a fixed permission in a table, is that the same decision engine can be reused across multiple services — inference API, agent orchestrator, admin panel — without duplicating logic.

Input and output guardrails

Guardrails are the rules that intercept the call to the model before it goes out (input) and the response before it's delivered (output):

MomentTypical checkAction on violation
InputPrompt contains data classified as restricted, unmaskedBlock and return a policy error
InputHigh-risk use case without logged human approvalBlock until approval
OutputResponse contains an unmasked PII patternBlock or auto-redact
OutputResponse indicates an irreversible action (e.g., cancellation, transfer)Hold for human approval
OutputConfidence score below the threshold defined for the use caseFlag as uncertain and route for review

Guardrails should be implemented as a layer separate from the application, not embedded in the code of each service that calls the model — that way, a policy change propagates without requiring a deploy of every consumer.

Mandatory human approval as a state, not a convention

High-risk use cases require human approval before execution. The robust way to implement this is not a manual side-check: it's modeling approval as a mandatory state in the decision's state machine.

states: pending -> awaiting_approval -> approved -> executed
                                     -> rejected -> closed

A high-risk decision simply has no transition path from "pending" to "executed" without going through "approved." This is enforced by the state engine, not by a process someone can skip under deadline pressure.

Policy tests in CI

If policy is code, it's testable as code. Every governance rule should have a set of test cases that run in the CI pipeline before any policy change reaches production:

test: "high_risk_use_case_without_approval_must_be_blocked"
given: use case with risk=high, human_approval=pending
when: request_execution()
then: result == "blocked"

test: "restricted_data_without_masking_must_block_input"
given: prompt containing an unmasked national ID
when: validate_input()
then: result == "blocked"

This catches policy regressions — a rule change that inadvertently unblocks something that should have stayed blocked — before they reach production.

Automatic evidence for audit

A side benefit of policy as code is that every rule evaluation, by construction, already produces a structured record: which rule was evaluated, with which input attributes, what the result was, and when. This replaces the manual reconstruction of compliance evidence — which usually happens under pressure, the night before an audit — with a query against a log that already exists.

What to do on Monday

  • Pick one policy rule already decided by the AI committee (e.g., "high-risk use cases require human approval") and formalize it as an executable rule, even if it runs in simulation mode at first.
  • Identify where guardrails currently live "inside each application's code" and plan their extraction into a shared layer.
  • Write the first policy test in CI covering the company's current highest-risk scenario.
  • Check whether the approval state machine actually prevents — not just discourages — execution without logged approval.

Further reading

Executive track:

ShareLinkedInX

Read next

Put it to work

From the article to practice: use this in your company

The capabilities described in this article are available on the e.works platform at eworks.cloud. You choose where your company's data lives: on e.works infrastructure, managed and protected on AWS, or in your own on-premises environment.

  • e.works infrastructure on AWS

    A managed environment protected by e.works on AWS, with encryption, per-company isolation, backup and high availability.

  • On-premises, in your environment

    The same platform running in your company's data center or private cloud, when data sovereignty requires that nothing leaves your perimeter.

In either model your data stays yours — with access control, audit logging, configurable retention and guaranteed availability.

Newsletter

Technical and strategic content, once a month

Analysis on automation, industrial data and technology adoption. No spam.