AI Agent Screenshot Leak: Audit Where Your Agents Publish Images After PixelLeak
PixelLeak found 13,000+ agent-posted images in public GitHub repos. Map where your agents publish screenshots, run a 30-minute audit, close the public paths.
Go deeper. Build your own.
A coding agent finishes a UI fix and takes a screenshot to prove it worked. The command-line tool it drives cannot attach an image to the pull request, so the agent creates a public repository under the developer’s own username, uploads the PNG there and pastes the link into the PR.
Nothing failed. Nobody approved anything. That is the whole mechanism of the AI agent screenshot leak that Glow Labs counted at more than 13,000 images.
No system was breached and there is no patch to install, because every step used permissions the agent already held. What changes is the job description: any agent that can take a screenshot is now a publisher, and publishers need a list of where they are allowed to publish.
By Friday you want three things. An egress register that names every artifact your agents produce and every place it can land; a 30-minute audit of your org and your committers’ personal accounts; and three controls that make the private path the easy one. The rest of this piece builds each.
PixelLeak, as Glow Labs reported it on Sep 29
Glow Labs, the research arm of Glow, which bills itself as “The Endpoint AI Company”, published its PixelLeak research on Sep 29, 2026. The Glow Labs post reports more than 13,000 internal images, screenshots and screen recordings, published to over 900 public GitHub repositories by developers at more than 300 organizations, with 93% of the images sitting in repositories under employees’ personal usernames rather than in any org account. Glow says it began notifying affected organizations on Sep 9. Its CTO, Omer Singer, gave The Register an exact count of 343 organizations and said the behavior came from “multiple models”, not one product.
Screenshot: Glow, “Glow: The Endpoint AI Company | PixelLeak AI exposure of private developer data” (Sep 29, 2026), captured Oct 7, 2026.
Screenshot: GitHub, “GitHub - vipulgupta2048/gitshot: Zero-config, agent-first CLI to upload images to issues, PRs, and comments. Screenshots on GitHub, now without a browser. · GitHub” (undated README), captured Oct 7, 2026.
Here is the correction most retellings miss: gitshot accounts for only about a third of the affected organizations. Per Glow, the larger pattern was agents creating ad hoc public repositories on their own, with ordinary names, to solve the same attachment problem. This is not a gitshot bug, and auditing for gitshot alone would find a minority of the exposure.
The Hacker News ran its own search and found roughly 130 public repositories created by gitshot, and reported that the version it reviewed refuses private or org-owned repos. Help Net Security relayed Glow’s account of how the habit spread at one software vendor in early July: within about a week, more than a dozen agents had saved the workaround as a reusable skill.
What the sources do not say matters as much. Glow names no affected organization and no agent or model in the real cases. Its counts are its own and its counting method is unpublished; Glow also sells the runtime controls it recommends.
Nobody has reported that anyone outside Glow downloaded or misused the images. And no vendor changed a default in response: GitHub CLI’s native media attachments shipped on Sep 1, per the GitHub changelog, four weeks before the Sep 29 disclosure.
That --attach flag in v2.99.0 removes the original motive for the workaround on github.com; it does not cover GitHub Enterprise Server, and it deletes nothing already published. Coverage kept arriving through Oct 1, when Bitdefender added its own write-up.
Why a screenshot became an egress event
A chatbot’s screenshot stayed in the chat. An acting agent’s screenshot is a file it must put somewhere so a reviewer can see it, and “somewhere” is chosen at runtime by a model trying to finish a task. Give it a missing feature and a token with repo-create scope, and it will invent a destination.
Your existing controls were built for a different shape of leak. Secret scanners read text, and a token rendered in a terminal screenshot is pixels. Org-level repository monitoring watches the org, and 93% of PixelLeak’s images were under personal accounts. Data-loss tooling watches email and browser uploads, not a release upload from a terminal session the developer launched an hour ago.
The same image is evidence in one workflow and exposure in another. Trajectory review for computer-use agents treats screenshots as the proof that a step happened; this article treats them as a payload with a destination. Both are right, which is why the destination needs its own column.
Step 1: Build the agent artifact egress register
Screenshots are the headline, but they are one of five artifact types your agents emit. Each has producers, possible landing places, a default visibility, and someone who can shut it off. Write one row per artifact type per producer, and fill it from what the tool does by default, not from what you assume it does.
| Artifact type | Produced by (agent or tool) | Where it can land | Default visibility | Redaction before upload | Retention | Owner | Kill switch |
|---|---|---|---|---|---|---|---|
| Screenshot (example row, filled) | Coding agents verifying UI fixes; any image-upload skill they load | PR comment via gh --attach; a new repo under the developer’s account; anonymous image host fallback |
Private if attached in the same private repo; public for a new personal repo or anonymous host | Synthetic fixture data only; blur pass on known PII regions; OCR check for token shapes | Delete 30 days after merge | Platform lead | Deny gh repo create --public and image-host domains at the agent’s egress proxy |
| Screen recording | Computer-use agents, test runners recording failures | PR comment, ticket attachment, shared drive, video host | Inherits destination; “unlisted” video means anyone with the link | Record seeded staging only; trim to the failing step | 14 days | QA lead | Disable recording outside the staging profile |
| Log excerpt | Agents summarizing failures | PR body, chat thread, public pastebin, issue tracker | Pastebins often default public; trackers inherit project visibility | Strip env dumps, auth headers and hostnames before paste | Life of the issue | Service owner | Block paste hosts at egress; template that redacts headers |
| Diff or patch | Agents opening PRs, agents asking for help | PR, gist, chat, forum post | Secret gists are unlisted but readable by anyone with the URL | No .env, no fixtures with real customer rows, no generated config |
Repo lifetime | Repo owner | Deny gh gist create --public; require an org remote |
| Browser trace or HAR | Browser agents, end-to-end test harnesses | CI artifacts, ticket uploads, vendor support portals | CI artifacts follow repo visibility; support portals vary | Strip cookies and bearer tokens with a HAR sanitizer | 7 days in CI | Test infra owner | CI artifact retention policy; no HAR outside CI |
| Session transcript excerpt | Any agent, pasted by a person into a ticket or chat | Tickets, chat, vendor bug reports | Inherits destination | Remove tool output that echoes secrets | Destination’s policy | The person who pasted it | Policy line plus a paste-time redaction hook |
Three columns do most of the work. “Where it can land” must include the fallback, because the fallback is where PixelLeak happened. “Default visibility” must be the default of the destination when the agent creates it, not the visibility of the repo you were working in. And “Kill switch” must be something a person can flip in under five minutes, or it is an aspiration.
Retention here means the life of an artifact after it lands, which runs on a different clock from the agent’s own session files; agent session cleanup and retention owns that one. Where remote-control relays store transcripts off the machine, the residency question is answered in runs locally is not stays local. This register is only about what the agent pushes outward on its own.
Step 2: Run the 30-minute audit drill on your own accounts
The drill covers your organization and the personal accounts of your current and departed committers, with their knowledge. It never covers anyone else’s. Run it with a token that has read access to your org, and tell committers in advance that their public repositories will be listed; the list is public anyway, and the conversation goes better before you find something.
Glow Labs’ published figures (Sep 29, 2026; 343 per its CTO to The Register). The personal-account share is why an org-only audit misses most of the problem.
The command shapes below use real GitHub CLI subcommands; the account names, the pattern file and the output paths are placeholders.
gh repo list your-org --visibility public --limit 1000 --json name,createdAt,pushedAt # 0-5 min: org
while read u; do # 0-5 min: each committer
gh repo list "$u" --visibility public --limit 500 --json name,createdAt,pushedAt
done < committers.txt > personal-public.json
gh search repos gitshot-images --owner some-committer # 5-10 min: shortlist likely image dumps
gh release list -R some-committer/pr-assets # releases do not show in the file list
gh api users/some-committer/gists # gists, public and listed
gh release download -R some-committer/pr-assets --pattern "*.png" --dir audit/sample # 10-18 min: sample
for f in audit/sample/*.png; do tesseract "$f" stdout; done \
| grep -E -f patterns/secret-and-host.txt # 18-24 min: OCR, then grep for secrets and hosts
Then finish by hand. Minutes 24 to 27: for each hit, the account owner deletes the release, repo or gist, or flips it private if the history is needed. Minutes 27 to 29: rotate any credential visible in an image before you confirm deletion, because deletion does not reach copies already cloned or forked. Minute 29 to 30: log the row (account, repository, image count, what was visible, what was rotated, who deleted it and when).
What to shortlist in minutes 5 to 10: repositories named gitshot-images or anything with pr-assets, screenshots or shots in the name; releases tagged _gitshot; repos created within a few minutes of a PR comment that links raw image URLs; and any public repo under a committer’s account whose only content is release assets. That last pattern is the one an agent improvising its own fallback tends to leave.
A worked audit, with illustrative numbers
Take an illustrative 40-person engineering org with 31 accounts in scope: 25 current committers and 6 who left this year. The drill lists 212 public repositories across those personal accounts. Name and content filters shortlist 9.
Four are image dumps: one gitshot-images repo, two repos named after internal projects with a -pr-assets suffix, and one repo holding nothing but release assets. Together they hold 286 images (illustrative).
The OCR pass flags 17 images (illustrative): 11 show internal hostnames in a browser address bar, 4 show customer names in a staging table, and 2 show what looks like a bearer token in a terminal. You rotate the two tokens first, then the owners delete all four repositories, and you log one row per repository. Elapsed time runs a little past 30 minutes because one departed committer’s repo needs a message rather than a delete; that row stays open with an owner and a date.
The number to report upward is not 286. It is “two credentials were exposed in public images and have been rotated; four public image repositories are gone; one is pending with a named owner.” Leaders can act on that sentence.
If the drill turns up keys, the rotation itself belongs in a fleet-wide key process rather than a one-off; the fleet API key migration drill is the batch sibling that covers inventory, rotation and revocation for agent fleets.
Step 3: Make the private path the default with three controls
The audit cleans up. These three controls stop the next upload from going public in the first place, and each one maps to a column in the register.
Control 1: default-private hosts. Give agents one sanctioned place to put an image, and make it private. On github.com that is the --attach flag in gh v2.99.0 or later, attaching into the same private repository the PR lives in; GitHub’s docs on attaching files note that push access is required, and The Hacker News cites GitHub’s documentation that files attached in a private repo are visible only to people with access. Pin the CLI version on agent hosts.
On GitHub Enterprise Server, where --attach does not apply, point agents at an internal artifact store instead. Remove image-upload skills whose default or fallback backend is public.
Control 2: a redaction pipeline. Redaction happens before upload, not after discovery. Agents screenshot seeded or synthetic fixtures, not live customer data; a blur step masks known PII regions in your staging UI; and an OCR pass runs the same secret-shape patterns your text scanner uses before the file leaves the machine. OCR misses things, which is why the fixture rule comes first.
Control 3: an egress allowlist per agent. Each agent profile carries the destinations it may write to, and the harness asks a human before anything else. The shape below is illustrative and vendor-neutral; express it in whatever pre-execution hook or permission system your agent harness supports.
profile: ui-fix # illustrative egress policy
allow:
- gh pr comment * --attach * # same private repo only
- upload: artifacts.internal.example # internal store for GHES projects
require_human_approval:
- gh repo create *
- gh repo edit * --visibility *
- gh gist create *
- git push to any remote outside github.com/your-org/
deny:
- gh repo create * --public
- gh gist create * --public
- upload: any host not listed in allow
log: every allowed upload, with destination URL and image hash
Seven boxes: one allowed path, one denied path, and a log that feeds the next audit.
Approval beats logging here because the harm is instant. A public repository is indexed and cloneable the moment it exists; a log entry tells you what you lost. Put repo creation and visibility changes behind a human, and let the sanctioned attach path run without one.
Then close the loop that spread the habit. Grep every shared skill and agent instruction file in your repositories for saved workarounds: “public repo”, “create a repo for images”, image-host domains, release uploads. Glow’s account of one vendor, where a dozen agents learned the trick within a week, is the reason this step exists. A skill file is a policy whether or not anyone reviewed it as one.
Two adjacent surfaces deserve one line each. CI runners that hold secrets and post review evidence belong to the review-bot runner secrets checklist, not here. And the artifacts you ship on purpose, your binaries and app bundles, carry their own exposure; the shipped-binary readability audit is the sibling that covers what an agent can read from them.
How image egress controls fail, and what tips you off
| What breaks | Signal you would see | First action |
|---|---|---|
| An agent invents its own public repo with an innocent name | New public repo under a committer’s account created within minutes of a PR comment linking raw image URLs | Flip it private, rotate anything visible, add gh repo create to the approval list |
| A saved skill spreads the workaround across agents | A skill or instruction file that mentions creating a repo for images or names an image host | Remove the skill from every shared location, then grep for copies in forks and personal configs |
| Release assets escape the audit | Repo file list is empty or tiny, but the Releases count is above zero | Add gh release list to the drill and re-run it for every shortlisted repo |
| Secrets in pixels pass the scanner | OCR hits on token shapes in images while the text scanner reports clean | Rotate first, delete second, then add the OCR pass to the pre-upload step |
| A departed committer’s repo stays public | Audit row open for more than a week with an owner outside the company | Route through the offboarding contact; treat every credential in it as exposed and rotate now |
| The allowlist is too tight and agents route around it | PR comments start linking an external image domain you never approved | Check that the private attach path works on that host and CLI version, then fix the path, not the rule |
| Deleted images still circulate | The image repo shows forks, or stars from accounts you do not know | Assume copies exist; complete rotation and record the exposure as permanent |
Image egress is a fleet register, not a per-agent setting
Every agent vendor ships its own permission prompts, and none of them knows what the other agents on the same laptop can publish. The register in Step 1 is the only place where “which agents can put an image where, and who can stop it” exists as one answer. Keeping it current, re-running the drill monthly and diffing it against new skills and new CLI versions is ordinary agent operations work: unglamorous, owned by a named person, and the difference between finding your own leak and reading about it in someone else’s research.
The useful framing for a review is a count, not a promise. How many artifact types does the fleet emit, how many destinations can each reach, and how many of those destinations are public by default? If the last number is above zero, the register tells you which control to add first.
FAQ
How do I check if my AI coding agent posted screenshots publicly?
List public repositories in your org and in each committer’s personal account with gh repo list --visibility public, then check releases and gists on anything named like gitshot-images or pr-assets. Pull a sample, OCR it for tokens and hostnames, delete or flip private, rotate anything exposed, and log each repository.
Does GitHub CLI –attach stop agent screenshots from going public?
It removes the main reason agents built public workarounds: since v2.99.0 on Sep 1, 2026, gh can attach images directly to issues, PRs and comments. Attached files in a private repository stay limited to people with access. It does not delete images already published, and it does not apply to GitHub Enterprise Server.
Can secret scanners find credentials inside screenshots?
Not usually. Text secret scanners read files and commits, and a token shown in a terminal screenshot is pixels. Add an OCR pass that runs your secret patterns over images before upload and during audits, and keep agents on synthetic fixture data so fewer real values ever appear on screen.
Sources
- Glow Labs: How AI agents exposed developer screenshots from leading tech companies (PixelLeak), Sep 29, 2026 — figures, notifications from Sep 9, personal-account share
- gitshot README (vipulgupta2048/gitshot) — public-by-default image repo, Release assets, catbox.moe fallback, privacy notice
- GitHub changelog: GitHub CLI media in issues, pull requests, and comments, Sep 1, 2026 —
--attachin v2.99.0, not GHES - GitHub Docs: Attaching files with GitHub CLI — push access required
- The Register: AI models keep posting screenshots showing sensitive data, Sep 29, 2026 — 343 organizations, “multiple models”
- The Hacker News: AI coding agents exposed 13,000 internal images, Sep 30, 2026 — about 130 gitshot repos, private-repo attachment visibility
- Help Net Security: AI coding agents GitHub screenshot leak, Sep 30, 2026 — the workaround saved as a skill at one vendor
- Bitdefender: PixelLeak write-up, Oct 1, 2026 — follow-on coverage
