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

# Enforce guardrails

> Switch to Enforce mode to block risky actions and require human approval before execution.

You've observed guardrail evaluations in Monitor mode. Now you need to actually stop a production deploy or secret read before it happens. **Enforce mode** applies guardrail decisions — blocks halt execution, and approval requirements pause until a human resolves them in the dashboard.

When you finish this page, blocked actions will throw before your callback runs, and approval-required actions will wait for dashboard resolution.

## Switch to Enforce mode

<CodeGroup>
  ```ts TypeScript theme={null}
  const apie = new Apie({
    agent: { key: "my-agent", name: "My Agent" },
    mode: "enforce",
    guardFailureMode: "fail_closed",
  });
  ```

  ```python Python theme={null}
  apie = Apie.create({
      "agent": {"key": "my-agent", "name": "My Agent"},
      "mode": "enforce",
      "guard_failure_mode": "fail_closed",
  })
  ```
</CodeGroup>

## Guard decisions in Enforce mode

| Decision           | Enforce behavior                                                          |
| ------------------ | ------------------------------------------------------------------------- |
| `allow`            | Proceed                                                                   |
| `warn`             | Proceed, log warning                                                      |
| `block`            | Throw — callback never runs                                               |
| `require_approval` | Emit approval event, wait for dashboard resolution, then proceed or throw |

### What you'll see

Blocked actions appear as failed tool calls in the run timeline with the matched guardrail and block reason. Approval-required actions show a pending approval in the dashboard.

In session replay, runtime intelligence can summarize the blocked or approval-required action and link the story card back to the related guardrail decision or approval request. Use that summary for review, but treat the guardrail decision itself as the authoritative runtime outcome.

## Guard failure modes

When the guard API itself fails (network error, timeout), `guardFailureMode` controls behavior:

| Mode                  | Behavior                         |
| --------------------- | -------------------------------- |
| `fail_open` (default) | Allow the action — log a warning |
| `fail_closed`         | Treat as blocked                 |
| `throw`               | Throw an error immediately       |

For production enforcement, use `fail_closed`:

<CodeGroup>
  ```ts TypeScript theme={null}
  guardFailureMode: "fail_closed"
  ```

  ```python Python theme={null}
  "guard_failure_mode": "fail_closed"
  ```
</CodeGroup>

## Complete enforcement example

<CodeGroup>
  ```ts TypeScript theme={null}
  const apie = await Apie.create({
    agent: { key: "release-gate", name: "Release Gate" },
    mode: "enforce",
    guardFailureMode: "fail_closed",
    runtime: { environment: "production" },
  });

  await apie.withRun({ inputSummary: "Production deploy attempt" }, async (run) => {
    try {
      await apie.withTool(
        {
          runId: run.id,
          tool: { name: "deploy.release", provider: "cicd", riskLevel: "high" },
          action: { type: "execute", name: "deploy.release" },
          resource: { type: "deployment_event", environment: "production" },
        },
        async () => deploy(),
      );
    } catch (error) {
      // Guard blocked the deploy — handle gracefully
      console.error("Deploy blocked by guardrail:", error);
    }
  });
  ```

  ```python Python theme={null}
  apie = Apie.create({
      "agent": {"key": "release-gate", "name": "Release Gate"},
      "mode": "enforce",
      "guard_failure_mode": "fail_closed",
      "runtime": {"environment": "production"},
  })

  def attempt_deploy(run):
      try:
          apie.with_tool(
              {
                  "runId": run.id,
                  "tool": {"name": "deploy.release", "provider": "cicd", "riskLevel": "high"},
                  "action": {"type": "execute", "name": "deploy.release"},
                  "resource": {"type": "deployment_event", "environment": "production"},
              },
              lambda: deploy(),
          )
      except Exception as error:
          print(f"Deploy blocked by guardrail: {error}")

  apie.with_run({"inputSummary": "Production deploy attempt"}, attempt_deploy)
  ```
</CodeGroup>

## MCP proxy Enforce mode

Set `mode: "enforce"` in `apie.mcp.json` to enforce guardrails on MCP tool calls without changing agent code. Blocked calls return JSON-RPC error `-32001`. See [MCP enforcement recipe](/recipes/mcp-enforcement).

## Prerequisites for Enforce mode

Before enabling Enforce mode in production:

1. [Declare capabilities](/boundaries/declare-capabilities) for all expected tools
2. [Enable guardrail templates](/guardrails/enable-guardrail-templates)
3. Provide explicit `action`, `resource`, and `riskLevel` metadata — don't rely on inference alone
4. Configure [human approval](/guardrails/human-approval) timeouts

## Next steps

<CardGroup cols={2}>
  <Card title="Human approval" icon="user-check" href="/guardrails/human-approval">
    Pause execution for dashboard approval.
  </Card>

  <Card title="Runtime intelligence walkthrough" icon="book-open" href="/recipes/runtime-intelligence-walkthrough">
    See the user-facing story for a production release session.
  </Card>

  <Card title="Monitor mode" icon="eye" href="/guardrails/monitor-mode">
    Observe before you enforce.
  </Card>
</CardGroup>
