Skip to content

Policy Engine Integration Guide — AIGP with Cedar, Rego, and Beyond

Policy Engine Integration Guide — AIGP with Cedar, Rego, and Beyond

PRIVATE AND PROPRIETARY. Owned by Kanjani AI Research & Causum. See NOTICE.md.

Status: Guide Author: Kanjani AI Research & Causum Date: July 2026 Audience: Enterprise architects, security engineers, policy teams evaluating AIGP for AI governance


Executive Summary

AIGP facilitates enforcement but does not mandate a policy language. This is a deliberate architectural decision rooted in interoperability, concern diversity, and separation of mechanism from governance.

Organizations already invested in Cedar, Rego, Sentinel, OPA, or custom policy engines can integrate them directly into AIGP’s governance stages without modification to the protocol. AIGP defines what must be decided and proved. The policy engine defines how the decision is made.

This guide explains:

  1. Why AIGP is policy-language agnostic
  2. How any policy engine integrates at the enforcement layer
  3. Specific integration patterns for AWS Cedar (Verified Permissions), OPA/Rego, and HashiCorp Sentinel
  4. What changes and what stays the same regardless of engine choice

1. Why AIGP Does Not Mandate a Policy Language

1.1 The Interoperability Argument

A governance protocol earns adoption by being implementable without rip-and-replace. The moment AIGP mandates Cedar, it loses:

  • Every organization invested in OPA/Rego (dominant in Kubernetes-native environments)
  • Every organization using HashiCorp Sentinel (Terraform/Vault ecosystems)
  • Every regulated entity with custom policy engines approved by their compliance teams
  • Every environment where the policy engine is dictated by procurement, not engineering

A protocol that requires one vendor’s language is not a protocol. It is a product integration guide. AIGP is a protocol.

1.2 The Concern Diversity Argument

Policy languages were designed for authorization — who can access what, under which conditions. Cedar excels at this. Rego excels at this.

But AIGP governs across 26 stages that span far beyond authorization:

Stage Governance Concern Nature of Decision
1 Identity & Session Authentication
2 Consent & Policy Data governance
3 Request Registration Audit trail
5 Prompt Assembly Content governance
7 Context Retrieval Data access control
8 Model Selection Risk classification
9 Runtime Invocation Budget/cost governance
13 Output Release Content safety
17 Reflection & Optimization Quality measurement
19 Delegation Scope Authority boundaries
21 Tool Authorization Access control
23 Autonomy Boundary Risk thresholds
25 Session Termination State management

Authorization policies (Cedar, Rego) are natural for stages 7, 10, 19, 21. But stages 9 (budget enforcement), 13 (content safety), 17 (quality measurement), and 23 (autonomy boundaries) require numeric thresholds, time-series analysis, ML-based detection, or statistical models — none of which are expressible in a policy language.

AIGP cannot mandate a language that covers only 30% of its governance surface. Instead, it defines the decision interface that any mechanism — policy engine, ML model, threshold check, or human approval — can implement.

1.3 The Separation Principle

AIGP separates three concerns that are often conflated:

Concern What it means Who owns it
Governance structure Which stages exist, what evidence they produce AIGP protocol (fixed)
Policy logic What rules apply at each stage Organization’s policy engine (flexible)
Enforcement behavior What happens when a rule fires (log, alert, block) Governance mode (TRACE/REPORT/ENFORCE)

This separation means:

  • Changing your policy engine does not change your governance structure
  • Changing your enforcement mode does not change your policies
  • Changing your policies does not change what evidence is produced

The protocol is stable. The policy engine is pluggable. The behavior is configurable.


2. The Integration Architecture

2.1 Decision Interface

Every AIGP governance stage produces a decision with the following interface:

Decision {
stage: int # Which stage (1-26)
decision: ALLOW | DENY # Binary outcome
reason: string # Human-readable explanation
policy_ref: string # Which policy/rule produced this decision
attributes: map # Context (what was evaluated)
duration_ms: int # How long evaluation took
status: OK | ERROR # Whether evaluation itself succeeded
}

