This quickstart uses the current developer entrypoints in sec0-sdk:
sec0-sdk/middleware for in-process tool enforcement
sec0-sdk/instrumentation for hop decorators and agent-state propagation
sec0-sdk/guard for outbound allow, redact, block, and escalate decisions
sec0-sdk/middleware plus sec0-sdk/gateway for cross-network tool calls
Prerequisites
- Node.js >= 20
- An Ed25519 signing key
- A local
policy.yaml
- Optional: a Sec0 API key when you switch to hosted policy or approvals
1. Install the SDK
2. Generate a Signing Key
mkdir -p .sec0/keys
openssl rand -base64 32 > .sec0/keys/ed25519.key
Store your signing key securely. If you keep the key outside default safe directories (.sec0/keys, keys, config/keys, .sec0/secrets, secrets), set SEC0_SIGNER_KEY_DIRS.
3. Create a Minimal policy.yaml
Start with a local, observe-mode policy:
tenant: my-app
default_retention: "30d"
signing:
enabled: true
key_ref: "file://./.sec0/keys/ed25519.key"
observability:
otlp_endpoint: "http://127.0.0.1:4318"
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://unused-local-dev"
For a first integration, use the local preset. It keeps policy, runtime decisions, approvals, and audit writes on-device.
import fs from "node:fs";
import { parsePolicyYaml } from "sec0-sdk/policy";
import { LocalDevSigner } from "sec0-sdk/signer";
import { sec0LocalMiddleware } from "sec0-sdk/middleware";
const server = createYourMcpServer();
const policy = parsePolicyYaml(fs.readFileSync("./policy.yaml", "utf8"));
sec0LocalMiddleware({
policy,
signer: LocalDevSigner.fromKeyRef(policy.signing.key_ref),
otel: {
endpoint: policy.observability.otlp_endpoint,
serviceName: "orders-mcp",
serviceVersion: "1.0.0",
environment: "dev",
tenant: policy.tenant,
},
sec0: { dir: ".sec0", retentionDays: 30 },
telemetry: { enabled: false },
})(server);
When you need hosted policy, approvals, or remote runtime evaluation, switch the same server to sec0HostedMiddleware. See Middleware.
Instrumentation uses sec0.config.yaml to resolve hop identity, gateway defaults, and local storage:
app:
tenant: my-app
environment: dev
client:
name: my-agent-runtime
version: "1.0.0"
hops:
Workflow.orchestrate:
type: orchestrator
nodeId: workflow-orch
orchestratorName: workflow-orch
orchestratorVersion: "1.0.0"
OrderAgent.run:
type: agent
nodeId: order-agent
agentName: order-agent
agentVersion: "1.0.0"
Gateway.forward:
type: gateway
nodeId: workflow-gateway
gateway: sec0-gateway
gatewayBaseUrl: https://gateway.example.com
automation:
auth: true
cause: true
idempotency: true
auth:
svcToken: ${SVC_TOKEN}
sec0ApiKey: ${SEC0_API_KEY}
controlPlane:
sec0Dir: ./.sec0
localSignerPath: ./.sec0/keys/ed25519.key
appenderDir: ./.sec0/logs
6. Initialize Decorators and Propagate Agent State
Decorators give you stable nodeId, runId, state propagation, and signed audit envelopes across agent hops:
import { initializeSec0App, sec0, AgentManager } from "sec0-sdk/instrumentation";
initializeSec0App("./sec0.config.yaml");
class OrderAgent {
@sec0.agent()
async run(ctx: any, input: { orderId: string }, manager: AgentManager) {
manager.agent.setState({ order_id: input.orderId });
manager.agent.setMetadata({ received_at: Date.now() });
const headers = manager.getAgentStateHeaders();
await fetch("https://api.example.com/process-order", {
method: "POST",
headers,
body: JSON.stringify({ orderId: input.orderId }),
});
return { ok: true };
}
}
class Workflow {
@sec0.orchestrator()
async orchestrate(ctx: any, input: any, manager: AgentManager) {
manager.agent.objective("Plan and execute the order workflow safely.");
await manager.invoke("OrderAgent.run", {
orderId: input.orderId,
});
return { ok: true };
}
}
7. Add Guard Checks for Outbound Messages or API Calls
Use sec0-sdk/guard when the action is not naturally wrapped by the middleware, or when you want a simple allow, redact, block, and escalate API in application code:
import { createSec0Guard } from "sec0-sdk/guard";
const guard = createSec0Guard({
mode: "standalone",
provider: {
local: {
policy: {
defaultOutcome: "allow",
rules: [
{
kind: "message_outbound",
target: "discord:supplier",
outcome: "block",
reason: "supplier_messages_require_review",
},
],
},
},
},
});
await guard.execute(
{
kind: "message_outbound",
target: "discord:supplier",
content: outboundMessage,
},
async () => sendToSupplier(outboundMessage),
);
See Guard API for dashboard and hybrid modes, redaction, and approvals transport wiring.
Use the bridge helper when tool execution crosses a process or network boundary:
import { callToolViaGateway } from "sec0-sdk/middleware";
const result = await callToolViaGateway({
gatewayBaseUrl: "https://gateway.example.com",
server: "payments-mcp",
toolAtVersion: "charge@1.0",
args: { amount: 4999, currency: "usd" },
authHeader: `Bearer ${process.env.SVC_TOKEN}`,
cause: { traceId: ctx.traceId, spanId: ctx.spanId },
agentState: manager.agent.snapshot(),
timeoutMs: 15_000,
});
Use Gateway Bridge for client options and Network Gateway to deploy the server side.
9. Switch to Hosted Policy and Approvals When Ready
Replace the local preset with the hosted preset when you want control-plane policy sync, escalation creation, or remote runtime evaluation:
import { sec0HostedMiddleware } from "sec0-sdk/middleware";
import { LocalDevSigner } from "sec0-sdk/signer";
sec0HostedMiddleware({
policy: {
source: "control-plane",
level: "middleware",
scope: "auto",
refreshTtlMs: 60_000,
},
auth: { apiKey: process.env.SEC0_API_KEY! },
signer: LocalDevSigner.fromKeyRef("file://./.sec0/keys/ed25519.key"),
otel: {
endpoint: "http://127.0.0.1:4318",
serviceName: "orders-mcp",
serviceVersion: "1.0.0",
environment: "dev",
tenant: "my-app",
},
sec0: { dir: ".sec0", retentionDays: 30 },
})(server);
Then configure enforcement.escalate_on plus security.side_effects.human_escalation and connect the approvals bridge. See Approvals & Escalations.
10. Verify
Use the Verify & Troubleshoot checklist to confirm each layer is working.
What’s Next?
Middleware
Wrap tool servers and choose local vs hosted presets
Guard API
Gate outbound messages, tool calls, and APIs
Instrumentation
Register hops, decorators, and propagation
Gateway
Add network-edge enforcement and brokering