Docs · Policy DSL
Write policy in seconds, not hours.
AEGIS ships six grammar-constrained templates that cover the policy patterns guardrail products actually use. The AI generator produces these templates from a one-paragraph description + your tool inventory; the AJV validator self-tests them on the same shot.
The six templates
Each template compiles to a JSON Schema fragment applied to a tool call's arguments object.
-
forbid_argument
An argument MUST be absent or empty. Use for "no shell commands", "no raw SQL".
{ "kind": "forbid_argument", "field": "command" } -
require_pattern
An argument MUST match a regex (allowlist).
{ "kind": "require_pattern", "field": "url", "pattern": "^https://api\\.example\\.com/" } -
forbid_pattern
An argument MUST NOT match a regex (denylist).
{ "kind": "forbid_pattern", "field": "sql", "pattern": "DROP\\s+TABLE" } -
max_length
String length cap. Use for prompt-injection caps.
{ "kind": "max_length", "field": "note", "max": 4096 } -
enum_values
Argument MUST be one of a fixed set.
{ "kind": "enum_values", "field": "method", "allowed": ["GET", "HEAD"] } -
require_https
Argument MUST be an HTTPS URL.
{ "kind": "require_https", "field": "callback" }
Composite policies (AND / OR)
Combine multiple templates against the same call:
{
"all_of": true,
"templates": [
{ "kind": "require_https", "field": "url" },
{ "kind": "enum_values", "field": "method", "allowed": ["GET", "HEAD"] },
{ "kind": "max_length", "field": "body", "max": 4096 }
]
} Same-field templates fold into allOf (or anyOf if all_of=false).
DSL combinators (top-level)
Outside the template grammar, AEGIS exposes a small expression DSL for policies that key on classification / anomaly / agent identity:
{
"when": {
"all": [
{ "classifier.category": "shell" },
{ "anomaly.score": { ">": 0.7 } },
{ "agent.id": { "in": ["agent-x", "agent-y"] } }
]
},
"then": { "decision": "block", "reason": "shell + anomalous + risky agent" }
} Comparators: == != > < >= <= in matches. Combinators: all any not.
AI policy generator
Don't want to write templates by hand? Run the generator with a description + tool inventory + (optional) workflow graph:
POST /api/ai/generate-policy-bundle
{
"description": "Customer support copilot; never shell, never email outside our domain",
"tool_inventory": [
{ "name": "shell" }, { "name": "send_email" }, { "name": "search_kb" }
],
"workflow_graph": { /* from the scanner */ }
}
→ Returns: policies[] + DSL rules, each with should_block / should_allow tests AEGIS pre-runs through AJV. Self-testing
Every generated (or hand-written) policy ships with a tests block:
{
"id": "no-shell",
"policy_schema": { ... },
"tests": {
"should_block": [
{ "tool": "shell", "arguments": { "command": "rm -rf /" } }
],
"should_allow": [
{ "tool": "search_kb", "arguments": { "q": "refund policy" } }
]
}
} AEGIS compiles the schema, runs the tests, and rejects the policy if any assertion fails. No bad-actor-shaped policies ever land in production.
Counterfactual explainer
When a policy blocks a call, AEGIS computes the minimum edit that would have passed, re-runs the validator, and surfaces it in the audit:
{
"decision": "block",
"policy_name": "https-only",
"counterfactual": {
"any_suggestion": true,
"suggestions": [{
"description": "Change field \"url\" to a value matching ^https://",
"proposed_arguments": { "url": "https://example.com/x" },
"verified": true,
"fix_kind": "pattern"
}]
}
} Effectiveness scoring
Per-policy precision / recall / F1 over a rolling window. Cockpit surfaces a HEALTHY / TIGHTEN / RETIRE / PROBE signal so operators know which policies are noise vs catching real risk.