Policies & Governance
MCP Shield policies let you control exactly which AI tool operations are allowed, denied, or require approval. Combined with DLP rules, you get comprehensive governance.
Governance as Enablement
Policies aren't about blocking developers - they're about enabling AI tooling safely. Well-designed policies give teams confidence to use AI tools knowing that guardrails are in place.
Policy Types
Allow Policies
Explicitly permit specific MCP operations for users or groups.
Deny Policies
Block operations that match specific patterns or conditions.
Approval Policies
Require manual approval before high-risk operations execute.
Audit Policies
Enhanced logging for sensitive operations without blocking.
Policy Structure
Policies are defined in YAML with conditions and actions:
# Example: Allow developers to read from GitHub
name: dev-github-read
description: Allow developers to use GitHub read operations
priority: 100
enabled: true
conditions:
- user.role IN ['developer', 'engineer']
- mcp.provider == 'github'
- mcp.tool IN ['list_repos', 'get_repo', 'list_issues', 'get_file_contents']
action: allow
audit:
level: decision_summary # minimal, decision_summary, full_requestCondition Syntax
Conditions use a simple expression language to match requests:
| Expression | Description |
|---|---|
| user.email | User's email address |
| user.role | User's role (admin, developer, etc.) |
| user.groups | Array of user's groups |
| mcp.provider | Provider name (github, vercel, etc.) |
| mcp.tool | MCP tool name |
| mcp.input.* | Access to input fields |
| time.hour | Current hour (0-23) |
| time.weekday | Day of week (0-6, 0=Sunday) |
# Example conditions
conditions:
# Exact match
- user.role == 'admin'
# List membership
- mcp.tool IN ['list_repos', 'get_repo']
# Pattern matching
- mcp.input.repo MATCHES 'production-*'
# Logical operators
- user.role == 'developer' AND mcp.provider == 'github'
# Time-based
- time.weekday IN [1, 2, 3, 4, 5] # Weekdays onlyPolicy Evaluation
Policies are evaluated in priority order (lower number = higher priority):
- 1
Explicit Deny
If any deny policy matches, request is denied.
- 2
Explicit Allow
If an allow policy matches, request proceeds.
- 3
Default Deny
If no policy matches, request is denied by default.
Data Loss Prevention (DLP)
DLP rules scan requests and responses for sensitive data patterns:
# DLP configuration
dlp:
enabled: true
scan_requests: true
scan_responses: true
patterns:
- name: api_keys
pattern: '(api[_-]?key|apikey)["\':\s]*[a-zA-Z0-9]{20,}'
action: block
- name: aws_credentials
pattern: 'AKIA[0-9A-Z]{16}'
action: block
- name: emails
pattern: '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
action: redact
- name: phone_numbers
pattern: '\b\d{3}[-.]?\d{3}[-.]?\d{4}\b'
action: warn| Action | Behavior |
|---|---|
| block | Deny the entire request |
| redact | Replace matched content with [REDACTED] |
| warn | Log warning but allow request |
Policy Simulation
Test policies before deploying with the simulation feature:
mcp-shield policies simulate \
--mcp github:create_pull_request \
--user alice@company.com \
--input '{"repo": "production-api", "base": "main"}'
# Output:
# Policy Simulation Result:
# ┌───────────────┬──────────────────────────────────────┐
# │ Decision │ DENY │
# │ Policy │ block-production-writes │
# │ Reason │ Write operations to production │
# │ │ repositories require approval │
# │ Suggestion │ Request approval or use staging │
# └───────────────┴──────────────────────────────────────┘Example Policies
Block production deployments outside business hours
name: business-hours-deploys
description: Only allow deployments during business hours
priority: 10
conditions:
- mcp.provider == 'vercel'
- mcp.tool == 'deploy'
- mcp.input.environment == 'production'
- NOT (time.hour >= 9 AND time.hour < 17)
- NOT (time.weekday IN [1, 2, 3, 4, 5])
action: deny
message: "Production deployments are only allowed Mon-Fri 9am-5pm"Require approval for database mutations
name: db-mutation-approval
description: Require approval for database write operations
priority: 20
conditions:
- mcp.provider == 'supabase'
- mcp.tool IN ['insert', 'update', 'delete', 'execute_sql']
- mcp.input.table IN ['users', 'orders', 'payments']
action: require_approval
approvers:
- role: db_admin
- email: dba@company.com