nullcipher

Heroku API keys and OAuth tokens (HRKU-…)

HRKU-AA followed by 58 letters, digits, dashes or underscores — Heroku's prefixed token format — or an older UUID-shaped key after a heroku-named setting. Below: the exact rule, a live check, why it matters, and what to do if one already leaked.

Live check: Heroku API key

What an AI chat would receive after masking

# EXAMPLE, not a real token
HEROKU_API_KEY=[HEROKU_API_KEY_V2_1]

1 × Heroku API key found and masked.

How nullcipher recognises it

Checked only when the text contains “hrku-aa” (any case). Pattern (gitleaks rule heroku-api-key-v2, v8.30.1, translated to JavaScript): /\b((HRKU-AA[\-0-9A-Z_a-z]{58}))(?:[\s"';`]|\\[nr]|$)/ — the first capture group is masked; any surrounding key name stays readable. The masked part must have a Shannon entropy above 4 bits per character, so repetitive placeholders like xxxx are left alone.

This is the rule text of the “Heroku API key (HRKU- format)” detector in the masking engine, copied from the engine when this page was built; the rule is ported from gitleaks’ default rule set (MIT licence; version, skipped rules and changes). Detectors run in a fixed order and, where two overlap, the earlier one wins.

The same page covers 1 more rule, each with its own placeholder:

Heroku API key (older UUID format) — [HEROKU_API_KEY_1]
Checked only when the text contains “heroku” (any case). Pattern (gitleaks rule heroku-api-key, v8.30.1, translated to JavaScript): /[\w\-.]{0,50}?(?:[Hh][Ee][Rr][Oo][Kk][Uu])(?:[\w\t \-.]{0,20})[\s"']{0,3}(?:=|>|:{1,3}=|\|\||:|=>|\?=|,)[\s"'=`]{0,5}([0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12})(?:[\s"';`]|\\[NRnr]|$)/ — the first capture group is masked; any surrounding key name stays readable. (gitleaks rule)

Example (fake)

# EXAMPLE, not a real token
HEROKU_API_KEY=HRKU-AAEXAMPLE_not_a_real_token_EXAMPLE_not_a_real_token_EXAMPLE0

nullcipher replaces it with [HEROKU_API_KEY_V2_1]. After HRKU-AA comes the phrase EXAMPLE_not_a_real_token. Heroku never issued it.

Why it matters in an AI chat

Heroku's docs say its OAuth access tokens are 65 characters long and prefixed with HRKU-, so leaked tokens can be found in code and logs by searching for the prefix; a token without the prefix has not been regenerated since the change.

The Heroku CLI uses your API token for every Platform API request, and the same token authenticates git pushes over HTTPS. Whoever holds it can deploy code to your apps, read their config vars — which usually hold database URLs and other keys — and scale dynos on your bill.

Tokens are stored in ~/.netrc by the CLI when no keychain is available, and that file, or the output of heroku auth:token, is easy to paste into an AI chat by accident.

If it already leaked

  1. Regenerate your API token in the Heroku web interface (account settings). Heroku says regenerating invalidates the current token and creates a new one; changing your password regenerates it too. [1]
  2. For a token created as an OAuth authorization (for a script or a third party), revoke the authorization: DELETE /oauth/authorizations/{authorization-id} blocks its tokens from making further requests. [2]
  3. Because the token could read config vars, rotate the secrets stored there (database passwords, API keys) as well.

Sources

  1. Heroku CLI authentication — Heroku Dev Center — checked 2026-09-25.
  2. OAuth: prefixed tokens and revoking authorization — Heroku Dev Center — checked 2026-09-25.

Open the full masking tool to mask a whole log, .env file or e-mail — every type at once — and restore the values in the AI's answer. Or see all 229 detectors, with a page for 46 secret types, and how to delete a chat you already sent.