What Governance-as-a-Service means
The GaaS pattern treats governance as a first-class service rather than a side effect of agent prompting. Instead of writing "don't do unsafe things" into every agent's system prompt, you route every proposed action through a standalone governance layer that applies a consistent policy and records the decision.
The pattern has four required components. A policy store holds the rules. An enforcement engine evaluates proposed actions against those rules. An audit trail records every decision. An agent interface lets agents submit proposed actions and receive verdicts. That's it. The pattern is deliberately minimal.
The key insight is separation: governance logic lives outside the agent. An agent that enforces its own rules is not governed, it's self-supervised. Self-supervision collapses when the agent's reasoning is compromised, which is exactly when you need governance most.
The Gatekeep implementation
Gatekeep was built before the GaaS pattern was formally named. Looking back, the correspondence is close enough to be useful as a reference implementation.
The policy store is a set of JSON files in the repository. Each rule has a condition (path pattern, action type, resource type, tag), a decision (allow, deny, require_approval), and a persona (Sentinel, Auditor, Architect). Rules are loaded at Lambda cold start and cached for the lifetime of the container.
The enforcement engine is a Lambda function. It receives a proposed action (agent name, action type, resource, context), loads the rules, and evaluates them in order. First-match wins. If no rule matches, the default is allow with an audit record. If a rule matches deny, the action is blocked and the reason is returned to the caller.
The audit trail is DynamoDB. Every evaluation is written regardless of outcome: action, decision, matched rule, persona, timestamp, and a hash of the action payload. This is not a log. It's a ledger. Records are immutable. The table has no TTL.
The agent interface has two forms. The MCP tool definition lets the AI assistant submit proposed actions interactively during a session. The pre-commit hook submits file changes and shell commands before they leave the working tree. Both call the same Lambda endpoint.
Why declarative rules survive migrations
When the platform changed from Paperclip to Lambda, every agent was rewritten. The orchestration model changed. The invocation model changed. The runtime environment changed. The governance rules didn't. They were JSON files in the repository, loaded by whichever enforcement engine was current. The rules are not coupled to the runtime.
This is not an accident. It's the reason for keeping rules declarative. A governance rule that says "deny writes to /etc" is portable. A governance rule embedded in an agent's system prompt is not: it's text that a different model might parse differently, and it disappears when the agent is replaced.
The migration took two days. One day to rewrite the Lambda evaluator. One day to test that the rules still produced the expected verdicts. Zero days to rewrite the rules.
Persona dispatch
Each rule specifies which persona should review it if the decision is not automatic. A rule that denies writes to infrastructure files routes to Sentinel. A rule that requires approval for spend above a threshold routes to Auditor. A rule that flags breaking API changes routes to Architect.
Persona dispatch matters because the same action can have different implications. A change to a Lambda memory setting is a cost question (Auditor), a performance question (Architect), and potentially a security question (Sentinel) simultaneously. Each persona has a different lens. The rule author decides which lens applies to which action type.
In practice, most actions never reach a persona. They're allowed automatically. The persona path is for edge cases: unusual combinations, novel action types, actions that match a rule flagged for human review. The path exists so that governance can escalate without becoming a bottleneck.
What Gatekeep does not do
It does not evaluate intent. It evaluates the proposed action: a specific operation on a specific resource. An agent that wants to write to a restricted path and frames it as "I need to update the config" will be denied because the action matches the path pattern. The reasoning is irrelevant to the enforcer.
It does not prevent prompt injection. If an agent is compromised and instructed to take harmful actions, Gatekeep will catch those actions that match rules. It won't catch novel harmful actions that no rule covers. The rules are maintained by a human. The humans decide what's in scope.
It does not replace testing. The governance layer is a runtime check, not a test suite. A deploy that passes Gatekeep evaluation can still fail. What Gatekeep provides is a consistent, auditable record that the governance check ran and what the verdict was.
Patterns demonstrated
- Guardrails and Safety (18): declarative JSON rules evaluated before every agent action
- Routing (2): persona dispatch routes violations to the appropriate reviewer
- Human-in-the-Loop (13): require_approval decisions gate on human sign-off
- Memory (8): audit ledger provides persistent record of all governance decisions
- MCP (10): governance exposed as a tool definition callable from any AI assistant
If the articles or tools have been useful, a coffee helps keep things running.
Working on something like this?
Fractional CTO and transformation leadership for situations that aren't working. Bring a problem — thirty minutes, no obligation.
Bring a problem → or scan a repo first →