Skip to main content
Sec0 can escalate high-risk actions instead of silently allowing them or hard-blocking them. The same approval policy model is used across:
  • sec0-sdk/middleware
  • sec0-sdk/gateway
  • hop decorators in sec0-sdk/instrumentation
  • sec0-sdk/guard

Example Policy

Define escalation behavior with enforcement.escalate_on and security.side_effects.human_escalation:
enforcement:
  deny_on: [egress_violation, fs_violation, missing_idempotency_for_side_effect]
  escalate_on: [egress_violation, fs_violation]

security:
  side_effects:
    approve_high_risk: true
    human_escalation:
      approval_strategy: human_quorum
      timeout_action: auto_reject
      min_approvals: 2
      min_rejections: 1
      required_roles: [security, ops]
      veto_roles: [security]
      approval_set_id: prod-reviewers
If enforcement.escalate_on is omitted, the same reasons from enforcement.deny_on are used.

What Happens At Runtime

  1. A Sec0-enforced hop detects a policy violation and reaches a deny path.
  2. If approve_high_risk: true and the violation is in escalate_on, Sec0 creates an escalation.
  3. Middleware, gateway, and decorator denies include escalation_id and escalation_status.
  4. sec0-sdk/guard can either return the pending escalation or wait for final resolution.

Generic Escalation Manager

Use sec0-sdk/escalation when your application already knows when to escalate and just needs a production-grade create/get/resolve/wait flow that is not tied to Guard or OpenClaw:
import { createEscalationManager } from "sec0-sdk/escalation";

const escalation = createEscalationManager({
  apiKey: process.env.SEC0_API_KEY!,
  controlPlaneUrl: process.env.SEC0_CONTROL_PLANE_URL,
  tenant: process.env.SEC0_TENANT_ID,
  timeoutMs: 5 * 60_000,
  pollIntervalMs: 2000,
  defaults: {
    ttlSeconds: 300,
    timeoutAction: "auto_reject",
  },
});

const { created, resolution } = await escalation.createAndWait(
  {
    content: outboundMessage,
    violation: "agent_guard_failed",
    message: "Approval required before sending",
    severity: "high",
    nodeId: "merchant-agent",
    agentRef: "run-42",
  },
  { timeoutMs: 120_000 },
);
This is the shared approvals primitive used by higher-level integrations. Use create(...), get(...), resolve(...), or waitForResolution(...) directly when your app needs finer control.

Guard + Approvals Bridge

Use the approvals bridge transport from sec0-sdk/guard when escalations should fan out to Discord or Telegram via the open-source bridge worker:
import {
  createApprovalsBridgeTransport,
  createSec0Guard,
} from "sec0-sdk/guard";

const guard = createSec0Guard({
  mode: "dashboard",
  provider: {
    remote: {
      auth: { apiKey: process.env.SEC0_API_KEY! },
      source: { source: "control-plane", level: "middleware", scope: "base" },
    },
  },
  escalation: {
    waitForResolutionByDefault: true,
    timeoutMs: 5 * 60_000,
  },
  transport: createApprovalsBridgeTransport({
    bridgeUrl: process.env.SEC0_APPROVALS_BRIDGE_URL!,
    tenantId: process.env.SEC0_TENANT_ID!,
    bearerToken: process.env.SEC0_APPROVALS_BRIDGE_TOKEN,
    sharedSecret: process.env.SEC0_APPROVALS_BRIDGE_SHARED_SECRET,
  }),
});
Deploy apps/sec0-approvals-bridge as the reference worker, or fork it to add your own channels and routing.

OpenClaw / Moltbot

If you are using sec0-sdk/integrations/openclaw, pair createMoltbotHooks(...) with createMoltbotEscalationManager(...). That helper now delegates to the same shared sec0-sdk/escalation manager, so you can inject a prebuilt manager when you want one approvals lifecycle shared across OpenClaw and non-OpenClaw code paths. See OpenClaw Integration.

Strategy Fields

  • approval_strategy:
    • auto_allow: allow immediately.
    • single_approver: first valid human vote decides.
    • human_quorum: wait for configured thresholds.
  • timeout_action:
    • auto_approve: approve on expiry.
    • auto_reject: reject on expiry.
  • min_approvals and min_rejections: quorum thresholds.
  • required_roles: roles that must approve before final approval.
  • veto_roles: roles that can force rejection.
  • approval_set_id: optional reviewer-group selector.

Troubleshooting

  • no_approvers_configured: policy requires human review but no reviewer set is resolved.
  • Frequent timeout outcomes: lower quorum thresholds or increase reviewer availability.
  • Missing escalation IDs on denied calls: verify approve_high_risk is true and the violation is in escalate_on (or deny_on when escalate_on is omitted).

References