This interface is what AIGP requires. How the decision is produced — Cedar evaluation, Rego query, Python function, manual approval, ML inference — is invisible to the protocol.

2.2 Integration Point

The policy engine is called inside the GovernanceEnforcer at each relevant stage:

┌─────────────────────────────────────────────────────────┐
│ AIGP Protocol Layer (fixed) │
│ ┌─────────────────────────────────────────────────┐ │
│ │ GovernanceEnforcer │ │
│ │ │ │
│ │ Stage 21: tool_authorization_runtime │ │
│ │ ↓ │ │
│ │ ┌────────────────────────────────┐ │ │
│ │ │ Policy Engine Adapter │ ← pluggable │ │
│ │ │ (Cedar / Rego / Custom) │ │ │
│ │ └────────────────────────────────┘ │ │
│ │ ↓ │ │
│ │ Decision(ALLOW/DENY, reason, policy_ref) │ │
│ │ ↓ │ │
│ │ AIGP records span with decision + attributes │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘

2.3 Adapter Pattern

Each policy engine integration implements a simple adapter:

class PolicyEngineAdapter(Protocol):
"""Interface that any policy engine must implement."""
async def evaluate(
self,
stage: int,
principal: str, # Who is acting (user, agent, service)
action: str, # What action (invoke_model, call_tool, access_data)
resource: str, # What resource (model_id, tool_name, kb_id)
context: dict, # Additional context (tokens, session, history)
) -> Decision:
"""Evaluate policy and return ALLOW/DENY decision."""
...

The GovernanceEnforcer calls this adapter at each stage. The adapter translates into whatever query format the underlying engine requires.


3. Cedar Integration (AWS Verified Permissions)

3.1 Why Cedar Is a Natural Fit

Cedar was designed for fine-grained authorization with:

  • Strongly typed entities (principals, actions, resources)
  • Hierarchical permissions (groups, roles, inheritance)
  • Attribute-based conditions
  • Fast evaluation (sub-millisecond)
  • Formal verification (provable policy properties)

These properties map directly to AIGP’s authorization stages (10, 19, 21).

3.2 Entity Model

Map AIGP concepts to Cedar entities:

// Principal types
entity User;
entity Agent;
entity Service;
// Action types
action "invoke_model";
action "call_tool";
action "access_knowledge_base";
action "delegate_to_agent";
action "exceed_token_budget";
// Resource types
entity Model;
entity Tool;
entity KnowledgeBase;
entity Agent;

3.3 Example Policies

Stage 21 — Tool Authorization:

// Only allow graph_query tool for the graph_query_agent
permit(
principal == Agent::"graph_query_agent",
action == Action::"call_tool",
resource == Tool::"graph_query"
);
// Deny all file-system tools for any agent
forbid(
principal,
action == Action::"call_tool",
resource
) when {
resource in Tool::"filesystem_tools"
};

Stage 19 — Delegation Scope:

// Allow delegation only within the same department
permit(
principal,
action == Action::"delegate_to_agent",
resource
) when {
principal.department == resource.department &&
principal.delegation_depth < 3
};

Stage 8 — Model Selection:

// Only allow approved models for production workloads
permit(
principal,
action == Action::"invoke_model",
resource
) when {
resource in Model::"approved_production_models" &&
context.environment == "production"
};
// Deny high-cost models for non-critical use cases
forbid(
principal,
action == Action::"invoke_model",
resource
) when {
resource.cost_tier == "high" &&
context.use_case.criticality < 3
};

3.4 Adapter Implementation

