← Back to Blog

Developers & Code | Published Aug 21, 2026 | Updated Oct 13, 2026 | 6 min read

How to Redact Tokens From Stack Traces Before Sharing

By Deepender Yadav

How to Redact Tokens From Stack Traces Before Sharing — Edge Drop Guide

Before you share a stack trace, search it for anything that grants access, such as a bearer token, API key, password in a connection string or private key, and replace each value with a placeholder like <redacted>, keeping the surrounding text so the error still makes sense. Do it in an editor or with a script before the text reaches chat, a ticket or an AI assistant. If a real secret has already been shared, revoke it and issue a new one; deleting the message isn't enough.

Where secrets hide in stack traces and logs

A plain stack trace is file names, line numbers and an error message, but secrets get pulled in from around it:

  • Error messages that echo their input. An HTTP client error that includes the full request URL also includes any ?api_key= or ?token= in it. A connection error your code formats with the connection string includes the password.
  • Request details. Error pages, debug middleware and error-reporting tools often attach request headers, cookies and query strings, including Authorization headers and session cookies.
  • Local variables. Some tools print variable values next to each frame, for example pytest with --showlocals (-l) and error trackers that capture locals. A variable holding a token is printed with everything else.
  • Configuration and environment dumps. Startup logs or failure handlers that print settings or environment variables expose every secret in them.
  • The command you ran. A curl command with -H "Authorization: Bearer ..." or a password on the command line is a secret in your terminal history and in any log that records it.

The OWASP Logging Cheat Sheet lists access tokens, passwords, database connection strings, encryption keys and session identifiers as data that usually shouldn't be recorded in logs at all.

Patterns to search for

WhatWhat it looks likeReplace with
Bearer tokenBearer abc123...Bearer <redacted>
JWTThree dot-separated parts starting with eyJ<redacted-jwt>
AWS access key IDAKIA or ASIA plus 16 uppercase letters and digitsAKIA<redacted>
GitHub tokenghp_, gho_, ghu_, ghs_ or ghr_ plus 36 characters<redacted-github-token>
Slack tokenStarts with xox and a letter, then a hyphen<redacted-slack-token>
Password in a URLscheme://user:password@hostscheme://user:<redacted>@host
Key in a query string?api_key=..., &token=...?api_key=<redacted>
Key in JSON or a dict"password": "...""password": "<redacted>"
Private key-----BEGIN ... PRIVATE KEY----- block<redacted-private-key>

Keep the key name and the shape of the value. api_key=<redacted> tells the reader a key was present, which can matter for the diagnosis; an empty value looks like a bug.

Patterns miss things: a password in an unusual field, a token in a custom header, an internal hostname you'd rather not share. Read the result once before you paste it.

A small redaction script

This Python script reads text, applies the patterns above and writes the result. It uses only the standard library.

import re
import sys

PATTERNS = [
    # "Bearer <token>" in headers or logs
    (r"(?i)(bearer\s+)[A-Za-z0-9._~+/=-]+", r"\1<redacted>"),
    # JSON Web Tokens
    (r"\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*", "<redacted-jwt>"),
    # AWS access key IDs (long-term AKIA, temporary ASIA)
    (r"\b(AKIA|ASIA)[0-9A-Z]{16}\b", r"\1<redacted>"),
    # GitHub tokens
    (r"\bgh[pousr]_[A-Za-z0-9]{36,}\b", "<redacted-github-token>"),
    # Slack tokens
    (r"\bxox[abposr]-[A-Za-z0-9-]+", "<redacted-slack-token>"),
    # Password in a connection URL: scheme://user:password@host
    (r"(://[^:/\s@]+:)[^\s/]+@", r"\1<redacted>@"),
    # Secrets in query strings: ?api_key=... &token=...
    (r"(?i)([?&](?:api_?key|access_token|token|key|secret|password)=)[^&\s]+", r"\1<redacted>"),
    # Secrets in JSON or dict output: "password": "..."
    (r"(?i)([\"'](?:api_?key|token|secret|password)[\"']\s*:\s*[\"'])[^\"']+", r"\1<redacted>"),
    # Private key blocks
    (r"-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----", "<redacted-private-key>"),
]

