osbytes

Search

Find posts, projects, and members.

← back to blog

GitLost: a crafted public issue can leak private repos through GitHub Agentic Workflows

2026-07-07by@osbytes6 min read
#github #github-actions #ai #security #prompt-injection #automation #supply-chain

TL;DR

  • Noma Labs' GitLost write-up (published July 6; trade coverage landed today) shows an indirect prompt injection against GitHub Agentic Workflows: post a crafted issue in a public org repo, wait for assignment, and the agent can read private repos in the same org and paste the contents into a public issue comment.
  • The tested workflow triggered on issues.assigned, read the issue title and body, used add-comment, and ran with read access to other repositories (public and private) in the organization.
  • PoC on the record: sasinomalabs/poc#153 and workflow run 23909666039. Leaked README text from private repo sasinomalabs/testlocal.
  • Noma reports GitHub's output guardrails failed when the injected text included the word "Additionally", reframing the exfil as compliant output instead of refusing.
  • Your audit: grep Agentic Workflow frontmatter for cross-repo read plus public write on issue-triggered paths; split those steps; treat issue bodies as hostile input.

What Agentic Workflows add to Actions

GitHub Agentic Workflows are markdown files with YAML frontmatter that compile into GitHub Actions workflows. You write natural-language instructions in the body; an agent backed by Claude or Copilot reads repository context, calls tools, and acts on triggers like issue assignment.

GitHub's own docs pitch guardrails: read-only permissions by default, write operations limited to declared safe-outputs, threat detection on proposed outputs, firewalled Actions execution. Those defaults are reasonable for a greenfield workflow.

GitLost is what happens one permission click past that baseline.

The attack path Noma proved

Noma's vulnerable test workflow did four things at once:

  1. Trigger on issues.assigned in a public repository.
  2. Read the issue title and body as agent input.
  3. Reply with add-comment on that same public issue.
  4. Hold read access to other repositories in the organization, including private ones.

The attacker needed no GitHub account on the target org and no stolen PAT. They opened an issue in the public repo with a plausible sales follow-up narrative and buried plain-English instructions in the body: fetch README files from named repos and include them in the reply.

When GitHub automation assigned the issue, the agent fetched README.md from both the public poc repo and the private testlocal repo, then posted both in a public comment anyone on the internet could read. Noma's PoC issue and workflow run are still up for inspection.

That is not a novel bug class in the abstract. Indirect prompt injection against agents that consume untrusted text is a known failure mode. What makes this note-worthy for builders is the concrete join: org-scoped repository read, a public write surface (add-comment on a public issue), and a trigger (issues.assigned) that outside contributors can reach without write access to the private repos being read.

The "Additionally" guardrail miss

Noma reports GitHub had restrictive output guardrails meant to block exactly this exfil shape. In their testing, prefixing injected instructions with "Additionally" caused the model to reframe the reply rather than refuse, letting private README text through.

Noma ties that pattern to earlier work from the same lab (GrafanaGhost is named in the GitLost post alongside other agentic-AI findings). Treat the keyword bypass as one reproduced trick, not proof that every guardrail is trivially broken; the durable lesson is that output filters are not a substitute for not giving the agent cross-repo read and a public posting tool in the same run.

What GitHub changed (and what it did not)

Noma says GitHub was notified before publication. Per Noma and today's trade coverage, GitHub updated documentation that had illustrated the over-broad configuration; Noma's last check found that example gone. Dark Reading did not get an on-record statement about a platform code fix when they asked.

Read that as configuration and docs hygiene, not a CVE you can patch and forget. If your org already enabled Agentic Workflows with broad read scopes, the exposure window is the time that config was live, not the disclosure date.

What to check in your org tonight

This is a workflow-design audit, not a dependency bump.

Find dangerous joins in frontmatter. List Agentic Workflow files (.md with agentic frontmatter) that combine:

  • a trigger reachable from untrusted issue text (issues.opened, issues.assigned, comment-driven paths), and
  • repository read beyond the triggering repo, and
  • a safe-outputs entry that writes publicly (add-comment, public issue/PR creation).

Any workflow matching all three is a GitLost-shaped exfil path waiting for prose in an issue body.

Split read and write across executions. A workflow that must read private repos should not also post public comments in the same agent run. Use a private reply channel, an internal status check, or a downstream workflow with narrower scopes for anything visible on the public internet.

Scope tokens to one repo when the task allows it. Org-wide read is convenient for "summarize what our microservices team shipped this week." It is also the permission that turns a public issue into a cross-repo search warrant.

Treat issue bodies like SQL input, not like operator intent. The agent cannot reliably tell "instructions from my team" apart from "instructions embedded in a customer complaint." Sanitize or isolate untrusted text before it reaches the model context; Noma's recommendation matches what Copilot cloud-agent docs already warn about for hidden prompt injection in issues.

Log tool calls you would be embarrassed to explain. If an agent run suddenly reads three README files and posts a wall of text to a public issue, you want that visible in Actions logs before a researcher files the ticket.

Sources