import boto3
from typing import Any
class CedarAdapter:
"""AIGP policy adapter backed by AWS Verified Permissions (Cedar)."""
def __init__(self, policy_store_id: str, region: str = "us-east-1"):
self.client = boto3.client("verifiedpermissions", region_name=region)
self.policy_store_id = policy_store_id
async def evaluate(
self,
stage: int,
principal: str,
action: str,
resource: str,
context: dict,
) -> Decision:
"""Evaluate Cedar policy via Verified Permissions."""
# Map AIGP stage to Cedar action
cedar_action = self._map_action(stage, action)
request = {
"policyStoreId": self.policy_store_id,
"principal": {"entityType": "Agent", "entityId": principal},
"action": {"actionType": "Action", "actionId": cedar_action},
"resource": {"entityType": self._resource_type(stage), "entityId": resource},
"context": {"contextMap": self._flatten_context(context)},
}
import time
t0 = time.time()
response = self.client.is_authorized(**request)
duration_ms = int((time.time() - t0) * 1000)
decision = "ALLOW" if response["decision"] == "ALLOW" else "DENY"
determining_policies = response.get("determiningPolicies", [])
policy_ref = determining_policies[0]["policyId"] if determining_policies else ""
return Decision(
stage=stage,
decision=decision,
reason=f"Cedar {decision}: {len(determining_policies)} policies evaluated",
policy_ref=policy_ref,
attributes={
"principal": principal,
"action": cedar_action,
"resource": resource,
"engine": "cedar/verified-permissions",
},
duration_ms=duration_ms,
status="OK",
)
def _map_action(self, stage: int, action: str) -> str:
"""Map AIGP stage + action to Cedar action ID."""
stage_actions = {
8: "invoke_model",
10: "call_tool",
19: "delegate_to_agent",
21: "call_tool",
}
return stage_actions.get(stage, action)
def _resource_type(self, stage: int) -> str:
"""Determine Cedar resource type from stage."""
return {8: "Model", 10: "Tool", 19: "Agent", 21: "Tool"}.get(stage, "Resource")
def _flatten_context(self, context: dict) -> dict:
"""Flatten nested context for Cedar contextMap."""
flat = {}
for k, v in context.items():
if isinstance(v, (str, int, float, bool)):
flat[k] = {"string": str(v)} if isinstance(v, str) else {"long": v}
return flat

3.5 Registration in GovernanceEnforcer

from .adapters.cedar import CedarAdapter
class GovernanceEnforcer:
def __init__(self, policy: dict):
self.policy = policy
# Use Cedar for authorization stages, default for others
self.cedar = CedarAdapter(
policy_store_id=policy.get("cedar_policy_store_id", ""),
) if policy.get("cedar_policy_store_id") else None
async def evaluate_stage(self, stage: int, **kwargs) -> Decision:
"""Route to appropriate policy engine per stage."""
if self.cedar and stage in (8, 10, 19, 21):
return await self.cedar.evaluate(stage=stage, **kwargs)
else:
# Default: threshold checks, allowlists, budget checks
return self._default_evaluate(stage, **kwargs)

4. OPA/Rego Integration

4.1 Why Rego

OPA (Open Policy Agent) with Rego is dominant in:

  • Kubernetes-native environments
  • Infrastructure-as-code pipelines
  • Organizations with existing OPA investments
  • Multi-cloud environments (cloud-agnostic by design)

4.2 Example Policies

Stage 21 — Tool Authorization:

package aigp.stage21
default allow = false
allow {
input.principal == "graph_query_agent"
input.resource in data.allowed_tools[input.principal]
}
# Deny dangerous tools globally
deny {
input.resource in data.dangerous_tools
}
# Final decision
decision = "ALLOW" {
allow
not deny
}
decision = "DENY" {
deny
}
decision = "DENY" {
not allow
}

Stage 23 — Autonomy Boundary (token budget):

package aigp.stage23
default decision = "ALLOW"
decision = "DENY" {
input.context.tokens_used_today > data.limits[input.principal].daily_max
}
decision = "DENY" {
input.context.tokens_this_invocation > data.limits[input.principal].per_invocation_max
}
reason = msg {
decision == "DENY"
msg := sprintf("Token budget exceeded: %d/%d daily",
[input.context.tokens_used_today, data.limits[input.principal].daily_max])
}

4.3 Adapter Implementation

