Skip to main content

Security by Obscurity and the Agent Reading Your Wiki

· 12 min read
Tian Pan
Software Engineer

There is an endpoint inside your company that has been safe for ten years. It lives at a path that nobody outside the original team would ever guess. It is not in the public docs. It is not in the OpenAPI spec. It is not in the gateway's allowlist of "documented routes." Its auth layer is a token that any internal service can mint, because the threat model said the only way to reach it was to already know it existed. The endpoint accepts a JSON blob that, on a slow Tuesday, will reissue a refund or rotate an API key or move a row between two billing ledgers. It has worked correctly and unremarkably since 2016.

Last month, a teammate wired a coding agent into the engineering wiki to help with onboarding questions. The agent indexed every Confluence space, every archived design doc, every "do not delete — historical" page. Yesterday, a junior engineer asked it how refunds work. The agent stitched together a forgotten 2018 architecture diagram, a Slack export someone had pasted into a runbook, and a half-written postmortem. It produced, in conversational prose, a complete description of that endpoint, the token type required, and an example payload. The endpoint had not changed. Its threat model had.

The shift is subtle and worth naming out loud. The endpoint's security posture did not regress because anyone wrote bad code, deployed a misconfiguration, or leaked a credential. It regressed because the population of "readers who can synthesize the documentation corpus into a working request" went from "a determined attacker willing to spend weeks of reconnaissance" to "any caller with a chat box and read access to the wiki." Obscurity was a budgetary line item — the cost in attacker hours to enumerate a hidden surface. The budget has been spent.

Obscurity Was Always a Time Tax, and the Tax Just Got Cheaper

Defenders have argued about security-by-obscurity for as long as there has been security. The honest version of the argument was never "obscurity is a control." It was "obscurity raises the cost of attack, and we layer it with real controls because budgets are finite and we cannot harden everything." A random UUID in a sharing URL was never the only thing standing between a private document and the world. It was a speed bump that bought time for the real defenses — authentication, audit, anomaly detection — to do their work.

The speed bump worked because the cost of enumeration scaled badly for the attacker. To find an unguessable path, you had to know it existed, guess its general shape, write a scanner, evade rate limits, correlate signals across hours or days. None of that was free. The defender had a budget asymmetry: the attacker spent compute and time per attempt; the defender spent nothing per attempt that did not happen.

An agent with read access to your internal documentation collapses that asymmetry in one direction. The agent does not enumerate by guessing — it reads the documentation that describes the surface, in the same compute budget it would use to summarize a meeting transcript. A page that nobody has opened since 2019, a Slack thread someone exported into a markdown file, a screenshot pasted into a wiki and OCR'd by your indexing pipeline — all of it is a single retrieval call away. The "time tax" that obscurity collected has fallen to roughly prompt-completion latency.

The OWASP Top 10 for LLM Applications has been edging toward this for two revisions. Excessive Agency, in the 2025 edition, was expanded to call out exactly the failure mode where an agent's tool surface and read corpus are broader than its task requires. Sensitive Information Disclosure was rewritten to include the case where the model leaks system architecture details by stitching together documentation it was given access to. The frame is the same one this post is making: the agent's reading corpus is part of its attack surface, and most teams have not audited it as one.

The Internal Docs Corpus Is Now a Discovery Index

The blast radius from the agent example above is not the single endpoint. The endpoint is one entry in a discovery index that the agent built for free, on read, without anyone authoring it. Every internal doc that names a hostname, every architecture diagram that draws an arrow into a service, every onboarding guide that says "we use this internal tool for X," every postmortem that explains why an endpoint behaves the way it does — together they are a map of the attack surface, indexed by a retrieval system that responds to natural-language questions about what exists where.

A few uncomfortable consequences follow.

The first is that the value of a doc is no longer governed by who reads it. A page that has not been opened by a human in three years still ships into the agent's context the moment its keywords match a question. The implicit assumption that old documentation is harmless because nobody finds it does not survive a retrieval system whose entire job is to find it.

The second is that screenshots, exports, copy-pasted snippets, and forgotten attachments are part of the corpus. Most companies have a documentation policy that ostensibly forbids credentials in wikis. Few have a policy that forbids architecture details, internal hostnames, or example payloads — those are exactly what onboarding docs are supposed to contain. The policy was written for a reader who had to find the page first. The reader changed.

The third is that the corpus has no permission model that maps cleanly to the endpoint's permission model. The endpoint may require a tier-3 service token. The doc explaining the endpoint may be in a wiki space where everyone with a corporate SSO can read. Before the agent, those two layers composed safely: humans who could read the wiki could not mint the token, and humans who could mint the token had no incentive to call the endpoint maliciously. With an agent acting on behalf of a caller, the composition no longer holds — the agent reads the doc as the user with wiki access, then calls the endpoint with whatever token the agent itself holds, which is almost always a service identity provisioned for the agent platform rather than for the individual user.

What "Hardening" Looks Like When the Threat Is a Helpful Agent

Closing the gap is not a single fix. It is a posture change across several teams, and the patterns below are the ones I see actually working in 2026.

