Some pages must never reach an AI. Blocking the tool call is not enough

· ~8 minute read

The Knowledge Base inside Stylus SFTP Server ships with a native MCP server, so an AI assistant can read and write your documentation. That is genuinely useful — we let one author an entire partner knowledge base to prove it. But the moment an assistant can read your pages, a policy question arrives with it: some of those pages must never be sent to an AI at all.

Contract terms. A breach post-mortem naming a customer. Anything your agreements or your compliance team say does not leave your walls. The requirement is simple to state and, it turns out, easy to implement badly.

The obvious design is the wrong one

The first shape everyone reaches for is: add a flag to the page, and make the write tool refuse it. That is backwards. Blocking update_page stops an assistant from changing the page while leaving it perfectly free to read the page — and reading is the thing policy forbids. The concern is data egress: content leaving your server for a model.

So reads come first. But once you are thinking about egress, two more routes appear that a "block the tool" design misses entirely:

The side door: your assistant already has a key

Here is the part that decides the whole design, and we know it from our own product rather than from theory.

A Knowledge Base has two ways in. There is the MCP endpoint — the polished front door, with typed tools like read_page and search_knowledge. And there is the ordinary REST API that the browser application itself uses: /knowledge/api/pages/…, plain HTTP, same content.

Assistants use both. When we had an assistant write that demo knowledge base, it did not upload screenshots through an MCP tool — inlining image bytes through a model is painfully slow. It POSTed the raw bytes straight to the REST attachment endpoint, authenticating with the OAuth token it already held. That is the supported, sensible path. It also means that any assistant with a Knowledge Base token can call any REST URL that token permits.

Now play out the naive design. An assistant is told to summarise a page. read_page returns "access denied." A capable agent does the obvious next thing: fetches the same page from the REST endpoint with the token in its pocket. The content leaves. The policy is violated, and the audit trail shows a perfectly ordinary API call.

AI assistant holds an API token MCP tools read_page, search… REST API /knowledge/api/… Auth layer token ⇒ agent session ⇒ human Blocked policy denial Served browser session
Two doors, one guard: the block is decided by how the request authenticated, not by which endpoint it called.

Credential type is identity

So the rule we shipped does not mention tools at all:

A request that authenticates with an API token or OAuth is an AI agent, on every URL. A request carrying a browser session cookie is a person.

That single line closes both doors, because it is enforced in the server's authentication layer — before any handler runs. It is also, usefully, immune to the model itself: no prompt, no jailbreak, no "ignore previous instructions" reaches the check, because the check never consults anything the model said. It looks at how the connection proved who it was.

The trade-off is honest and small: if you ever build a non-AI automation that authenticates with an API token — a nightly export script, say — it too will be refused on blocked pages. We decided that is the right default. A script exporting customer-private pages to somewhere else is the same egress risk the policy exists to stop.

What "blocked" actually covers

RouteBehaviour for a blocked page
read_pageDenied, with an explicit company-policy message
update_page, publish_pageDenied
search_knowledgeExcluded from results — snippets are content
list_topicsOmitted entirely — titles are content
Attachment upload (REST, token)Denied
Page content over REST (token)Denied
Anything with a browser sessionUnchanged — people read normally

Two smaller decisions matter more than they look:

An agent can never unblock a page for itself. The toggle has exactly one endpoint, it refuses token-authenticated requests outright, and no other write path can touch the flag — page saves, MCP writes and imports all ignore an aiBlocked field if one shows up in their payload. A security control an agent can switch off is decoration.

The block survives a revert. Knowledge Base pages are git-versioned, and page metadata travels with them. Store the flag only in that versioned metadata and rolling a page back to last month silently unblocks it — the worst kind of failure, because nothing looks wrong. So the enforced value lives in the database, and a revert re-stamps the restored file from it. There is a test whose entire job is to revert a blocked page to a version that predates the block and assert it is still blocked.

What it cannot do, stated plainly

Every access control has an edge, and a security feature that hides its edge is worse than one that has none, because people plan around the promise. Ours has three tiers:

That last one deserves its own sentence, because it is where a lot of "AI blocking" marketing quietly overpromises: if a user runs an AI browser extension against their own logged-in session, the content is available to it. The mitigation is a workstation policy about which AI tools are permitted on machines with access — not a checkbox on a server. What the server can promise, it promises completely: a blocked page is never served to anything the server can identify as an agent.

Using it

Open the page in the editor and click the AI: Allowed button in the toolbar. It turns red and reads AI: Blocked, effective immediately — no save, no publish step, because a policy control should not wait on a draft. Readers see an AI access blocked badge next to the title, so a colleague who asks the assistant about that page understands why it claims not to see it. Anyone who can edit the page can set it, and every toggle lands in the audit trail with the operator's name.

One button, one page, one rule underneath it: what you authenticate with is what you are.