import httpx
import time
class OPAAdapter:
"""AIGP policy adapter backed by Open Policy Agent."""
def __init__(self, opa_url: str = "http://localhost:8181"):
self.opa_url = opa_url
async def evaluate(
self,
stage: int,
principal: str,
action: str,
resource: str,
context: dict,
) -> Decision:
"""Evaluate OPA/Rego policy."""
package = f"aigp/stage{stage}"
payload = {
"input": {
"principal": principal,
"action": action,
"resource": resource,
"context": context,
}
}
t0 = time.time()
async with httpx.AsyncClient(timeout=2.0) as client:
resp = await client.post(
f"{self.opa_url}/v1/data/{package}",
json=payload,
)
duration_ms = int((time.time() - t0) * 1000)
result = resp.json().get("result", {})
decision = result.get("decision", "DENY")
reason = result.get("reason", "")
return Decision(
stage=stage,
decision=decision,
reason=reason or f"OPA {decision}",
policy_ref=f"rego:{package}",
attributes={
"principal": principal,
"action": action,
"resource": resource,
"engine": "opa/rego",
},
duration_ms=duration_ms,
status="OK",
)

5. HashiCorp Sentinel Integration

5.1 When Sentinel Makes Sense

Sentinel is the right choice when:

  • The organization uses Terraform/Vault/Consul/Nomad
  • Policy enforcement is already in the HashiCorp stack
  • Cost governance ties into Terraform plan approval

5.2 Example Policy

import "aigp"
# Stage 9: Enforce model cost limits
main = rule {
aigp.stage == 9 and
aigp.context.estimated_cost_usd <= 1.00 and
aigp.context.model_id in approved_models
}
approved_models = [
"us.anthropic.claude-sonnet-4-6",
"us.anthropic.claude-3-haiku-20240307-v1:0",
"us.amazon.nova-lite-v1:0",
]

6. Custom/Hybrid Integration

6.1 The Common Pattern

Most organizations will use a hybrid approach:

Stage Engine Rationale
8 (Model Selection) Cedar Fine-grained model access control
9 (Runtime Invocation) Custom threshold Token/cost budget is a numeric check
10, 21 (Tool Auth) Cedar or Rego Authorization is their strength
13 (Output Release) ML model (Guardrails) Content safety needs ML, not rules
19 (Delegation Scope) Cedar Hierarchical authority
23 (Autonomy Boundary) Custom threshold Budget/error-rate is numeric
26 (Post-Session Audit) Custom analytics Statistical analysis, not policy

This is natural. AIGP does not force a single engine because no single engine covers all governance concerns.

6.2 Routing Configuration

{
"policy_engines": {
"cedar": {
"type": "cedar",
"policy_store_id": "ps-abc123",
"stages": [8, 10, 19, 21]
},
"opa": {
"type": "opa",
"url": "http://opa.internal:8181",
"stages": [7]
},
"default": {
"type": "builtin",
"stages": [1, 2, 3, 5, 9, 13, 14, 17, 23, 26]
}
}
}

7. What Stays the Same Regardless of Engine

No matter which policy engine (or combination) is used, AIGP guarantees:

Invariant Description
Evidence schema Every decision produces the same span structure in the trace
Audit trail Every decision is recorded with timestamp, policy_ref, and reason
Governance modes TRACE (log only), REPORT (log + alert), ENFORCE (block) work identically
Cross-organizational comparison Two organizations using different engines but the same Dialect produce comparable governance postures
D-DNA integrity Evidence is cryptographically signed regardless of what produced the decision
Temporal chaining Decisions form an immutable chain regardless of engine
Framework compliance EU AI Act, NIST RMF, ISO 42001 mapping remains valid regardless of engine

This is the value of separating governance structure from policy logic: the evidence is portable even when the mechanism is not.


8. Migration Path

For organizations evaluating AIGP with an existing policy engine:

Phase 1: Observe (Week 1)

  • Deploy AIGP in TRACE mode (no enforcement)
  • Use built-in allowlist checks (no external engine needed)
  • See what your AI systems do, which stages fire, what evidence looks like

