Guides/Playbook

PixelLeak disclosed: Keep agent screenshots inside private review

7 min read
On this page
A screenshot sheet crossing a private boundary and leaving an exposed copy outside it

PixelLeak screenshot security

General Analysis

An agent can keep a code change inside a private repository and still publish the screenshots used to review it. On September 29, 2026, Glow disclosed PixelLeak: coding agents used public GitHub repositories to host images intended for internal review. Glow reported more than 13,000 images across over 300 organizations, with 93% of cases involving repositories under employees' personal usernames.

The immediate decision is where an agent may send review artifacts. Stop unapproved publishing, investigate earlier uploads, and give the workflow a private destination with an explicit failure path. An attachment error must leave the screenshot local until someone resolves it.

There is already a supported command-line route. GitHub CLI 2.99.0, released September 1, added image and video attachments to issues, pull requests, and comments. That predates the disclosure and Glow's September 9 notification campaign. The release supplies an alternative to public hosting; it does not establish which versions or permissions the affected agents used.

The findings here belong to Glow. General Analysis has not recounted the exposed images or reproduced the incident. The procedure below combines the disclosure with GitHub's documented behavior and our recommendations for platform teams.

Approve the destination before the screenshot leaves#

Treat the screenshot as a separate data transfer. Record the source workspace, the account making the upload, the receiving repository or service, and the people allowed to retrieve the file. A private pull request does not make an externally hosted image private.

GitHub's attachment documentation says uploaded files in private or internal repositories require repository access. Public-repository uploads are accessible without authentication. Choose the destination based on the intended audience: an internal repository can still have a broader audience than the team reviewing a sensitive change.

Use this decision table before approving an upload:

SituationReview pathIf the path fails
GitHub.com or Enterprise Cloud, approved repository, suitable agent permissionsNative CLI attachment to that explicit repositoryKeep the file local and report the error
Agent lacks the required push accessAuthorized reviewer attaches it, or use approved private artifact storageDo not broaden repository permissions just to embed an image
Other host or unsupported attachment capabilityUse a separately verified private upload processDo not assume Cloud behavior applies
Destination owner, visibility, or audience is unknownResolve those details before uploadDo not let the agent pick a replacement host

GitHub documents push access as a prerequisite. An agent intended only to comment should not receive wider code-write authority as an incidental screenshot fix. A human upload or a narrowly scoped artifact service may fit that workflow better.

See how your AI systems hold up under real attacks

General Analysis maps AI applications and agents, red teams prompts, retrieval, tools, MCP servers, browser actions, permissions, and business workflows, then turns findings into evidence your team can reproduce and retest.

Make the receiving repository explicit#

First inspect the intended repository. This read-only example uses placeholder ownership; replace it with the approved destination. GitHub's gh repo view reference lists the requested fields.

Code source: GitHub CLI repository reference, adapted.

Shell
gh repo view https://github.com/example-org/private-app \ --json nameWithOwner,visibility,viewerPermission

Confirm that the returned owner and visibility match the approval, then check the credential identity through your managed authentication process. Repository access alone does not tell you whether this is the intended account. This inspection is a snapshot, not an enforcement policy.

After reviewing the pixels and approving the destination, a permitted uploader can attach the files to the existing pull request. The following example creates a comment and uploads both images; it is documentation, not a command we executed. Substitute your repository, pull request number, and sanitized local files.

Code source: GitHub CLI attachment guide and gh pr comment, adapted.

Shell
gh pr comment 123 \ --repo github.com/example-org/private-app \ --body-file review.md \ --attach './before.png#Before the layout change' \ --attach './after.png#After the layout change'

The CLI adds uploaded URLs to the comment body. Keep review.md local and check it for unintended content too. If an upload or comment operation fails, inspect what was created before retrying. Do not infer that a failed command left no remote artifact.

For the first approved use, check the resulting image with an intended reviewer and with an account lacking repository access. Check the direct attachment as well as the pull request. Use a harmless test image for this acceptance check; record the observation rather than assuming that a visible image proves privacy.

Find earlier uploads by storage location#

Pause the publishing workflow while the responsible team investigates. Work from authorized endpoint records, upload logs, pull request links, and developer-assisted inventory. Include company work performed through personal accounts where your investigation is authorized; an organization-only repository list leaves that scope unresolved. Our shadow-AI guide covers the preceding task of finding unmanaged agent use.

For each artifact, preserve its URL, storage object or commit identifier, owning account, approximate exposure interval, and source workflow in a restricted incident record. Review the actual image or recording through your incident process. Filenames alone cannot establish what appeared on screen.

Cleanup depends on where the bytes live:

Storage locationRemoval work to assignEvidence still needed
File committed to GitCoordinate removal from relevant history and referencesOld commits, forks, clones, and cached views
Release assetRemove the uploaded asset through the repository ownerDirect asset URL and any separately uploaded copies
Gist or another hosting serviceUse that service's removal processOriginal URL, versions, and copied links
Link in a pull request or commentRemove or replace the reference and locate its targetWhether the underlying upload remains accessible

These are investigation categories, not a guarantee that every copy can be found. GitHub's sensitive-data removal guidance warns that rewriting Git history does not remove other people's clones or all forks, cached views, and pull request references. GitHub Support assistance is conditional. Do not apply a history-rewrite procedure to a release asset and call the asset removed.

Revoke or rotate any exposed credential promptly. For screenshots of customer records or unreleased work, credential rotation cannot retract the information. Assign the data owner to assess the remaining exposure, and keep inaccessible accounts or unknown copies open in the incident record.

Remove the workaround from future runs#

Glow describes agents saving public screenshot hosting as a reusable skill. Review the specific skill, helper, project instruction, or scheduled workflow that chose the destination. Updating gh leaves those instructions in place.

Replace the procedure with an approved destination and a stop condition. Back that instruction with controls on the actual publishing paths available to the agent, including shell, API, browser, and connected tools. A shell-command approval rule covers only the paths it intercepts. The broader runtime controls are in our coding-agent security guide.

Close the incident against recorded observations. The approved upload should reach the intended reviewer, while an account without repository access cannot retrieve the test attachment. Each old public location needs a disposition, and the replacement workflow must stop when its approved upload path fails. Record the tested client, host, account, and policy revision beside those results. Leave unresolved copies and untested paths assigned to the incident owner.

Frequently asked questions

  • Does upgrading GitHub CLI fix PixelLeak?

    It supplies a supported attachment path on GitHub.com and GitHub Enterprise Cloud, but it does not remove existing public images or change saved agent skills. Review upload destinations, permissions, prior copies, and the instructions that selected public hosting.

  • Are screenshots attached to a private GitHub repository public?

    GitHub documents that files attached to private or internal repositories require access to that repository. Public-repository attachments are accessible without authentication. This differs from linking a private pull request to an image hosted in a separate public repository. Verify the actual destination and access behavior.

Browse all