> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sec0.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Middleware Options Reference

> Developer-facing sec0-sdk/middleware configuration for wrapping a tool server.

`sec0SecurityMiddleware(...)` is the main Sec0 integration point for a tool server. This page keeps the configuration a developer normally sets in an application and leaves adapter internals out of the main reference path.

## Minimal shape

```typescript theme={null}
import { sec0SecurityMiddleware } from "sec0-sdk/middleware";
import { LocalDevSigner } from "sec0-sdk/signer";

sec0SecurityMiddleware({
  policy: {
    source: "control-plane",
    scope: "auto",
  },
  signer: LocalDevSigner.fromKeyRef("file://./.sec0/keys/ed25519.key"),
  otel: {
    endpoint: process.env.OTLP_ENDPOINT!,
    serviceName: "orders-server",
    serviceVersion: "1.0.0",
    environment: "dev",
    tenant: "my-app",
  },
  sec0: {
    dir: ".sec0",
    retentionDays: 30,
  },
  controlPlaneUrl: process.env.SEC0_URL,
  auth: { apiKey: process.env.SEC0_API_KEY },
});
```

Preset wrappers are also available:

* `sec0LocalMiddleware(...)` for local defaults
* `sec0HostedMiddleware(...)` for control-plane defaults

## MiddlewareOptions

| Key               | Type                                                    | Required | Description                                           |
| ----------------- | ------------------------------------------------------- | -------- | ----------------------------------------------------- |
| `policy`          | `PolicyObject`, `string`, or `ControlPlanePolicySource` | Yes      | Policy object, YAML string, or remote policy source   |
| `signer`          | `Signer`                                                | Yes      | Signer used for audit envelopes                       |
| `otel`            | `OTelConfig`                                            | Yes      | Trace export settings                                 |
| `sec0`            | `Sec0Config`                                            | Yes      | Local audit storage settings                          |
| `controlPlaneUrl` | string                                                  | No       | Policy server base URL                                |
| `apiKey`          | string                                                  | No       | Convenience API key for audit upload discovery        |
| `auth`            | object                                                  | No       | API key or bearer token for policy fetch              |
| `runtime`         | object                                                  | No       | Runtime evaluation mode and remote evaluator settings |
| `telemetry`       | object                                                  | No       | Turn middleware tracing on or off                     |
| `ap2`             | object                                                  | No       | AP2 mandate handling                                  |
| `sast`            | object                                                  | No       | Static analysis controls                              |
| `dast`            | object                                                  | No       | Dynamic analysis controls                             |
| `agentGuard`      | object                                                  | No       | Prompt/output/run guard settings                      |

The full internal adapter, raw-payload, and envelope extension hooks are intentionally left out of this page. Most app integrations do not need them.

## policy

Accepted forms:

* `PolicyObject`: parsed policy object
* `string`: YAML policy loaded at runtime
* `ControlPlanePolicySource`: fetch policy from the control plane

### ControlPlanePolicySource

| Key              | Type                             | Required | Description                                              |
| ---------------- | -------------------------------- | -------- | -------------------------------------------------------- |
| `source`         | `"control-plane"`                | Yes      | Remote policy source selector                            |
| `level`          | `"gateway"` or `"middleware"`    | No       | Policy tier to fetch. Default is `"middleware"`          |
| `scope`          | `"base"`, `"agent"`, or `"auto"` | No       | Scope resolution mode                                    |
| `nodeId`         | string                           | No       | Default `nodeId` when runtime state is missing it        |
| `fallbackToBase` | boolean                          | No       | Fall back to workspace policy when agent policy is empty |
| `refreshTtlMs`   | number                           | No       | Policy cache TTL in milliseconds. `0` fetches every call |

See [Agent Scoped Policies](/docs/reference/agent-scoped-policies) for how `scope`, `nodeId`, and `fallbackToBase` affect runtime policy lookup.

## signer

If you provide a custom signer, it must match this shape:

