sec0-sdk/middleware is the in-process enforcement layer for tool servers. It wraps any McpServerLike server, evaluates policy on every tool invocation, emits signed audit envelopes, and can delegate final allow or deny decisions to either the local runtime adapter or a remote runtime service.
Use it when you want to secure a tool server inside the same process as your application. For outbound messages, raw API calls, or other application-level checks that are not naturally wrapped as server calls, use Guard API.
Choose an Entrypoint
The public middleware surface has three integration styles:| API | Use it when |
|---|---|
sec0SecurityMiddleware(options) | You want full control over adapters and runtime wiring |
sec0LocalMiddleware(options) | You want a zero-control-plane integration for local policy, local runtime decisions, and local audit |
sec0HostedMiddleware(options) | You want control-plane policy fetch, approval verification, escalation creation, and optional remote runtime evaluation |
createLocalSec0Preset(...)createHostedSec0Preset(...)
Local Preset
Use the local preset first unless you already need hosted policy or approvals:- a static policy provider
- a local runtime adapter
- a local audit sink
- no-op approval verification and escalation reporting
Hosted Preset
Switch to the hosted preset when policy should come from the control plane or when denies need approval verification and escalation creation:- policy can be fetched from the control plane
- approval verification can be delegated to the control plane
- escalation creation can be delegated to the control plane
- runtime decisions can stay local or be delegated to a remote runtime endpoint
auth is the credential used for policy and approval APIs. The top-level apiKey option is separate and only helps auto-wire audit uploads when you are not supplying sec0.presign yourself.
Full-Control Wiring with sec0SecurityMiddleware
Use the base entrypoint when you need custom adapter implementations:
sec0-sdk/core.
What the Middleware Enforces
When the wrapper is installed, the middleware:- Freezes the tool registry and blocks handler swaps after wrapping.
- Hashes server and handler source to detect version or code drift.
- Evaluates policy on every
callTool. - Applies optional Agent Guard, compliance, skill scan, SAST, and DAST hooks.
- Emits a signed audit envelope for allow and deny outcomes.
- Adds escalation metadata when the deny reason is configured for escalation.
tool_not_in_allowlistversion_unpinnedmissing_idempotency_for_side_effectagent_guard_failedserver_code_changedtool_code_changedskill_scan_failedsast_faileddast_failed
Policy Sources
policy accepts three shapes:
- a parsed
PolicyObject - a YAML string
- a control-plane source descriptor
scope: "base" when the same middleware policy applies to every node. Use scope: "agent" or scope: "auto" when the executing nodeId should influence policy lookup.
Remote Runtime Decisions
By default, middleware decisions are evaluated locally. To move final allow or deny resolution behind a remote service:failureMode: "local" keeps a local fallback when the remote runtime is unavailable. allow and deny are available when you want fail-open or fail-closed behavior instead.
Crossing a Network Boundary
When tool execution crosses a network boundary, use the bridge function:agentState payload, use callToolViaGatewayWithAgent(...) instead.