Audit the discovery surface, not just the endpoints. Most teams have an inventory of services. Few have an inventory of which docs, diagrams, and exports name those services. The audit that matters is the join: every internal endpoint and the graph of documentation pages that points at it. Treat the doc graph as part of the attack surface inventory. Pages that name endpoints whose auth model relies on URL secrecy should be flagged for either redaction or for an auth upgrade on the endpoint itself. Most teams will discover, on the first pass, that several "internal-only" endpoints are described in five different places, three of which are in the corpus the agent indexes.

Make the auth layer the layer. This is the boring, correct, expensive answer. If your endpoint's security depends in any meaningful way on a caller not knowing it exists, the auth layer is doing less than you thought. Move the endpoint behind an auth model that does not degrade if its path becomes public — strong service identity, scoped tokens, audit, and rate limits per-identity rather than per-IP. Defense in depth still wants obscurity as a layer, because cheap layers are still layers, but obscurity cannot be the load-bearing layer. It never could; the agent only made the math visible.

Split the agent's reading corpus from the human's reading corpus. This is the pattern that most surprises teams when they implement it. The default assumption is that the agent should see what its user sees — same wiki access, same Slack channels, same shared drives. That assumption inherits decades of "broadly readable" defaults from a world where the cost of reading was a human's attention. With an agent, every readable thing is functionally read. The right shape is two corpora: a curated, intentionally-authored agent corpus, and the broader human corpus that the agent does not retrieve from by default. Yes, this means duplicating content. Yes, this means a curation cost. That cost is the price of the audit you should have been doing anyway.

Prefer allowlists to "read everything with good judgment." RAG access control vendors have been making this argument for two years and most teams have been politely ignoring it because allowlists are tedious. The choice is not tedium versus elegance. It is tedium versus a discovery surface that grows monotonically with every wiki edit anyone makes. Document-level access control, enforced at the vector layer rather than at the prompt layer, is the only configuration that does not silently expand over time. Approaches built on Zanzibar-style fine-grained authorization for retrieval are now boring infrastructure rather than novel research; the gap is in the willingness to use them.

Treat the agent's service identity as a separate principal. A common error pattern is granting the agent the union of permissions across all of its users. The agent then has a permission set that no single human in the org has ever held, and that set is what determines what the agent can do when it acts on a prompt. The fix is to scope the agent's tool calls to the requesting user's identity for every action that exits the read boundary, and to make the agent's own service identity narrow enough that, on its own, it cannot reach the sensitive endpoints. The agent should have to "borrow" the user's authority to do anything beyond reading, and the borrowing should be auditable.

The Threat Model Update Nobody Scheduled

The teams that handle this well do not necessarily have better tools. They have a threat model document that names the agent as an actor and updates the population estimates accordingly. The "attacker who finds the URL" entry in the risk register used to read something like "low likelihood, high impact, mitigated by obscurity plus auth-layer-X." The same row now reads "high likelihood, high impact, mitigated by auth-layer-X." The likelihood moved because the population of readers moved. The mitigation column shrank because one of its terms vanished.

Updating the threat model document is the cheap part. The expensive part is the audit it implies: a sweep through the endpoint inventory and the doc graph, asking the same question of every row — would this endpoint be safe if its URL were on the front page of the public docs tomorrow? If the answer is no, the obscurity layer was load-bearing, and the load needs to move. Most teams will find a small number of endpoints where the load was load-bearing and a larger number where it was layered correctly all along; the value is in knowing which is which.

I have seen this audit framed as a security project and seen it framed as an AI-readiness project, and the latter framing tends to get budget faster. That is fine. The work is the same. The threat is not new — obscurity has been a weak control for as long as anyone has written threat models — but the population of readers has changed in a way that makes the weakness operationally visible for the first time. The agent did not create the vulnerability. It published it.

The Forward-Looking Part

Two things are going to happen over the next 18 months, and both are worth getting ahead of.

The first is that the agent's reading corpus will keep growing. New connectors will land — your ticketing system, your incident review tool, your shared drives, your customer-support archive. Each connector ships with its own access model and its own assumption that the reader is a human. Each one widens the discovery surface unless it is explicitly scoped. The work to keep the corpus narrow is not a one-time audit; it is a standing review whose cadence matches the cadence at which new sources are added.

The second is that the agent's behavior will become part of the surface itself. As agents start acting on the docs they read — opening pull requests, filing tickets, calling tools, drafting emails — the "obscurity as a layer" frame will extend from the endpoints into the actions. An action that was safe because no human knew to take it will become unsafe because an agent inferred from the docs that it should. The same posture applies: do not let the auth model depend on a caller not knowing the action exists.

The architectural realization, finally, is the one the topic itself names. Security by obscurity was always a budgetary line item. It bought time, and the time was paid for in attacker hours. The line item has not been deleted; the rate has changed. The hours have collapsed into seconds, and the seconds belong to a caller that your team installed last quarter and whose read access nobody has audited since. The endpoint is unchanged. The model around it is not. Audit the docs the way you would audit the code, and move the auth boundary to where it should have been all along.

References:Let's stay in touch and Follow me for more thoughts and updates