---
title: "Boundary Enforcement"
description: "How to set up schema validation, guardrails, and budgets for POST /run and OpenAI-compatible /v1/* gateway traffic, with examples."
canonical: https://www.norcaster.com/docs/boundary-enforcement
---
<!-- Generated at build time from the rendered page by portal/scripts/generate-llms.mjs. The page is the source of truth; edit it, not this file. -->

Runtime boundary

# Schema validation, guardrails, and budgets

Norcaster runs these controls at the execution boundary: before a request reaches a provider model, native agent loop, retrieval path, or configured tool. Applies on `POST /run` and OpenAI-compatible `/v1/*` gateway routes with deployment binding (see [runtime protection overview](https://www.norcaster.com/docs/boundary-readiness)). This page shows how to set controls up via deployment config and test them.

## Schema validation

Checks the incoming JSON shape before the request reaches model, agent, retrieval, or tool execution.

## Guardrails

Apply policy actions such as block, warn, redact, or approve before risky downstream work runs.

## Budgets

Limit rate, compute time, and retry amplification so runaway traffic stops early.

## Audit

Records decisions, violation codes, traces, and payload evidence for review.

## Setup path

1. **1\. Define the boundary** — Pick the deployment or workflow entry point where Norcaster should evaluate a request before provider inference or tool execution.
2. **2\. Add schema validation** — Declare the JSON shape you expect. In strict mode, required fields must be present and unexpected fields are rejected instead of silently passing through.
3. **3\. Choose guardrail behavior** — Set violation actions such as block, warn, or redact. Use enforcement packs when you want a tested starting point for RAG, agents, privacy, or cost-sensitive traffic.
4. **4\. Add budget gates** — Limit request rate, compute seconds, and retry amplification before expensive model, agent, retrieval, or tool paths run.
5. **5\. Test both paths** — Run one valid payload and one invalid payload. Confirm the valid request continues and the invalid request records an enforcement event before inference.
6. **6\. Audit the result** — Review traces, violation codes, redaction summaries, budget outcomes, and the model or agent payload that reached the provider.

## Copyable examples

### Strict chat boundary

Use this when your app sends a simple prompt and you want unknown fields blocked.

```
{
  "pipeline_lock": {
    "contract_version": "1.0",
    "mode": "enforce",
    "schema": {
      "strict": true,
      "input_schema": {
        "type": "object",
        "required": ["prompt"],
        "properties": {
          "prompt": { "type": "string" }
        },
        "additionalProperties": false
      }
    },
    "policies": {
      "actions": {
        "on_violation": "block",
        "http_status": 400,
        "include_violation_context": true,
        "emit_event": true
      }
    }
  }
}
```

Valid: { "prompt": "Summarize this contract." } Blocked: { "prompt": "Summarize this contract.", "debug": true }

### Guardrails and budgets together

Use this when schema, policy, and cost controls should all run before the model call.

```
{
  "pipeline_lock": {
    "contract_version": "1.0",
    "mode": "enforce",
    "schema": {
      "strict": true,
      "input_schema": {
        "type": "object",
        "required": ["prompt", "user_tier"],
        "properties": {
          "prompt": { "type": "string" },
          "user_tier": { "type": "string", "enum": ["free", "pro", "enterprise"] }
        },
        "additionalProperties": false
      }
    },
    "policies": {
      "actions": { "on_violation": "block", "emit_event": true },
      "budget": {
        "request_rate_per_minute": 60,
        "max_compute_per_request_seconds": 120,
        "retry_cost_multiplier_ceiling": 2.0
      }
    }
  }
}
```

Valid: { "prompt": "Draft a reply.", "user\_tier": "pro" } Blocked: { "prompt": "Draft a reply.", "user\_tier": "trial" }

### Workflow privacy boundary

Use this when a workflow fetches external data and must redact it before provider inference.

```
{
  "workflow": "input -> mcp_input -> redact_text -> model -> output",
  "redact_text": {
    "fields": ["raw_tickets.text"],
    "patterns": ["email", "phone_se", "personnummer_se", "orgnumber_se"],
    "extra_patterns": ["\\+\\d{1,3}[\\s-]?\\d(?:[\\d\\s()-]{6,}\\d)"],
    "replacement": "[REDACTED]"
  },
  "model": {
    "deployment_id": "dep_support_summary",
    "prompt_field": "raw_tickets.text"
  }
}
```

Inspect the workflow run and confirm model\_request.messages contains redacted ticket text.

### Agent tool boundary

Use this when an agent can call tools, but only through configured functions with loop and budget limits.

```
{
  "agent": {
    "deployment_id": "dep_reasoning_model",
    "prompt_field": "question",
    "max_iterations": 4,
    "tools": [
      {
        "name": "lookup_account",
        "description": "Fetch account context",
        "input_schema": {
          "type": "object",
          "properties": { "account_id": { "type": "string" } },
          "required": ["account_id"]
        },
        "function": {
          "execution_type": "http",
          "method": "POST",
          "endpoint": "https://crm.internal/account",
          "body_template": { "account_id": "{account_id}" }
        }
      }
    ]
  }
}
```

Inspect agent\_steps to see each model request, tool call, function result, and final agent\_output.

## Website chat embed

Add a governed chat widget via script tag or npm adapters. Each send is an independent `POST /run`. Full guide: [Governed chat widget](https://www.norcaster.com/docs/chat-widget).

- **Script** — load `https://www.norcaster.com/chat/v1.js` with `data-deployment` and `data-api-key` (a key that can only run requests; see Security).
- **npm** — `@norcaster/chat-react`, `-vue`, or `-svelte` for framework apps.
- **Options** — `data-theme`, `data-greeting`, inline vs floating mode, and `data-run-url` for a same-origin proxy.
- **Security** — every visitor can read a browser key, so prefer `data-run-url`; otherwise use a key from the deployment's Connect tab or one with only`runs:write`. Add customer origins to API`CORS_ORIGINS`. Transcript UI is per-message (not full multi-turn memory).

## What to verify before production

- Invalid schema payloads are blocked or warned according to the configured mode.
- Budget gates stop excessive request rate, compute time, or retry amplification.
- Redaction or contextual policies run before external provider inference.
- Agent tools are configured functions, not arbitrary local code execution.
- Audit traces show the enforcement decision, violation details, and downstream payload evidence.
