Skip to main content

Policy Engine API

Evaluate agent actions against YAML policies.

Functions

evaluateAction

Evaluate an agent action against a loaded policy.

function evaluateAction(
action: AgentAction,
policyPath: string
): Promise<PolicyDecision>

Parameters:

  • action: AgentAction — Action to evaluate
  • policyPath: string — Path to policy YAML file

Returns: Promise<PolicyDecision> — Policy evaluation result

Example:

import { evaluateAction } from '@shadow-executor/core';

const action = {
service: 'rds',
operation: 'DeleteDBInstance',
resource: 'arn:aws:rds:us-east-1:123456789012:db:prod-customer-data',
resource_tags: { Environment: 'production' },
timestamp: new Date().toISOString(),
};

const decision = await evaluateAction(action, './shadow-exec.policy.yaml');

console.log(`Action: ${decision.action}`);
console.log(`Reason: ${decision.reason}`);
console.log(`Rule: ${decision.matched_rule_id}`);

loadPolicy

Load and validate a policy YAML file.

function loadPolicy(policyPath: string): Promise<Policy>

Parameters:

  • policyPath: string — Path to policy YAML file

Returns: Promise<Policy> — Parsed and validated policy

Throws: Error if policy is invalid

Example:

import { loadPolicy } from '@shadow-executor/core';

const policy = await loadPolicy('./shadow-exec.policy.yaml');
console.log(`Policy: ${policy.name}`);
console.log(`Rules: ${policy.rules.length}`);

Types

AgentAction

interface AgentAction {
/** Service name (e.g., 'rds', 's3', 'iam') */
service: string;

/** Operation name in PascalCase (e.g., 'DeleteDBInstance') */
operation: string;

/** Resource ARN or identifier (optional) */
resource?: string;

/** Resource tags for matching (optional) */
resource_tags?: Record<string, string>;

/** Operation parameters (optional) */
parameters?: Record<string, unknown>;

/** IPI detection score 0.0-1.0 (optional, set by IPI detector) */
ipi_score?: number;

/** IPI class IDs (optional, set by IPI detector) */
ipi_class?: string[];

/** Agent identifier for tracking (optional) */
agent_id?: string;

/** ISO 8601 timestamp */
timestamp: string;
}

PolicyDecision

interface PolicyDecision {
/** Policy action to take */
action: PolicyAction;

/** Matched rule ID (null if no match) */
matched_rule_id: string | null;

/** Matched rule name (null if no match) */
matched_rule_name: string | null;

/** Human-readable reason for decision */
reason: string;

/** Original agent action */
agent_action: AgentAction;

/** Decision timestamp (ISO 8601) */
timestamp: string;

/** HMAC signature (set by audit logger, not policy engine) */
hmac?: string;
}

PolicyAction

type PolicyAction =
| "BLOCK" // Prevent execution
| "WARN" // Allow with warning
| "REQUIRE_APPROVAL" // Pause for human approval
| "BLOCK_AND_ALERT" // Block + send alert
| "LOG_ONLY"; // Log without enforcement

Policy

interface Policy {
/** Policy version (currently "1.0") */
version: string;

/** Policy name */
name: string;

/** List of policy rules */
rules: PolicyRule[];
}

PolicyRule

interface PolicyRule {
/** Unique rule identifier */
id: string;

/** Human-readable rule name */
name: string;

/** Rule severity level */
severity: "CRITICAL" | "HIGH" | "MEDIUM" | "LOW";

/** Action to take if rule matches */
action: PolicyAction;

/** Match conditions */
match: PolicyMatch;
}

PolicyMatch

interface PolicyMatch {
/** Service name (string or array) */
service?: string | string[];

/** Operation name (string or array, supports wildcards) */
operation?: string | string[];

/** Resource ARN (string, supports glob patterns) */
resource?: string;

/** Resource tags (all must match) */
resource_tags?: Record<string, string>;

/** IPI score threshold (e.g., ">= 0.7") */
ipi_score?: string;

/** IPI class IDs (array) */
ipi_class?: string[];
}

Rule Evaluation Logic

  1. Load policy: Parse and validate YAML
  2. Iterate rules: Process rules in order from top to bottom
  3. Check match conditions: For each rule, evaluate all match conditions
    • Service match (exact or in array)
    • Operation match (exact, in array, or wildcard)
    • Resource match (exact or glob pattern)
    • Resource tags match (all tags must match)
    • IPI score match (evaluate threshold expression)
    • IPI class match (any class in array)
  4. First match wins: Return action of first matching rule
  5. Default fallback: If no rule matches, return LOG_ONLY

Error Handling

Policy loading errors:

try {
const policy = await loadPolicy('./invalid.yaml');
} catch (error) {
console.error('Policy validation failed:', error.message);
// Error: Policy rule SE-001 missing required field 'action'
}

Policy evaluation never throws — it returns a decision:

const decision = await evaluateAction(action, './policy.yaml');

// Decision always has an action
if (decision.action === 'BLOCK') {
throw new Error(`Blocked by rule ${decision.matched_rule_id}`);
}

Source Code

Implementation: packages/core/src/policy/engine.ts

Tests: packages/core/src/policy/engine.test.ts

Next Steps