Screenshot redaction for developers: secure bug reports in seconds
Short answer: a good bug report needs context, the failing request, the console, the app state, and that is exactly where secrets hide. So scrub the sensitive parts inside the same capture-to-share loop, before the image goes anywhere, then use a Marker to circle the actual bug. Done in the editor in one pass, it costs seconds rather than a detour into a separate app, which is the only reason you will keep doing it. Here is what leaks in a dev context, how to still point clearly at the problem, and why making the safe path fast is the whole point.
Good bug reports leak secrets by design
A useless bug report says "it broke" with a screenshot of an empty error toast. A useful one shows the failing request, the response, the relevant log lines, the state the app was in. Context is what turns a ticket into something another developer can act on without three rounds of back-and-forth. The problem is that the context you need is the context where secrets live.
- The network panel shows the request that failed, and its
Authorizationheader, with a bearer token sitting right there. - Your terminal scrollback has the command that worked three lines up, the one that printed an API key to confirm it was set.
- A
.envor config block you opened to show one wrong value carries the database connection string, password and host included. - App state and admin screens are full of real customer data: email addresses, account IDs, names tied to whoever you happened to be testing against.
None of this is the bug. It is the frame around the bug, which is exactly why it slips through, you are looking at the red error, not the header above it. The better your report, the more context you capture, and the more there is to leak.
Scrub inside the loop, not as a detour
The honest reason secrets end up in tickets is not carelessness. It is friction. If cleaning a screenshot means saving the file, opening a separate editor, finding the redaction tool, doing the edit and re-exporting, you will manage it the first time and skip it the tenth, especially mid-debug, when you have a repro in front of you and just want to file it before it disappears.
So the safe move only happens if it is no slower than the careless one. That means the redaction has to live inside the capture-to-share loop itself: press the shortcut, scrub the secrets, mark the bug, paste into the ticket. No round trip to a website, no second app. A tool that uploads your image to a server to redact it fails this twice, it is slower, and it sends the unredacted original off your machine first, which is the exact thing you were trying to contain. I get into why on-device matters in the guide to redacting screenshots on Mac without uploading them.
What to scrub, and how to still point at the bug
Before a screenshot of a terminal, the dev tools, a config file or an admin screen goes into a ticket or a chat, run your eye over the frame for these:
- Tokens and keys: bearer, access and session tokens in request headers, cookies and URLs; API keys in scrollback and config.
- Secrets and connection strings: client secrets, signing keys, and any line from a
.envthat bundles a username, password and host. - Internal URLs and hostnames that expose staging environments or internal infrastructure.
- Customer and account data: email addresses, names, user IDs, order numbers, anything that ties the shot to a real person you were testing against.
Scrubbing does not mean hiding the bug. The point of the report is still to be read, so after you cover the secrets, use the Marker to circle the failing request or the wrong value, and the Text tool to label what should have happened. The reader's eye lands on the problem, not on the smudge. Scrub and mark are the same pass in the same editor, the secret disappears and the bug gets clearer in one go. The specifics of what counts as a credential are worth knowing cold, which is the focus of hiding API keys and emails in screenshots.
The loop on a Mac, step by step
With ScrubShot the whole thing is one uninterrupted move:
- Press the shortcut. It captures the screen you are looking at, the network panel, the terminal, the failing screen.
- Drag the Scrub tool over the token, the key, the connection string, the customer email. It is pixelated straight into the image as you go.
- Check the corners and the scrollback for anything you missed, and scrub that too.
- Use the Marker to circle the actual error and Text to label it, so the report reads at a glance.
- Crop down to the relevant frame if there is noise around the edges, then copy to the clipboard or let it save to your Pictures folder and paste it into the issue.
The Scrub tool rewrites the underlying pixels, so a scrubbed token cannot be lifted off or recovered later, it is gone, not covered. If you over-scrub or miss the mark there is Undo. None of it touches the network, so the cleanup happens in the half-second between the repro and the paste. When you are filing into Jira, GitHub or Linear, the cleaned image is the only version that was ever created.
A fast safe path is one you will actually repeat
Security advice that depends on you being diligent every single time loses, because nobody is. The thing that actually protects a codebase is a habit cheap enough to survive a bad afternoon, the day the build is broken, the on-call pager is going off, and you have four tickets to file before standup. On those days you will not take a detour. You will do whatever is in front of you.
So the win is not "remember to redact". It is making the redaction part of the same motion as taking the screenshot, so there is nothing extra to remember. Once scrubbing a token is one drag inside the capture, you stop deciding whether it is worth the effort, because there is no effort to weigh. That consistency is the whole protection. One caveat to keep honest about: redaction is not revocation. If a live secret already went into a ticket unredacted, editing a clean copy afterwards does nothing for the one already attached, rotate or revoke it at the source and treat it as compromised. Scrubbing is what stops the leak; it cannot reverse one.
FAQ
- What should I scrub in a bug report screenshot?
- Anything that grants access or identifies a person or environment: API keys and tokens in the network panel, connection strings and secrets in config, internal hostnames and staging URLs, email addresses and customer or account identifiers in app state. If it is not part of the bug you are reporting and you would not paste it into a public issue, scrub it before the screenshot leaves your Mac.
- How do I point at the bug clearly after I have scrubbed the secrets?
- Use the Marker to circle the actual error and the Text tool to label what is going on, so the person reading the report looks where you want them to. Scrubbing the secret and marking the bug are the same pass in the editor, so a clean report that still reads clearly takes seconds, not a second tool.
- A live token already went into an issue before I redacted it. Is editing the image enough?
- No. Once a real secret has been seen unredacted by anyone, treat it as compromised and rotate or revoke it at the source. Editing a clean copy afterwards does nothing for the version already attached to the ticket or the chat. Redaction protects the next screenshot; it cannot un-send the last one.
- Does redacting screenshots slow down filing a bug report?
- Only if redaction lives in a separate app. The reason it feels like a tax is the detour: save the image, open an editor, find the tool, re-export. When the scrub happens inside the capture-to-share loop on your own Mac, covering a token is one drag and the whole report still takes seconds. A fast safe path is the one you actually repeat.
Try it
ScrubShot is a Mac app built for exactly this: press the shortcut, drag over the token or the customer email to pixelate it into the image, circle the bug with the Marker, then copy or save and paste it into the ticket. The cleaned screenshot is the only version that ever leaves your Mac. There is a free 7-day trial with no card required. After that it is $30 once.