Skip to main content
Sign in →

Shadow Mode

Observe, measure, and validate security controls without blocking agent traffic — the safe path to full enforcement.

What Is Shadow Mode?

Shadow mode is a non-blocking evaluation pass. When enabled, the ShieldAgent proxy evaluates every tool call through the full policy engine and security pipeline — but does not block the request even if a deny rule matches. The decision is logged to the audit trail with a shadowDeny: true flag so you can review the impact before committing to enforcement.

Shadow mode ON: evaluate → log shadow_deny → allow (no block)
Shadow mode OFF: evaluate → block (deny enforced)

Default: shadow mode is on. New tenants and new agents start in shadow mode. This gives you visibility into what would be blocked before any agent traffic is disrupted.

Three-Level Cascade

Shadow mode is resolved from most specific to least specific — the first non-null value wins. This lets you enforce globally while keeping specific agents in observation mode, or vice versa.

1. Per-binding MCP server binding setting (nullable)
↓ if not set, fall through to agent level
2. Per-agent Agent-level setting (default: shadow on)
↓ if not set, fall through to tenant default
3. Tenant default Tenant settings in dashboard (default: shadow on)
LevelScopeHow to configure
Tenant defaultAll agents in the tenantSettings → Security → Shadow Mode toggle (or API)
Per-agentAll MCP server bindings for one agentPATCH /tenants/:tenantId/agents/:agentId {"shadowMode": false}
Per-bindingOne agent ↔ one MCP server connectionPATCH /tenants/:tenantId/agents/:agentId/mcp-bindings/:serverId {"shadowMode": false}

Shadow Events in the Audit Trail

Every shadow deny produces a full audit event so you can quantify the impact before switching to enforcement. Key fields:

FieldValue
outcome"shadow" — the call was allowed but would have been denied under enforcement
shadowDenytrue — policy engine determined this should be blocked
matchedRuleIdUUID of the first deny rule that matched; null for implicit deny
reasonHuman-readable explanation of which rule matched and why
json
{
  "id": "ae_...",
  "agentId": "...",
  "toolName": "bash",
  "outcome": "shadow",
  "shadowDeny": true,
  "matchedRuleId": "pol_...",
  "reason": "Rule 'deny bash rm -rf' matched on arguments.command",
  "timestamp": "2026-04-24T09:15:00.000Z"
}

Recommended Rollout

Shadow mode enables a safe, iterative path to full enforcement:

1

Start globally in shadow mode

The default. Deploy ShieldAgent and let all traffic flow through without blocking. Monitor the audit trail for shadow_deny events to understand what your agents are doing.

2

Author and test policies

Create deny rules via the dashboard or API. Because shadow mode is on, no traffic is disrupted. Use the audit trail to verify the rules match the intended tool calls.

3

Enforce per-agent as you validate

Once you are confident an agent's policies are correct, flip that agent to enforce mode: PATCH /agents/:id {"shadowMode": false}. Other agents remain in shadow mode.

4

Enforce globally when all agents are clean

Disable shadow mode at the tenant level in Settings → Security. Policy denials now block tool calls. Shadow mode can be re-enabled for specific agents at any time.

Monitoring Shadow Denies

Use the audit log to quantify impact before enforcing. Filter by outcome=shadow to see all shadow events, then group by matchedRuleId to see which rules fire most often.

bash
# List shadow deny events for a tenant (last 24h)
curl -s 'https://api.shieldagent.io/tenants/:tenantId/audit-events?outcome=shadow&limit=100' \
  -H 'Authorization: Bearer <token>'

# Check shadow mode status for an agent
curl -s 'https://api.shieldagent.io/tenants/:tenantId/agents/:agentId' \
  -H 'Authorization: Bearer <token>' | jq '.shadowMode'

API Reference

PATCH/tenants/:tenantId/agents/:agentIdSet {"shadowMode": false} to enforce for one agent
PATCH/tenants/:tenantId/agents/:agentId/mcp-bindings/:serverIdSet {"shadowMode": false} for a single agent ↔ server binding
GET/tenants/:tenantId/audit-events?outcome=shadowList all shadow deny events
GET/tenants/:tenantId/audit-events?shadowDeny=trueAlias — same result as outcome=shadow
Related: Shadow mode applies to policy engine denies. The DLP scanner and excessive agency detector have their own shadow/enforce modes configured separately. See DLP and Excessive Agency for details.