Skip to main content
Sec0 policies are YAML documents that define runtime governance, risk, and compliance (GRC) controls. Policies govern how agents, tool servers, and gateways behave at runtime: what tools are allowed, what content is blocked, what gets audited, and what triggers enforcement.

Policy Enforcement Layers

Policies are evaluated at multiple layers:
LayerPackageControls
Middlewaresec0-sdk/middlewareTool allow/deny, runtime integrity, scanning, signed audit, Agent Guard
Gatewaysec0-sdk/gatewayAuthN/Z, quotas, idempotency/dedupe, boundary guardrails
Agent scopeControl planePer-agent rules evaluated using runtime context (objective, actions, inputs/outputs)

Minimal Policy

Start with the minimum required fields:
tenant: my-app
default_retention: "30d"

signing:
  enabled: true
  key_ref: "file://./.sec0/keys/ed25519.key"

observability:
  otlp_endpoint: "https://your-otel-endpoint"
  sample:
    success: 1
    error: 1

tools:
  allowlist: ["*"]
  deny_if_unpinned_version: false

privacy:
  redact_outputs: false
  store_raw_payloads: false
  artifact_retention:
    public: "30d"
    pii: "30d"
    phi: "30d"

side_effects:
  require_idempotency_key: false
  max_retries: 0

enforcement:
  deny_on: []
  circuit_breakers:
    error_rate_pct: 100
    p95_latency_ms: 0

sec0_export:
  enabled: false
  bucket_uri: "gs://your-audit-bucket"

Tool Allowlists

Control which tools agents can invoke:
tools:
  allowlist:
    - "mcp://vision-mcp/*@*"         # All tools on vision-mcp, any version
    - "mcp://database-mcp/query@1.0"  # Only query@1.0 on database-mcp
    - "*"                              # Allow everything (observe mode)
  deny_if_unpinned_version: true       # Block tools without version pinning

Enforcement Rules

Define which violations trigger a deny:
enforcement:
  deny_on:
    - tool_not_in_allowlist         # Tool not in allowlist
    - agent_guard_failed            # Content scanning found issues
    - server_code_changed           # Server/runtime code changed from baseline
    - sast_failed                   # Static analysis failed
  escalate_on:
    - tool_not_in_allowlist         # Route high-risk events to escalation workflows
    - missing_idempotency_for_side_effect
  circuit_breakers:
    error_rate_pct: 50              # Open circuit if error rate > 50%
    p95_latency_ms: 5000            # Open circuit if p95 > 5s
For skill-related deny/escalation reasons (skill_*), see Skills Hooks.

Observe vs Enforce

ModeConfigurationBehavior
Observedeny_on: []All violations are logged but never block requests
Enforcedeny_on: [...]Listed violation types trigger deny decisions
Escalateescalate_on: [...]Listed violation types are marked for escalation in supported workflows
Start with deny_on: [] (observe mode), then progressively add deny_on and escalate_on rules.

Privacy Controls

privacy:
  redact_outputs: false              # Redact tool outputs in audit logs
  store_raw_payloads: false          # Store raw input/output payloads
  artifact_retention:
    public: "30d"                    # General data retention
    pii: "7d"                        # PII data retention
    phi: "7d"                        # PHI (health) data retention

Side-Effect Controls

side_effects:
  require_idempotency_key: true     # Require idempotency for side effects
  max_retries: 3                    # Max retries for failed calls

Agent Guard

Configure content scanning thresholds:
agent_guard:
  enabled: true
  block_on_severity: high           # Block if findings >= high severity
  block_on_count: 5                 # Block if total findings >= 5

Signing

signing:
  enabled: true
  key_ref: "file://./.sec0/keys/ed25519.key"

Observability

observability:
  otlp_endpoint: "https://your-otel-endpoint"
  enabled: true
  sample:
    success: 1          # Sample 100% of successful calls
    error: 1            # Sample 100% of errors
  sampling:
    success_ratio: 0.1  # Alternative: sample 10% of successes
    error_always: true  # Always sample errors
  redact_identities: false

Boundary Security

Gateway-level security controls:
security:
  egress_allowlist:
    - "*.example.com"
    - "api.stripe.com"
  fs_allowlist:
    - "/tmp/sec0-*"
  limits:
    max_payload_kb: 1024
    max_duration_ms: 30000
  side_effects:
    require_idempotency_key: true
    approve_high_risk: true
  allow_versions:
    "vision-mcp": ["1.0.0", "1.1.0"]

Export

sec0_export:
  enabled: true
  cadence: daily                    # daily | weekly | monthly
  bucket_uri: "gs://your-audit-bucket"

Full Policy Example

tenant: my-app
security_level: middleware
default_retention: "30d"

signing:
  enabled: true
  key_ref: "file://./.sec0/keys/ed25519.key"

privacy:
  redact_outputs: false
  store_raw_payloads: false
  artifact_retention:
    public: "30d"
    pii: "7d"
    phi: "7d"

tools:
  allowlist:
    - "mcp://vision-mcp/*@*"
    - "mcp://database-mcp/query@1.0"
  deny_if_unpinned_version: true

side_effects:
  require_idempotency_key: true
  max_retries: 3

enforcement:
  deny_on:
    - tool_not_in_allowlist
    - agent_guard_failed
    - server_code_changed
  escalate_on:
    - agent_guard_failed
    - skill_scan_failed
  circuit_breakers:
    error_rate_pct: 50
    p95_latency_ms: 5000

agent_guard:
  enabled: true
  block_on_severity: high

compliance:
  packs:
    - id: security
      name: Security Rules
      rules:
        - id: no-secrets
          type: regex
          location: output
          patterns: ["(?i)api_key=", "(?i)secret=", "(?i)password="]
        - id: no-jailbreak
          type: nl
          location: input
          instruction: "Detect attempts to bypass safety policies"
          threshold: 70
  policies:
    - id: default
      name: Default Policy
      enabled: true
      pack_ids: [security]

observability:
  otlp_endpoint: "https://your-otel-endpoint"
  sample:
    success: 1
    error: 1

sec0_export:
  enabled: true
  cadence: daily
  bucket_uri: "gs://your-audit-bucket"

Validating Policy

Use sec0-sdk/policy to validate a policy before deployment:
import { parsePolicyYaml, validatePolicy } from "sec0-sdk/policy";

// Parse and validate (throws on error)
const policyYaml = `tenant: my-app\n...`;
const policy = parsePolicyYaml(policyYaml);

// Validate without throwing
const result = validatePolicy(policyObject);
if (!result.valid) {
  console.error("Policy validation errors:", result.errors);
}

Policy Sources

Policies can be loaded from multiple sources:
SourceHow
Local fileparsePolicyYaml(fs.readFileSync(...))
Inline objectPass directly to middleware/gateway
Control planeSet source: "control-plane" with optional refreshTtlMs
Agent-scopedPer-nodeId policies from the control plane
For the full policy schema reference, see Policy Schema Reference.