text = sys.stdin.read()
for pattern, replacement in PATTERNS:
    text = re.sub(pattern, replacement, text)
sys.stdout.write(text)

Save it as redact.py, then run it on a file. In Command Prompt or Git Bash (in WSL, use python3):

python -X utf8 redact.py < trace.txt > trace-redacted.txt

Or redact whatever is on the clipboard in PowerShell and put the result back:

Get-Clipboard -Raw | python -X utf8 redact.py | Set-Clipboard

The clipboard version is convenient for plain ASCII logs. If the text contains accented or non-Latin characters, use the file version, because PowerShell's pipeline to and from external programs depends on console encoding settings.

For scanning whole repositories or CI output, use a maintained scanner with a larger rule set, such as gitleaks or Yelp's detect-secrets, rather than growing this script.

Example: before and after

Before:
ConnectionError: could not connect to postgres://app_user:s3cretP@ss@db-prod-01:5432/app
GET https://api.example.com/v1/invoices?api_key=abc123SECRETvalue&page=2 returned 401
Headers: {"Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMifQ.c2lnbmF0dXJl"}

After:
ConnectionError: could not connect to postgres://app_user:<redacted>@db-prod-01:5432/app
GET https://api.example.com/v1/invoices?api_key=<redacted>&page=2 returned 401
Headers: {"Authorization": "Bearer <redacted>"}

The error, the host, the endpoint and the status code are all still there for whoever is debugging.

Why redact before the clipboard, not after

Once a secret is copied, it can end up in more places than the message you paste it into: Windows clipboard history if it's on, another device if clipboard sync is on, and any clipboard manager you run. Opening the raw trace in an editor, redacting there and copying only the clean version keeps the original out of all of them. If you do copy a secret, clear clipboard history (Win+V, then Clear all) once you're done; is an API key on the clipboard a security incident? covers the rest of the cleanup.

Online tools are another route out. Pasting a real token into a web-based JWT decoder or regex tester sends it to someone else's page; see whether it's safe to paste tokens into online debuggers.

Code review gives you a natural checkpoint: if you batch review comments in a pending review, reread any pasted logs for secrets before you click Submit review.

If a secret has already been shared

  1. Revoke or rotate it with the service that issued it. This is the step that actually ends the exposure.
  2. Remove or edit the message, comment or issue, so the value doesn't stay visible to new readers.
  3. Check where else it went, such as notification emails, linked tickets, CI logs and AI chat history.
  4. Fix the source, so the next trace doesn't print it: configure your logger or error tracker to mask known fields, and stop formatting connection strings into error messages.

On GitHub, secret scanning checks public repositories, including issue and pull request comments. For supported providers' tokens, GitHub notifies the provider, which can revoke the credential. Treat that as a safety net, not a reason to skip rotation.

FAQ

Is a stack trace without secrets safe to share publicly?

It still reveals file paths, internal hostnames, library versions and sometimes user data. For public issues, trim it to the frames that matter, as described in how to copy an error log without the noise, and replace internal names you don't want to publish.

Should I redact request IDs and user IDs?

Request IDs usually help the person debugging and don't grant access, so keep them for internal tickets. Remove personal data such as email addresses or names, especially anywhere public.

Can I just blur a screenshot of the log instead?

Share text instead. Text is searchable and copyable for the person helping you, and blurring or cropping can miss part of a value.

Related reading

Sources

Deepender Yadav
Written by Deepender Yadav · Creator & Developer

Deepender Yadav created Edge Drop and builds and tests it, from the edge-hover shelf to each release. A B.Tech Computer Science Engineering student, Deepender writes the Edge Drop guides, comparisons and developer posts, and checks product details against the app's source code.

GitHub · LinkedIn

Copy. Stack. Drop.

Transform your clipboard into an interactive edge shelf. Stack, pin, and drag assets into any app with zero friction.

Download for Windows Get from Microsoft Store

How to Install Guide · First 10 Minutes Guide · Drag & Drop Guide · Edge Drop vs Win+V · Support

Free · Lightweight · Privacy First
Find us on CodeHype