| Member  | Type                                         | Description                                |                                       |
| ------- | -------------------------------------------- | ------------------------------------------ | ------------------------------------- |
| `keyId` | string                                       | Key identifier written into audit metadata |                                       |
| `sign`  | \`(data: Uint8Array) => Promise\<Uint8Array> | Uint8Array\`                               | Signs the canonicalized payload bytes |

For local development, use `LocalDevSigner.fromKeyRef(...)` from [Signer & Tracing Reference](/docs/reference/signer-otel).

## otel

| Key                   | Type   | Required | Description                    |
| --------------------- | ------ | -------- | ------------------------------ |
| `otel.endpoint`       | string | Yes      | OTLP collector endpoint        |
| `otel.serviceName`    | string | Yes      | Service name                   |
| `otel.serviceVersion` | string | No       | Service version                |
| `otel.environment`    | string | No       | Deployment environment         |
| `otel.tenant`         | string | No       | Tenant or workspace identifier |

## sec0

| Key                  | Type   | Required | Description                  |
| -------------------- | ------ | -------- | ---------------------------- |
| `sec0.dir`           | string | Yes      | Local audit directory        |
| `sec0.retentionDays` | number | No       | Local retention in days      |
| `sec0.presign`       | object | No       | Hosted audit upload settings |

### sec0.presign

| Key                          | Type   | Required | Description                   |
| ---------------------------- | ------ | -------- | ----------------------------- |
| `sec0.presign.apiBaseUrl`    | string | No       | Upload API base URL           |
| `sec0.presign.auditKey`      | string | Yes      | Audit API key or bearer token |
| `sec0.presign.tenant`        | string | No       | Tenant hint                   |
| `sec0.presign.clientName`    | string | No       | Client name hint              |
| `sec0.presign.clientVersion` | string | No       | Client version hint           |
| `sec0.presign.environment`   | string | No       | Environment hint              |
| `sec0.presign.timeoutMs`     | number | No       | Upload timeout override       |

## apiKey and auth

`apiKey` is a convenience option. When it is set and `sec0.presign` is omitted, Sec0 can auto-discover hosted audit upload settings.

Use `auth` when policy fetch should use explicit credentials:

| Key                | Type   | Required | Description                   |
| ------------------ | ------ | -------- | ----------------------------- |
| `auth.apiKey`      | string | No       | API key for policy fetch      |
| `auth.bearerToken` | string | No       | Bearer token for policy fetch |

## runtime

The main runtime setting most developers care about is remote evaluation:

### runtime.enforcement

| Key                                         | Type                              | Required | Description                                 |
| ------------------------------------------- | --------------------------------- | -------- | ------------------------------------------- |
| `runtime.enforcement.mode`                  | `"local"` or `"remote"`           | No       | Runtime adapter mode. Default is local      |
| `runtime.enforcement.protocolVersion`       | string                            | No       | Runtime protocol version override           |
| `runtime.enforcement.failureMode`           | `"local"`, `"allow"`, or `"deny"` | No       | Fallback behavior when remote runtime fails |
| `runtime.enforcement.remote.endpoint`       | string                            | No       | Remote runtime evaluate endpoint            |
| `runtime.enforcement.remote.timeoutMs`      | number                            | No       | Remote call timeout                         |
| `runtime.enforcement.remote.maxRetries`     | number                            | No       | Retry count                                 |
| `runtime.enforcement.remote.retryBackoffMs` | number                            | No       | Retry backoff base                          |
| `runtime.enforcement.remote.headers`        | object                            | No       | Extra request headers                       |
| `runtime.enforcement.remote.apiKey`         | string                            | No       | API key sent to the remote runtime          |

## telemetry

| Key                 | Type    | Required | Description                           |
| ------------------- | ------- | -------- | ------------------------------------- |
| `telemetry.enabled` | boolean | No       | Disable to turn off middleware traces |

## ap2

| Key                          | Type      | Required | Description                          |
| ---------------------------- | --------- | -------- | ------------------------------------ |
| `ap2.enabled`                | boolean   | No       | Enable AP2 mandate checks            |
| `ap2.requireForSideEffects`  | boolean   | No       | Require AP2 for side-effecting tools |
| `ap2.headers.intent`         | string    | No       | Header name for intent mandate       |
| `ap2.headers.cart`           | string    | No       | Header name for cart mandate         |
| `ap2.headers.bundle`         | string    | No       | Header name for bundle               |
| `ap2.trust.didMethods`       | string\[] | No       | Allowed DID methods                  |
| `ap2.trust.issuersAllowlist` | string\[] | No       | Allowed issuers                      |
| `ap2.trust.clockSkewSec`     | number    | No       | Clock skew in seconds                |
| `ap2.tools.allow`            | string\[] | No       | Tool allowlist for AP2 checks        |

## sast

| Key                              | Type                                   | Required | Description                               |
| -------------------------------- | -------------------------------------- | -------- | ----------------------------------------- |
| `sast.enabled`                   | boolean                                | No       | Enable SAST                               |
| `sast.block_on_change`           | boolean                                | No       | Block while a new scan result is pending  |
| `sast.block_on_severity`         | `low`, `medium`, `high`, or `critical` | No       | Deny threshold                            |
| `sast.cache_ttl_ms`              | number                                 | No       | Result cache TTL                          |
| `sast.scan_all_on_server_change` | boolean                                | No       | Rescan all tools when server code changes |

## dast

| Key                      | Type                                   | Required | Description                              |
| ------------------------ | -------------------------------------- | -------- | ---------------------------------------- |
| `dast.enabled`           | boolean                                | No       | Enable DAST                              |
| `dast.block_on_change`   | boolean                                | No       | Block while a new scan result is pending |
| `dast.block_on_severity` | `low`, `medium`, `high`, or `critical` | No       | Deny threshold                           |
| `dast.block_on_count`    | number                                 | No       | Deny when findings reach this count      |
| `dast.sandbox_url`       | string                                 | No       | DAST sandbox URL                         |
| `dast.templates`         | string                                 | No       | Template path                            |
| `dast.tags`              | string\[]                              | No       | Included scanner tags                    |
| `dast.exclude_tags`      | string\[]                              | No       | Excluded scanner tags                    |
| `dast.severity`          | string\[]                              | No       | Severity filter                          |
| `dast.mode`              | `"sync"` or `"async"`                  | No       | Whether middleware waits for the scan    |
| `dast.scope`             | `"server"` or `"tool"`                 | No       | Scan scope                               |

## agentGuard

| Key                                     | Type                                              | Required | Description                         |
| --------------------------------------- | ------------------------------------------------- | -------- | ----------------------------------- |
| `agentGuard.enabled`                    | boolean                                           | No       | Enable Agent Guard                  |
| `agentGuard.block_on_severity`          | `unknown`, `low`, `medium`, `high`, or `critical` | No       | Deny threshold                      |
| `agentGuard.block_on_count`             | number                                            | No       | Deny when findings reach this count |
| `agentGuard.pii_patterns`               | string\[]                                         | No       | Override PII patterns               |
| `agentGuard.secret_patterns`            | string\[]                                         | No       | Override secret patterns            |
| `agentGuard.prompt_injection_patterns`  | string\[]                                         | No       | Override prompt injection patterns  |
| `agentGuard.dangerous_commands`         | string\[]                                         | No       | Override dangerous command patterns |
| `agentGuard.toxicity_patterns`          | string\[]                                         | No       | Override toxicity patterns          |
| `agentGuard.malicious_code_patterns`    | string\[]                                         | No       | Override malicious code patterns    |
| `agentGuard.policy_violation_patterns`  | string\[]                                         | No       | Override policy violation patterns  |
| `agentGuard.data_exfiltration_patterns` | string\[]                                         | No       | Override exfiltration patterns      |
| `agentGuard.run_context`                | object                                            | No       | Run-context capture limits          |
| `agentGuard.adapters`                   | array                                             | No       | External scanner adapter chain      |

### agentGuard.adapters\[]

| Key          | Type                                                  | Required    | Description                       |
| ------------ | ----------------------------------------------------- | ----------- | --------------------------------- |
| `type`       | `"nemo"`, `"guardrails"`, `"llmguard"`, or `"custom"` | Yes         | Adapter type                      |
| `serviceUrl` | string                                                | Conditional | Required for hosted adapter types |

### agentGuard.run\_context

| Key                 | Type    | Required | Description                      |
| ------------------- | ------- | -------- | -------------------------------- |
| `enabled`           | boolean | No       | Enable run-context scanning      |
| `max_chars`         | number  | No       | Max total chars collected        |
| `max_events`        | number  | No       | Max events collected             |
| `max_event_chars`   | number  | No       | Max chars per event              |
| `max_runs`          | number  | No       | Max cached runs                  |
| `ttl_ms`            | number  | No       | Cache TTL                        |
| `include_objective` | boolean | No       | Include objective in run context |
| `include_metadata`  | boolean | No       | Include metadata in run context  |
