Redact API keys, secrets and personal data from text

Paste logs, config or a prompt and replace API keys, tokens, passwords, emails and card numbers before you share it. Nothing is uploaded.

How it works

  1. Paste the logs, config or prompt
  2. Switch detectors on or off and pick the replacement style
  3. Check the result and the table of what was found, then copy it

What gets replaced

To redact API keys from logs, paste the text and the page replaces every match with a placeholder such as [REDACTED:AWS_ACCESS_KEY], leaving the rest of the text as it was. Worked example: the sample log has an email twice, an IPv4 address, an AWS key pair, a GitHub token, an OpenAI key, a password in a database URL, a quoted password, a JWT in an Authorization header and a card number. That is 11 redactions, and the table lists each type with a count, never the value. Detectors cover AWS access key IDs (AKIA, ASIA), AWS secret keys after aws_secret_access_key, GitHub tokens, OpenAI keys including sk-proj-, Anthropic keys (sk-ant-), Google API keys (AIza), Slack tokens, Stripe live keys, JWTs, private key blocks, bearer and Basic header values, user:password@ in URLs, password=, secret=, token= and api_key= values, emails, IPv4, IPv6 and phone numbers. IPv6 and phone numbers start switched off because they match ordinary text more often.

Replacement styles and numbering

The default style is [REDACTED:TYPE]. Switch on numbering and the same value always gets the same number, so jane@example.com becomes [EMAIL_1] each time and a second address becomes [EMAIL_2]. That keeps a log readable for the person you send it to: they can still see that two lines involve the same user. The other style keeps the first 4 characters of values that are 12 characters or longer and hides the rest, so AKIAIOSFODNN7EXAMPLE becomes AKIA****. Shorter values become ****. Keeping 4 characters helps you spot which key it was, but it is also 4 characters of the secret, so use the label style when the text goes outside your team.

Why it cannot promise to catch everything

The page matches patterns. A key with a format it does not know, a password in a sentence, a name, an address or a secret split across two lines will pass through unchanged, and an ordinary string can look like a secret and be replaced. A password= value that is a variable reference such as $DB_PASS or {{ token }} is left alone on purpose. A card number is replaced only when it has 13 to 19 digits, starts with 3, 4, 5 or 6 and passes the Luhn check, so order numbers and timestamps are usually left alone. Read the result before you share it, and rotate any real key that has already been pasted somewhere. Replacing it here does not make an old copy safe.

Limits and safety of the matching

The patterns are written so that a long run of repeated characters cannot make the page hang; the tests run 1 MB of such text through every detector. Text up to 1,000,000 characters is accepted. If more than 50,000 matches are found, the page shows an error instead of a partial result, because a half-redacted text would look finished. Where two detectors match the same text, the more specific one wins, so a key in api_key=sk-proj-... is reported as an OpenAI key and not as a generic secret. The text is processed in this tab and the table never shows a matched value.

Frequently asked questions

How do I remove API keys from logs before sharing them?

Paste the log, leave the key detectors on and copy the result. Each key becomes a placeholder such as [REDACTED:GITHUB_TOKEN]. With the sample log you get 11 redactions, and the table shows the type and count of each, not the values.

Is it safe to paste my logs into ChatGPT after this?

It lowers the risk but does not remove it. The page only catches the patterns it knows, so read the result line by line first. A name, a customer ID or a password with no label can still be in the text, and any key that was already shared should be rotated.

Can the same email get the same placeholder every time?

Yes. Turn on Number repeats and every copy of jane.doe@example.com becomes [EMAIL_1], while the next different address becomes [EMAIL_2]. The numbering applies to the label style and restarts each time you change the text.

Why was my credit card number not redacted?

A number is replaced only if it has 13 to 19 digits, starts with 3, 4, 5 or 6 and passes the Luhn check. A 16-digit number that fails the check, such as 4111 1111 1111 1112, is left alone. Digits split by anything other than a single space or hyphen are not joined.

Why are IPv6 and phone numbers off by default?

Both patterns also match harmless text, such as C++ scope names like A::B or long reference numbers. Switch them on if your text has real addresses or numbers, then look at what was replaced.

Is my text uploaded?

No. The text is processed in your browser and not uploaded. The detector switches and style are saved in this browser, never the text.