Phase 2: Connect (Week 2-3)

  • Implement the adapter for your existing engine (Cedar, OPA, etc.)
  • Route authorization stages (10, 19, 21) to your engine
  • Keep TRACE mode — log decisions but don’t block

Phase 3: Enforce (Week 4+)

  • Switch to ENFORCE mode on stages where policies are proven
  • Monitor DENY rates, false positives
  • Tune policies based on evidence (the reinforcement loop)

Phase 4: Extend (Ongoing)

  • Add policies for new stages as you understand your governance surface
  • Subscribe to Dialects that provide stage-specific measurement models
  • Graduate from authorization-only to full-lifecycle governance

9. Frequently Asked Questions

Q: If I use Cedar, do I need to rewrite my Cedar policies for AIGP? A: No. Your existing Cedar policies work unchanged. The adapter translates AIGP stage context into Cedar authorization requests. You may add new policies for AI-specific decisions, but existing access control policies remain as-is.

Q: Can I use different engines for different stages? A: Yes, this is the expected pattern. Authorization stages → Cedar/Rego. Budget stages → numeric thresholds. Content safety → ML models. AIGP routes to the appropriate engine per stage.

Q: Does AIGP add latency to my policy evaluation? A: AIGP adds the time to record the decision (microseconds). The policy evaluation time is your engine’s latency, which AIGP measures and records (the duration_ms field) but does not add to.

Q: What if my policy engine is down? A: The GovernanceEnforcer handles this per your configuration:

  • Fail-open: Allow the action, record that evaluation failed (status=ERROR)
  • Fail-closed: Deny the action, trigger circuit breaker (Stage 26)
  • Fallback: Use the built-in allowlist as a degraded-mode evaluator

Q: Can I verify that my Cedar policies cover all required AIGP stages? A: Yes. The AIGP conformance tests include a “policy coverage” check that verifies every stage in your subscribed Dialect has a mapped evaluator (Cedar, OPA, custom, or built-in). Uncovered stages are flagged.

Q: How does this relate to AWS Verified Permissions specifically? A: AWS Verified Permissions is a managed Cedar service. The CedarAdapter calls the IsAuthorized API. This means:

  • No self-hosted Cedar engine to manage
  • IAM-integrated authentication
  • CloudTrail audit of all policy evaluations (in addition to AIGP’s own trace)
  • Policy versioning and management via AWS console or API

10. Summary

AIGP’s relationship to policy engines is architectural, not competitive:

AIGP defines what governance looks like. Your policy engine decides what governance does.

The protocol provides:

  • The 26-stage lifecycle (where decisions happen)
  • The evidence schema (how decisions are recorded)
  • The enforcement modes (what decisions mean)
  • The trust substrate (how decisions are verified)

Your policy engine provides:

  • The rules (what is allowed/denied)
  • The logic (how rules are evaluated)
  • The language (how rules are expressed)
  • The management (how rules are updated)

Both are necessary. Neither replaces the other. AIGP without a policy engine has no rules. A policy engine without AIGP has no governance lifecycle, no evidence trail, and no cross-organizational comparability.

The protocol governs. The engine decides. The evidence proves.


Appendix: Supported Stages by Engine Type

Stage Name Cedar Rego Sentinel ML Model Threshold Manual
1 Identity & Session
2 Consent & Policy
3 Request Registration
5 Prompt Assembly
7 Context Retrieval
8 Model Selection
9 Runtime Invocation
10 Tool/Agent Auth
13 Output Release
14 Post-Invocation Record
17 Reflection & Optimization
19 Delegation Scope
21 Tool Auth (Runtime)
23 Autonomy Boundary
26 Post-Session Audit

✓ = Natural fit for this engine type. Empty = possible but not the typical choice.


AIGP is owned by Kanjani AI Research & Causum. Registered with the U.S. Copyright Office (Case #1-15160968741, #1-15180695311). Patent-pending. Commercial licensing available exclusively through Causum.