From 6b878a9cfcc8079c249d20602e4d6d7876229d49 Mon Sep 17 00:00:00 2001 From: maverick0628 <26542471+maverick0628@users.noreply.github.com> Date: Wed, 5 Aug 2026 13:58:17 -0400 Subject: [PATCH] docs: say that the guard filters tools/list, not just calls The README described the guard as a tool allowlist enforced at the wire, which undersells it. Denial happens twice and the first one matters more: tools/list is filtered to the allowlist before the client sees it, so a denied tool is never advertised to the model at all. The call-time block is the backstop. That behaviour was only documented in a bash comment in the verification snippet, so the front door never said it and the decision-tiers table read as if deny were purely a call-time check. Co-Authored-By: Claude Opus 5 --- README.md | 5 +++++ docs/mcp-guardrails.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/README.md b/README.md index 14ddb5d..163d963 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,11 @@ allowlist, argument filtering, and response redaction. A trading server can be allowed to read quotes and denied the ability to place an order, and the denial is enforced at the wire, not by asking the model nicely. +The allowlist filters `tools/list` as well, so a denied tool is never advertised +to the model in the first place. It cannot attempt what it cannot see. The list is +default-deny, so a tool the policy has never heard of stays blocked until someone +adds it rather than allowed until someone notices. + The browser UI is the other half of the idea. It can add and edit every secret in the store, and it **never displays one**. No endpoint behind it returns plaintext — the detail view shows `sk-l...c9ae` and nothing more — so a stolen session diff --git a/docs/mcp-guardrails.md b/docs/mcp-guardrails.md index 73575e9..7bc0133 100644 --- a/docs/mcp-guardrails.md +++ b/docs/mcp-guardrails.md @@ -36,6 +36,11 @@ There is no soft "warn-and-allow" tier for trades — omission is a hard block. (`warnArgPatterns` still exists for credential-shaped arguments, inherited from the engine defaults.) +Denial happens twice, and the first one matters more. `tools/list` is filtered to +the allowlist before the client ever sees it, so a denied tool is never advertised +to the model — it cannot attempt what it is not shown. The call-time block is the +backstop for a client that asks for a tool it was not offered. + ## The policies Authored as standalone, reviewable files loaded by the existing policy engine: