MCP Compliance Integration
Overview
This skill secures Model Context Protocol (MCP) integrations used by the compliance agent. MCP servers expose tools (Playwright browser automation, Postgres queries, Slack notifications, Presidio DLP) to the agent runtime. Misconfiguration creates pathways for ePHI exfiltration, unauthorized CDE access, and unlogged actions.
Security baseline:
- OAuth 2.1 with PKCE for user-delegated MCP access
- Tool allowlists—principle of least functionality
- TLS 1.2+ for all MCP transport
- Structured audit logging without cleartext PHI (see
audit-logging-integrity)
- BAA coverage for MCP operators processing ePHI (see
hipaa-baa-vendor-assessment)
When to Use
Use this skill when:
- Deploying new MCP servers for compliance workflows
- Auditing existing MCP configurations (scopes, tools, network placement)
- Implementing OAuth 2.1 + PKCE for MCP authorization
- Defining tool sets per role (auditor vs read-only vs emergency)
- Integrating Playwright, Postgres, Slack, Presidio MCP patterns from this repository
- Incident response for compromised MCP tokens or rogue tools
Do not use this skill when:
- Writing PCI script inventory logic (use
pci-dss-script-audit—references Playwright MCP)
- Presidio entity tuning without MCP (use
hipaa-phi-redaction-pipeline)
- Enterprise vendor risk programs without MCP (use
vendor-third-party-risk)
Core Process
Execute steps in order.
Step 1: MCP server inventory
- List all MCP servers connected to compliance agent:
| Server |
Package/source |
Data sensitivity |
Operator |
| Playwright |
@playwright/mcp |
URLs, DOM (may contain PHI in page) |
Self/hosted |
| Postgres |
Official/community postgres MCP |
Query results (PHI/CDE risk) |
Self/hosted |
| Slack |
Slack MCP |
Messages (notification only) |
Vendor |
| Presidio |
Custom/REST wrapper |
Raw text (PHI) |
Self/hosted |
- Document version, deployment location, network zone, BAA status.
- Artifact:
mcp-inventory-{id}.json.
Step 2: OAuth 2.1 and PKCE configuration
- Register OAuth client per MCP server with:
- Exact redirect URI allowlist (no wildcards)
- Authorization code flow with PKCE S256 (OAuth 2.1 requirement)
- Short-lived access tokens (≤1 hour) and refresh token rotation
- Prohibit implicit flow and password grant.
- Bind tokens to audience (specific MCP server resource identifier).
- Test: authorization without PKCE challenge → must fail.
Step 3: Tool set design (least functionality)
For each MCP server, define role-based tool sets:
Playwright MCP pattern (PCI 6.4.3 / 11.6.1)
- Allowed tools:
browser_navigate, browser_snapshot, browser_take_screenshot
- URL allowlist: payment page URLs only—block
file://, internal IPs unless scoped
- Prohibited: arbitrary JavaScript execution beyond documented audit scripts
- Evidence: DOM snapshots stored with SHA-256; no PAN fields in stored HTML if avoidable
Postgres MCP pattern (baselines, evidence)
- Read-only role on
compliance schema only
- Prohibited:
DROP, UPDATE, production PHI/CDE tables
- Parameterized queries only; no arbitrary SQL from model without template allowlist
- Row limits on exports (e.g., max 10,000 rows)
Slack MCP pattern (SOC alerts)
- Channel allowlist:
#soc-alerts, #compliance-audit—no DMs to personal accounts
- Message template: URL, diff summary, severity—no raw ePHI or PAN
- Prohibited: file uploads containing evidence bundles with PHI
Presidio MCP pattern (DLP)
- Mirror
redaction.py entity types and thresholds
- Process locally where possible—avoid sending text to third-party Presidio SaaS without BAA
- Do not log input text in MCP server logs
- Fail closed if Presidio unavailable—agent must not bypass redaction
Step 4: Transport and network security
- Enforce HTTPS/TLS 1.2+ for remote MCP; mTLS for sidecar deployments.
- Place MCP servers in dedicated subnet; NSC rules per
pci-dss-network-segmentation.
- No MCP admin interfaces on public Internet without VPN/ZTNA.
Step 5: Authentication and session binding
- Map MCP OAuth identity to agent session correlation_id.
- Revoke tokens on session end.
- Service-to-service MCP: use workload identity (SPIFFE, cloud IAM)—not static API keys in
agent.py.
Step 6: Logging and monitoring
- Log per tool invocation:
timestamp, actor, tool_name, resource, result, correlation_id.
- Exclude raw tool arguments containing PHI from logs—or encrypt at field level.
- Alert on: new tool registered, auth failure spike, Postgres query outside allowlist.
Step 7: Deployment and change control (CC8)
- MCP server updates via CI/CD with
compliance-as-code-governance policy scans.
- Pin MCP server versions; hash container images.
- Require approval for tool manifest changes.
Step 8: Compliance testing
- Negative tests:
- Attempt disallowed URL in Playwright → deny
- Attempt SQL write via Postgres MCP → deny
- Attempt Slack post to non-allowlisted channel → deny
- Positive tests: PCI script audit workflow end-to-end with evidence hashes.
- Document results in
mcp-security-test-{id}.json.
Common Rationalizations
| Excuse the agent might generate |
Required rebuttal |
| "MCP is local, OAuth is unnecessary overhead." |
Local MCP still processes sensitive data—authentication and tool allowlists prevent lateral abuse from compromised agent. |
| "Postgres MCP needs write for convenience." |
Write access to evidence DB must use separate controlled pipeline—not general MCP write tools. |
| "Slack alerts need full DOM for context." |
Full DOM may contain PHI/PAN—send diff summaries and artifact IDs only. |
| "PKCE is optional for confidential clients." |
OAuth 2.1 mandates PKCE for all clients—including confidential. |
| "We trust the model to pick safe tools." |
Models are not authorization layers—enforce tool sets server-side. |
| "Presidio MCP can fall back to no redaction." |
Fail closed—unredacted PHI to LLM is a critical violation. |
Red Flags
- MCP server accepts connections without authentication
- Postgres MCP connected to production CDE or clinical database
- Playwright MCP without URL allowlist (arbitrary navigation)
- Slack MCP posting evidence with cleartext PHI
- OAuth redirect URI wildcard (
https://*.example.com/callback)
- MCP server logs store full tool arguments
- New MCP tool added without change ticket and security review
Verification
1---2name: mcp-compliance-integration3description: Hardens Model Context Protocol (MCP) server integrations for compliance—OAuth 2.1, PKCE, scoped tool sets, transport security, and patterns for Playwright, Postgres, Slack, and Presidio MCP servers in audit workflows. Trigger when deploying, configuring, or auditing MCP servers for HIPAA, PCI, or SOC 2 agent architectures. Do not use for general IAM reviews without MCP focus (use access-control-identity-audit) or PCI script DOM audits (use pci-dss-script-audit).4---56# MCP Compliance Integration78## Overview910This skill secures **Model Context Protocol (MCP)** integrations used by the compliance agent. MCP servers expose **tools** (Playwright browser automation, Postgres queries, Slack notifications, Presidio DLP) to the agent runtime. Misconfiguration creates pathways for **ePHI exfiltration, unauthorized CDE access, and unlogged actions**.1112Security baseline:1314- **OAuth 2.1** with **PKCE** for user-delegated MCP access15- **Tool allowlists**—principle of least functionality16- **TLS 1.2+** for all MCP transport17- **Structured audit logging** without cleartext PHI (see `audit-logging-integrity`)18- **BAA coverage** for MCP operators processing ePHI (see `hipaa-baa-vendor-assessment`)1920## When to Use2122Use this skill when:2324- **Deploying** new MCP servers for compliance workflows25- **Auditing** existing MCP configurations (scopes, tools, network placement)26- Implementing **OAuth 2.1 + PKCE** for MCP authorization27- Defining **tool sets** per role (auditor vs read-only vs emergency)28- Integrating **Playwright, Postgres, Slack, Presidio** MCP patterns from this repository29- **Incident response** for compromised MCP tokens or rogue tools3031Do **not** use this skill when:3233- Writing PCI script inventory logic (use `pci-dss-script-audit`—references Playwright MCP)34- Presidio entity tuning without MCP (use `hipaa-phi-redaction-pipeline`)35- Enterprise vendor risk programs without MCP (use `vendor-third-party-risk`)3637## Core Process3839Execute steps **in order**.4041### Step 1: MCP server inventory42431. List all MCP servers connected to compliance agent:4445| Server | Package/source | Data sensitivity | Operator |46| --- | --- | --- | --- |47| Playwright | `@playwright/mcp` | URLs, DOM (may contain PHI in page) | Self/hosted |48| Postgres | Official/community postgres MCP | Query results (PHI/CDE risk) | Self/hosted |49| Slack | Slack MCP | Messages (notification only) | Vendor |50| Presidio | Custom/REST wrapper | Raw text (PHI) | Self/hosted |51522. Document version, deployment location, network zone, BAA status.533. Artifact: `mcp-inventory-{id}.json`.5455### Step 2: OAuth 2.1 and PKCE configuration56571. Register OAuth client per MCP server with:58 - **Exact redirect URI** allowlist (no wildcards)59 - **Authorization code flow** with **PKCE S256** (OAuth 2.1 requirement)60 - **Short-lived access tokens** (≤1 hour) and refresh token rotation612. Prohibit implicit flow and password grant.623. Bind tokens to **audience** (specific MCP server resource identifier).634. Test: authorization without PKCE challenge → **must fail**.6465### Step 3: Tool set design (least functionality)6667For each MCP server, define **role-based tool sets**:6869#### Playwright MCP pattern (PCI 6.4.3 / 11.6.1)7071- **Allowed tools**: `browser_navigate`, `browser_snapshot`, `browser_take_screenshot`72- **URL allowlist**: payment page URLs only—block `file://`, internal IPs unless scoped73- **Prohibited**: arbitrary JavaScript execution beyond documented audit scripts74- **Evidence**: DOM snapshots stored with SHA-256; no PAN fields in stored HTML if avoidable7576#### Postgres MCP pattern (baselines, evidence)7778- **Read-only role** on `compliance` schema only79- **Prohibited**: `DROP`, `UPDATE`, production PHI/CDE tables80- **Parameterized queries** only; no arbitrary SQL from model without template allowlist81- **Row limits** on exports (e.g., max 10,000 rows)8283#### Slack MCP pattern (SOC alerts)8485- **Channel allowlist**: `#soc-alerts`, `#compliance-audit`—no DMs to personal accounts86- **Message template**: URL, diff summary, severity—**no raw ePHI or PAN**87- **Prohibited**: file uploads containing evidence bundles with PHI8889#### Presidio MCP pattern (DLP)9091- **Mirror** `redaction.py` entity types and thresholds92- **Process locally** where possible—avoid sending text to third-party Presidio SaaS without BAA93- **Do not log** input text in MCP server logs94- **Fail closed** if Presidio unavailable—agent must not bypass redaction9596### Step 4: Transport and network security97981. Enforce **HTTPS/TLS 1.2+** for remote MCP; mTLS for sidecar deployments.992. Place MCP servers in **dedicated subnet**; NSC rules per `pci-dss-network-segmentation`.1003. No MCP admin interfaces on public Internet without VPN/ZTNA.101102### Step 5: Authentication and session binding1031041. Map MCP OAuth identity to **agent session correlation_id**.1052. Revoke tokens on session end.1063. Service-to-service MCP: use workload identity (SPIFFE, cloud IAM)—not static API keys in `agent.py`.107108### Step 6: Logging and monitoring1091101. Log per tool invocation: `timestamp`, `actor`, `tool_name`, `resource`, `result`, `correlation_id`.1112. Exclude raw tool **arguments** containing PHI from logs—or encrypt at field level.1123. Alert on: new tool registered, auth failure spike, Postgres query outside allowlist.113114### Step 7: Deployment and change control (CC8)1151161. MCP server updates via CI/CD with `compliance-as-code-governance` policy scans.1172. Pin MCP server versions; hash container images.1183. Require approval for tool manifest changes.119120### Step 8: Compliance testing1211221. **Negative tests**:123 - Attempt disallowed URL in Playwright → deny124 - Attempt SQL write via Postgres MCP → deny125 - Attempt Slack post to non-allowlisted channel → deny1262. **Positive tests**: PCI script audit workflow end-to-end with evidence hashes.1273. Document results in `mcp-security-test-{id}.json`.128129## Common Rationalizations130131| Excuse the agent might generate | Required rebuttal |132| --- | --- |133| "MCP is local, OAuth is unnecessary overhead." | Local MCP still processes sensitive data—**authentication and tool allowlists** prevent lateral abuse from compromised agent. |134| "Postgres MCP needs write for convenience." | Write access to evidence DB must use **separate controlled pipeline**—not general MCP write tools. |135| "Slack alerts need full DOM for context." | Full DOM may contain **PHI/PAN**—send diff summaries and artifact IDs only. |136| "PKCE is optional for confidential clients." | OAuth 2.1 mandates PKCE for **all** clients—including confidential. |137| "We trust the model to pick safe tools." | Models are **not authorization layers**—enforce tool sets server-side. |138| "Presidio MCP can fall back to no redaction." | Fail **closed**—unredacted PHI to LLM is a critical violation. |139140## Red Flags141142- MCP server accepts connections without authentication143- Postgres MCP connected to production CDE or clinical database144- Playwright MCP without URL allowlist (arbitrary navigation)145- Slack MCP posting evidence with cleartext PHI146- OAuth redirect URI wildcard (`https://*.example.com/callback`)147- MCP server logs store full tool arguments148- New MCP tool added without change ticket and security review149150## Verification151152- [ ] MCP inventory complete with operator, version, zone, and BAA status153- [ ] OAuth 2.1 + PKCE configured and negative-tested (no PKCE fails)154- [ ] Role-based tool sets documented and enforced server-side155- [ ] Playwright URL allowlist configured for payment audit URLs only156- [ ] Postgres MCP read-only on compliance schema; write paths prohibited157- [ ] Slack MCP restricted to allowlisted channels with PHI-free templates158- [ ] Presidio MCP aligned with redaction.py; fail-closed tested159- [ ] TLS/mTLS and network segmentation verified160- [ ] Tool invocation audit logs configured without cleartext PHI arguments161- [ ] Negative and positive security tests completed with hashed evidence