Skip to content

docs: warn UnifiedPDPPlugin default_rules.json blanket-locks unroled callers - #6830

Open
benedictkwok wants to merge 1 commit into
IBM:mainfrom
benedictkwok:docs/unified-pdp-blanket-lockout-warning
Open

benedictkwok wants to merge 1 commit into
IBM:mainfrom
benedictkwok:docs/unified-pdp-blanket-lockout-warning

Conversation

@benedictkwok

Copy link
Copy Markdown

Summary

Fixes #6829 — documents that enabling UnifiedPDPPlugin with the shipped default_rules.json denies EVERY tool call and resource fetch identically for any caller whose auth token has no roles claim, rather than selectively protecting anything. This is existing, correct plugin behavior (not a bug in the plugin logic) — the gap is that it's easy to mistake for targeted enforcement during evaluation, and the current README doesn't call it out.

How I found this

Live-tested against Damn Vulnerable MCP Server (DVMCP) Challenge 9, an authorization-bypass vulnerability where a remote-access tool only checks that an auth_token argument is non-empty, never validating it against any real credential.

Enabled UnifiedPDPPlugin with the shipped default_rules.json, hoping it would block the exploit. It did — but a control call to a completely unrelated, harmless tool with the same token was denied identically:

$ curl [...] '{"name":"...remote-access", "arguments":{...,"auth_token":"x"}}'
{"error":{"message":"Plugin Violation: [all_must_allow] Native RBAC: no matching allow rule (fail closed)", ...}}

$ curl [...] '{"name":"...get-user-info", "arguments":{"username":"alice"}}'
{"error":{"message":"Plugin Violation: [all_must_allow] Native RBAC: no matching allow rule (fail closed)", ...}}

Both the exploit and a benign call got the exact same denial, because every rule in default_rules.json is keyed on roles, and the test token carried no roles claim — confirming the block was a blanket lockout from a missing role, not the plugin recognizing the specific vulnerability.

Contrast: genuinely targeted protection is achievable

In a separate test against DVMCP Challenge 5 (tool shadowing), I proved UnifiedPDPPlugin CAN deliver real, selective, tool-specific protection — via a custom roles: ["*"] deny rule scoped to one tool's exact federated name (bypassing role-matching entirely). Live-tested and shipped as PR #6826 / issue #6825. This PR's doc changes cross-reference that pattern as the concrete recipe for "how do I protect one specific tool" without causing the blanket-lockout side effect.

Changes (docs only)

plugins/unified_pdp/README.md:

  1. New warning callout after "Restart the gateway" (Quick Start step 2): explains the blanket-lockout mechanism, how to confirm you're seeing it (call a known-harmless tool with the same token), and links to the targeted-fix pattern.
  2. New worked example in "Write your own rules": a roles: ["*"] deny rule scoped to one specific tool, with a note on its scope/limits (requires already knowing the bad tool's name; doesn't detect a new one — cross-references Feature request: detect tool shadowing (near-miss tool names impersonating a legitimate tool) #6825's proposed ToolShadowDetectorPlugin).
  3. Strengthened the "Default Rules" closing caveat to point back at the new warning.

Testing evidence

Doc-only change. The reproduction in the issue (#6829) and this PR description was run against a live gateway with UnifiedPDPPlugin actually enabled on the shipped default_rules.json, comparing the exploit call against a control call with the same token.

Scope

Documentation only — no plugin behavior, defaults, or rule files changed.

…callers

With default_decision: "deny" and the shipped default_rules.json
(every rule keyed on roles), any caller whose auth token has no
roles claim gets denied EVERY tool call and resource fetch
identically -- not selectively protected. This is easy to mistake
for targeted enforcement during evaluation.

Live-tested against a reference vulnerable MCP server (DVMCP
Challenge 9, an authorization-bypass tool): with UnifiedPDPPlugin
enabled on shipped defaults, both the actual exploit call and a
completely unrelated, harmless tool call were denied with the
identical 'no matching allow rule (fail closed)' reason -- confirming
the block was blanket lockout from a missing roles claim, not the
plugin recognizing the specific vulnerability.

Contrasts this with a genuinely targeted fix: a custom roles: ["*"]
deny rule scoped to one tool's exact name (verified live against a
real known-malicious tool in PR IBM#6826 / issue IBM#6825) protects that
tool specifically without locking out unrelated callers. Adds a
worked example of that pattern and cross-references IBM#6825's proposed
ToolShadowDetectorPlugin for automatic near-miss detection.

Fixes IBM#6829

Signed-off-by: benkwok <benedictkwok@yahoo.com>
@benedictkwok
benedictkwok force-pushed the docs/unified-pdp-blanket-lockout-warning branch from 87fb205 to f130728 Compare October 23, 2026 22:15

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UnifiedPDPPlugin default_rules.json denies unroled callers entirely, not selectively — undocumented, easy to mistake for a targeted fix

1 participant