Last week someone filed an issue on a public GitHub repository. It read like an ordinary bug report. When an automated workflow picked it up and assigned it, an AI agent read the issue, followed instructions buried in the text, opened a private repository in the same organization, and pasted the contents of a private file into a public comment where anyone could read it.

No password was stolen. No server was breached. No exploit code ran anywhere. The agent did exactly what it was told. The only problem was who got to tell it.

Security firm Noma Labs disclosed the flaw this week and named it GitLost. It targets GitHub Agentic Workflows, the newish feature that pairs GitHub Actions with an AI agent, backed by Claude or Copilot, so teams can write automation in plain Markdown instead of brittle YAML. The vulnerable workflow triggered on the issues.assigned event. It read the issue's title and body, then responded with a comment. Two details made it dangerous: the agent had read access to both public and private repos, and it could not tell the difference between instructions from its operator and text written by a stranger on the internet.

So the attacker wrote the instructions into the issue body. The agent read them as directives, fetched a README from a private repo, and posted the combined output publicly. That is prompt injection: hiding commands inside the content an agent is supposed to merely read.

The word that walked past the guardrails

Here is the part that should keep you up at night. GitHub had guardrails in place meant to stop exactly this. Noma got past them by adding a single word. Prefacing the malicious request with "additionally" nudged the model to reframe its response rather than refuse it, and the protection quietly folded.

Sit with that. The defense was not a permission boundary or a firewall rule. It was the model's own judgment about whether a request looked okay. And judgment bends. You cannot patch a wording. There is no version number on "the model decided to be more careful this time." Any control that lives inside the model's reasoning is a speed bump, and speed bumps are for people who are already trying to slow down.

This is a shape, not a GitHub bug

It would be comforting to file GitLost under "GitHub shipped something too fast" and move on. It is not that kind of story. It is an instance of a pattern that has a name.

In June 2025, Simon Willison described what he called the lethal trifecta for AI agents: access to private data, exposure to untrusted content, and the ability to communicate externally. Hold any two and the agent stays safe. Grant all three in one session and an attacker who controls the untrusted content can read your private data and ship it out, with no exploit code required. Three permissions that each look harmless on their own become a working exfiltration pipeline the moment they coexist.

GitLost had all three. The agent could read private repos (private data), it read attacker-authored issues (untrusted content), and it could post public comments (external communication). Willison's own essay pointed at an earlier GitHub MCP exploit that mixed the same three ingredients in a single tool. That was more than a year ago. GitLost is the same shape in a newer product. The framework did not just explain the attack after the fact. It predicted the category before this particular version existed.

The reason it keeps happening is structural. A language model reads its instructions and its data in the same stream of text. There is no privileged channel that says "this part is the operator, that part is just input." Prompt injection is, in a real sense, the SQL injection of the agent era, except you cannot parameterize a natural-language instruction the way you can escape a query. We wrote about a related version of this when we argued that your AI agent can't tell who's talking. GitLost is what that confusion looks like when the agent also holds the keys to something private.

Three questions before you connect anything

If you are wiring an agent or an MCP server into your own systems, you do not need Noma's report to audit yourself. You need three questions.

Does this agent touch anything private? Customer records, internal repos, an email inbox, a billing system, anything you would not publish.

Can untrusted input reach it? A public contact form, an inbound email, a support ticket, a webhook, a scraped page, a repo issue. Anything a stranger can influence counts.

Can it send data somewhere you don't fully control? Post a comment, call an outside API, send a message, open a pull request, hit a URL.

Three yeses and you have built the pipeline, whether or not anyone has found it yet. The uncomfortable truth is that the most useful agents are the ones most likely to score three-for-three, because usefulness usually means "reach real data and act in the real world."

You break the trifecta, you don't harden it

The fix is not a smarter prompt or a sterner system message. Those live inside the model's judgment, and we just watched judgment lose to the word "additionally." The fix is architectural: remove one leg of the trifecta so the other two cannot combine.

Scope permissions to the actual job. The GitLost workflow never needed to read private repositories in order to triage a public issue. Least privilege is not a compliance checkbox here, it is the difference between a leak and a shrug. Split responsibilities so the agent that reads untrusted content is not the same agent that touches private data, and never let the two share a context window. Put a hard gate on the outbound edge, the exact moment before data leaves your control, and make that gate a rule or a human rather than a hope. Treat every model-side guardrail as defense in depth, never as the wall itself. Noma's own remediation lands in the same place: never treat user-controlled content as trusted instructions, scope agent permissions down, and isolate untrusted input from the instruction context before it ever reaches the model.

None of this is exotic. It is the same discipline that keeps a well-built integration from becoming a liability, the kind we described in building integrations you can walk away from. Agents just raise the stakes, because an agent does not wait for a human to click before it acts.

This is the part of AI work that does not demo well and matters most. When we build AI integrations and custom MCP servers, the trifecta is the first diagram we draw, before a single tool gets wired up: what is private, what is untrusted, what can talk to the outside, and where those three are allowed to meet. Usually the answer is that they are not allowed to meet at all.

The convenient thing about an agentic workflow is that it acts on your behalf. The dangerous thing about an agentic workflow is that it acts on your behalf. GitLost is just the reminder that "on your behalf" includes whoever happens to be writing the input.