Skip to content

feat(policy): shadow/monitor mode for MCPAccessGrants #307

@Agent-Hellboy

Description

@Agent-Hellboy

Summary

Add mode: monitor to MCPAccessGrant so operators can deploy governance rules without immediately blocking agents. The authz filter evaluates the full policy, lets the request through, but records would_deny: true in the audit event.

Motivation

Right now flipping a grant from allow→deny is instant and irreversible in production — you can't safely test a new policy rule without risk of breaking agents. Every serious enforcement platform has a dry-run/shadow mode (Kuma AllowWithShadowDeny, Envoy RBAC shadow_rules, Portkey log-only guardrails).

Pitch: "Deploy governance on day 1 without breaking a single agent. Watch what would be denied, then flip to enforce."

Implementation sketch

Policy schema

Add mode field to MCPAccessGrant:

type Grant struct {
    Name      string `json:"name"`
    Mode      string `json:"mode,omitempty"` // "enforce" (default) | "monitor"
    // ...existing fields
}

filter_authz.go

if !decision.Allowed {
    if grantIsMonitorMode(policy, decision.MatchedGrant) {
        ex.WouldDeny = true
        ex.WouldDenyReason = decision.Reason
        // fall through — request is allowed
    } else {
        return Deny(decision.Status, decision.Reason)
    }
}

exchange.go

Add fields to Exchange:

WouldDeny       bool
WouldDenyReason string

proxy.goauditPayload

if ex.WouldDeny {
    payload["would_deny"] = true
    payload["would_deny_reason"] = ex.WouldDenyReason
}

Acceptance criteria

  • mode: monitor grants allow all requests through
  • Audit events for monitor-mode denials include would_deny: true and would_deny_reason
  • mode: enforce (default) behaviour unchanged
  • pkg/policy.Validate rejects unknown mode values
  • Unit tests covering monitor vs enforce paths in authzFilter

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions