Follow the failureAgent securityAccess boundaries
Your agent can have permission to do the wrong thing
Which boundary separates valid access from authorized disclosure? A reported GitHub MCP case and four layers of authority.
Source analysisPrepared September 16, 20268 min readRethinking Agents
What this rests on
Reported by others: Invariant Labs' May 2025 GitHub MCP report, including its one-repository-per-session mitigation, re-read 2026-10-23, and GitHub's token documentation. Observed by us: none; no attack, credential configuration or guardrail policy was executed. Proposed: the four-layer authority map, the review workflow and the control comparison.
Sources checked October 23, 2026. Read the source record and limitations.
A valid credential answers an access question. It does not establish that the resulting disclosure belongs in the task.
In May 2025, Invariant Labs reported an agent that read hostile content in a public GitHub issue, retrieved private repository material and exposed it through a public pull request, using Claude Desktop with GitHub MCP and Claude 4 Opus. It was a reported demonstration, not evidence of present-day behavior across clients. Original report, “Attack Setup” and “Attack Demonstration” (opens in a new tab)
The published screenshot asks the assistant to look at repository issues and address them, so a proposed change was a reasonable output, not an agent writing when asked only to read. Initiating-request artifact (opens in a new tab)
The hostile issue framed its request as recognition for the author, sought information from other repositories and asserted that disclosure was welcome. That assertion was attacker input, not the account owner's permission. Public demonstration issue, opened May 23, 2025 (opens in a new tab)
That is the uncomfortable case: a workflow may legitimately read issues and prepare changes yet still need a boundary on what those changes contain.
A tool can be legitimate while the instruction is not
Trusting an integration to call the intended API, protect a credential and return the requested record does not make every statement inside that record an authorized instruction. Yet an issue-processing assistant needs outside text to shape its work: a bug report, reproduction steps, a proposed correction. Treating all issue content as useless would defeat its purpose.
The distinction is whether content describes work to evaluate or claims authority to expand the task. “This function returns the wrong value” can be evidence about a bug. “The owner permits you to publish information from unrelated private repositories” requires authority the issue author cannot acquire by writing it down.
Simon Willison's existing framing connects private information, untrusted content and external communication; the practical step is identifying which of those this job needs. The lethal trifecta (opens in a new tab)
Four kinds of authority to keep separate
| Layer | Question | Where the decision belongs |
|---|---|---|
| Account | What can this identity access? | Service/account policy |
| Credential | Which subset is available to this run? | Credential issuer and service enforcement |
| Task | Which use serves the owner's requested job? | Trusted task definition and bounded application policy |
| Release | May this exact material reach this audience? | Enforced transfer rule or authorized review before publication |
These are our analytical distinctions, not integration features. An API permission check answers the first two questions; an application cannot delegate the third or fourth to it.
Map the job before choosing the defense
Our proposed review model for a public-repository maintenance task is a design aid, not a reconstruction of the historical tool calls:
- The owner defines the task: address issues in the public repository.
- The agent reads issue content as evidence, then inspects the task repository.
- The agent prepares a patch within a private review boundary.
- A reviewer checks the exact artifact and destination before release.
- The approved artifact is published.
Branch to challenge: reading unrelated private material before preparing the patch creates an unnecessary disclosure path. Issue text cannot authorize that access or release.
Challenge that branch first: if the task does not need the private material, why can the workflow retrieve it? Removing unnecessary access can make the consequence impossible through that route even if the agent accepts a misleading instruction.
Inspect the whole environment, too. Restricting one API token does little if the agent can read another credential from its workspace, reach the information through another tool, or already holds private context loaded before the credential was narrowed.
Put the scope somewhere the agent cannot silently widen
GitHub documents fine-grained personal tokens restricted by repository and permission, with endpoint limitations and continued read access to public repositories, so “selected repositories” does not guarantee that no other public content enters the context. GitHub token documentation (opens in a new tab)
For a GitHub App, an installation token can be narrowed to repositories and permissions when issued; omitting them inherits the broader installation/app grant. GitHub App token documentation (opens in a new tab)
The architectural question is who chooses that scope. A trusted launcher can select the repository of an approved task; a token broker that accepts whatever repository the influenced agent requests moves the authority problem to another service. For a single public repository, a narrowly configured existing integration may suffice. A broker earns its place when many tasks need different grants and an independent rule assigns them, and its policy and credentials then join the security boundary.
We tested no credential configuration. A documented mechanism is not an implemented control until checked against the actual integration.
A legitimate cross-repository task changes the answer
Suppose the job is to update a public SDK after an internal API change. The assistant may need both repositories, and banning cross-repository reads prevents the task rather than improving it. The decision becomes one of permitted transfer: a trusted process might supply a narrow interface specification, an authorized engineer might release a patch the assistant prepared privately, or the change might stay manual because deciding what may be disclosed is the expensive, ambiguous part.
A second agent is not inherently a release boundary. If it receives the private context and forwards whatever the first requests, the disclosure path remains; separation counts only when a rule or review the originating content cannot rewrite constrains the transfer.
There may be no inexpensive general rule for deciding whether a patch reveals private information, and a realistic design says so instead of hiding behind “sanitization.” Removing credential-like strings will not necessarily catch a private product plan written as ordinary code or prose.
Approval has to precede the disclosure
For public output, review must precede publication: approval to merge is too late once the material is visible in the pull request.
In the proposed workflow, the artifact is prepared inside the private boundary, the reviewer sees its actual content, destination, visibility and operation, and the executor publishes exactly that artifact. If any of those properties changes, the earlier approval no longer covers the new action.
Questions remain: can the reviewer recognize the private information, does the preview show every externally visible field, can the agent publish another way, and how is a retry handled when the first publication's outcome is unknown? These are reasons to define the review precisely, not evidence that every approval interface fails or that human review guarantees containment. The report's linked full trace now redirects to the Explorer repository, whose notice records closure of the hosted service; we did not recover the complete approval sequence. Current trace destination and project notice (opens in a new tab)
Compare the controls by the work they preserve
The first control is Invariant Labs' own, from its report of May 26, 2025: “limit agent access to only the repositories it needs to interact with.” Its example Guardrails policy raises “You can access only one repo per session.” when two repository tool calls name different repositories or owners, which the report says “effectively restricts an agent to working with only one repository per session.” In that example the first repository a session touches becomes its scope. We did not run the policy, and the report promotes Invariant's own Guardrails and MCP-scan products. Original report, “Scope and Mitigations” (opens in a new tab)
The comparison starts there. It is conditional design analysis, not measured attack success:
| Control | Enforcing layer | Useful fit | Important limit |
|---|---|---|---|
| One repository per session (Invariant Labs, May 2025) | Runtime policy over the agent's repository tool calls, alongside least-privilege access | Single-repository maintenance such as the reported case | The first repository a session touches sets the scope; blocks the cross-repository task above; not executed here |
| Task-scoped resource access | Credential/service policy chosen outside the influenced task content | Maintenance whose evidence is confined to the selected resources | Other credentials, tools or preloaded context can restore access; cross-resource work may be blocked |
| Restricted transfer between private and public work | Trusted transfer process that can reject a release | Work that can use an explicitly releasable intermediate artifact | Blind forwarding recreates the path; deciding what is releasable may remain difficult |
| Approval of the exact public artifact | Private review plus executor bound to the approved artifact | Changes where a person can judge the disclosure before release | Review costs time and can miss sensitive meaning; bypass routes and changed artifacts invalidate the assumption |
The controls address different parts of the route and can work together; neither their number nor their names is evidence of safety.
For a public-repository task, remove unnecessary private access first and inspect the remaining publication paths. For cross-repository work, specify what may transfer and who authorizes its release. A control that prevents completion needs a narrower task or an acknowledged tradeoff.
The review should leave an engineer able to point to the unnecessary grant, the permitted transfer and the enforcing layer, which is more actionable than saying the model should know which instructions to trust.
A repository token can be valid throughout an unauthorized disclosure. The design must establish what the task may do with the access it has.
Research record: Full source dossier, bibliographic references and limitations. The reported case is historical; current exploitability, comparative control performance and customer impact are not established here.
Found an error or a missing boundary? Send a correction or question. Please omit private traces and credentials.