redact-secret · Report
OAuth access token (HRKU-prefixed)
HRKU- prefixed OAuth access token in its two documented prefixed generations: 41 characters (HRKU- plus a UUID, granted 2024-04-01 to 2025-04-22) and 65 characters (HRKU- plus 60 of [A-Za-z0-9_-], granted from 2025-04-23, observed to begin AA).
Research record
3 events in the review history: 2 observed, 1 reviewed. Latest: observed on 2026-09-24 by automation, project maintainer. Project-maintained review is not independent validation. The family record at this release.
Format
What it looks like
- Descriptive pattern
^HRKU-(?:AA[A-Za-z0-9_-]{58}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$
Parts are shown as recorded. Evidence classes belong to the facts below; no class is assigned to a part.
Format facts
Provider documented ·
provider-source· current · observed 2026-09-23HRKU- prefixed OAuth access token (41-character 2024-04 and 65-character 2025-04 generations): the page states "Heroku OAuth access tokens are 65 characters long and prefixed with HRKU-" and shows a 65-character worked example beginning HRKU-AA (not reproduced here, since secret scanners classify it as a live token); its own response examples, changelog-items/2842 and changelog-items/3175 ("increasing from 41 characters to 65 characters") document the earlier 41-character HRKU-<uuid> generation. The literal AA after the dash is example- and tool-observed and the [A-Za-z0-9_-] body alphabet is tool-corroborated; neither is stated in prose
- devcenter.heroku.com/articles/oauthprovider-documentation · last read 2026-09-24 · latest outcome read · supports the page states "Heroku OAuth access tokens are 65 characters long and prefixed with HRKU-" and shows a 65-character worked example beginning HRKU-AA (not reproduced here, since secret scanners classify it as a live token); its own response examples, changelog-items/2842 and changelog-items/3175 ("increasing from 41 characters to 65 characters") document the earlier 41-character HRKU-<uuid> generation. The literal AA after the dash is example- and tool-observed and the [A-Za-z0-9_-] body alphabet is tool-corroborated; neither is stated in prose
Tool corroborated ·
tool-corroboration· current · observed 2026-09-23Pinned scanner rules are consistent with the contract grammar (2 artifacts: gitleaks 8.30.1; trufflehog 3.97.4).
- gitleaks/gitleaks @ v8.30.1: config/gitleaks.tomlscanner-rule-source · last read 2026-10-04 · latest outcome read · supports gitleaks 8.30.1: gitleaks.toml
- trufflesecurity/trufflehog @ v3.97.4: pkg/detectors/heroku/v2/heroku.goscanner-rule-source · last read 2026-09-23 · latest outcome read · supports trufflehog 3.97.4: heroku/v2
Provider documented ·
field-prefix· current · observed 2026-09-24prefix: HRKU-
- devcenter.heroku.com/changelog-items/2842provider-documentation · last read 2026-09-24 · latest outcome read · supports prefix: HRKU-
- devcenter.heroku.com/articles/oauthprovider-documentation · last read 2026-09-24 · latest outcome read · supports prefix: HRKU-
Provider documented ·
field-g2-total-length· current · observed 2026-09-24g2-total-length: 65 characters for tokens granted from 2025-04-23
- devcenter.heroku.com/changelog-items/3176provider-documentation · last read 2026-09-24 · latest outcome read · supports g2-total-length: 65 characters for tokens granted from 2025-04-23
- devcenter.heroku.com/articles/oauthprovider-documentation · last read 2026-09-24 · latest outcome read · supports "65 characters long and prefixed with HRKU-"
Provider documented ·
field-g2-aa-start· current · observed 2026-09-24g2-aa-start: the 60-character G2 body begins AA (Also pinned by gitleaks 8.30.1 and trufflehog 3.97.4 (tool); osv-scalibr does not pin it. Kept in `pattern` as observed/tool grammar, never as provider-stated; no non-AA twin or control asserts silence on it (#235).)
- devcenter.heroku.com/articles/oauthprovider-documentation · last read 2026-09-24 · latest outcome read · supports worked example only; not stated in prose
- github.com/trufflesecurity/trufflehog/issues/4510provider-documentation · last read 2026-09-24 · latest outcome read · supports disputed: a reporter says AA is not a fixed prefix; a vendor sample still matched it
Unresolved ·
field-g2-body-alphabet· current · observed 2026-09-24g2-body-alphabet: [A-Za-z0-9_-]
- gitleaks/gitleaks @ v8.30.1: config/gitleaks.tomlscanner-rule-source · last read 2026-10-04 · latest outcome read · supports g2-body-alphabet: [A-Za-z0-9_-]
- github.com/redact-secret/redact-secret-benchmarks/issues/235scanner-rule-source · last read 2026-09-24 · latest outcome read · supports consistent with the provider examples, which contain "_"
Unresolved ·
field-g2-checksum· current · observed 2026-09-24g2-checksum: internal structure behind "additional security checks for token validation" (Undocumented; nothing relies on it.)
- devcenter.heroku.com/changelog-items/3175provider-documentation · last read 2026-09-24 · latest outcome read · supports g2-checksum: internal structure behind "additional security checks for token validation"
Provider documented ·
field-g1-generation· current · observed 2026-09-24g1-generation: HRKU- plus a 36-character UUID, 41 characters, granted 2024-04-01 through 2025-04-22 and valid until regenerated (Corrects the earlier "undocumented-width variant" note. Pinned gitleaks and trufflehog do not match this generation (GitLab's rule matches only it).)
- devcenter.heroku.com/changelog-items/2842provider-documentation · last read 2026-09-24 · latest outcome read · supports before/after example: HRKU- plus the same UUID
- devcenter.heroku.com/changelog-items/3175provider-documentation · last read 2026-09-24 · latest outcome read · supports "increasing from 41 characters to 65 characters"
Provider documented ·
field-g1-uuid-case· current · observed 2026-09-24g1-uuid-case: lowercase 8-4-4-4-12 hex (Uppercase hex is unresolved; no case twin is authored.)
- devcenter.heroku.com/changelog-items/2842provider-documentation · last read 2026-09-24 · latest outcome read · supports g1-uuid-case: lowercase 8-4-4-4-12 hex
Unresolved ·
field-g0-bare-uuid-generation· current · observed 2026-09-24g0-bare-uuid-generation: bare UUID granted before 2024-04-01, valid until regenerated (Measured by the separate context-gated heroku-api-key-legacy contract (owned by #207); recorded here only as this credential's oldest generation.)
- devcenter.heroku.com/changelog-items/2842provider-documentation · last read 2026-09-24 · latest outcome read · supports g0-bare-uuid-generation: bare UUID granted before 2024-04-01, valid until regenerated
Unresolved ·
field-forty-hex-netrc-example· current · observed 2026-09-24forty-hex-netrc-example: a 40-character lowercase hex token in the authentication article's .netrc example (Undated, probably stale; neither a positive nor a control here, since silence on it would turn a hypothesis into a negative expectation.)
- devcenter.heroku.com/articles/authenticationprovider-documentation · last read 2026-09-24 · latest outcome read · supports forty-hex-netrc-example: a 40-character lowercase hex token in the authentication article's .netrc example
Provider documented ·
dossier-research· current · observed 2026-09-24Legacy dossier research (verdict ready, tier T1) cited 3 sources; the dossier does not attribute sources to individual properties.
- devcenter.heroku.com/changelog-items/2842provider-documentation · last read 2026-09-24 · latest outcome read · supports Cited by the legacy dossier research for this family
- devcenter.heroku.com/articles/oauthprovider-documentation · last read 2026-09-24 · latest outcome read · supports Cited by the legacy dossier research for this family
- devcenter.heroku.com/changelog-items/3175provider-documentation · last read 2026-09-24 · latest outcome read · supports Cited by the legacy dossier research for this family
Provider documented ·
taxonomy-sources· current · observed 2026-09-24The legacy taxonomy lists 3 sources for this family. The taxonomy records no date; the dossier researchedAt is used as the observed-at date.
- devcenter.heroku.com/changelog-items/2842provider-documentation · last read 2026-09-24 · latest outcome read · supports Listed as a source for this family in the legacy taxonomy
- devcenter.heroku.com/articles/oauthprovider-documentation · last read 2026-09-24 · latest outcome read · supports Listed as a source for this family in the legacy taxonomy
- devcenter.heroku.com/changelog-items/3175provider-documentation · last read 2026-09-24 · latest outcome read · supports Listed as a source for this family in the legacy taxonomy
Open questions
No open question is recorded for this revision.
Benchmark dossier notes
- Shape
- two documented prefixed generations.
HRKU-plus a UUID (41 characters), granted 2024-04-01 to 2025-04-22, andHRKU-plus 60 characters of[A-Za-z0-9_-](65 characters), granted from 2025-04-23. Every 65-character example startsAAafter the prefix. Both older generations stay valid until regenerated. - Basis
- T1 for the prefix and both lengths (changelog 2842, 3175 and 3176, the OAuth article). The
AAstart is example-observed; gitleaks and trufflehog pin it, osv-scalibr does not, and a trufflehog issue disputes it (a contributor's fresh tokens all matchedAA). The OAuth article's own response examples still show the 41-character form while its prose says 65. Changelog 3176 mentions "additional security checks", which may mean an internal structure or checksum; nothing documents it. - Issuance
heroku authorizations:create(non-expiring by default), Dashboard, or the OAuth flows. Not attempted. Revocable from the Dashboard.- Contract in core
- detector-families.md (
heroku_api_key; see itsHRKU-rows).
In this benchmark
- Fixtures
- 29
- Left readable
- 0
- Redacted too much
- 0
- False alarms
- 0
29 fixtures: 12 expect a redaction, 17 must stay quiet. See every row
| Evidence level | Fixtures | Left readable | Too much | False alarms |
|---|---|---|---|---|
| T1Provider-documented | 12 | 0 | 0 | 0 |
| T2Tool-corroborated | 12 | 0 | 0 | 0 |
| T3Project policy | 5 | 0 | 0 | 0 |
Every scanner on the same fixtures
In run order. Counts are what each scanner recorded on this family's fixtures, whichever rules it has; a scanner with no rule for the family has nothing to report on it.
| Scanner | Fixtures | Left readable | Too much | False alarms |
|---|---|---|---|---|
| flare-redactRuntime library · 1.6.1 · Published npm package · secrets-only (pii, generic_assignment disabled) · JavaScript engineNo rule maps to it | 29 | 11 | 0 | 0 |
| gitleaksRepository scanner · 8.30.1 · Directory scan · default rules1 rule targets it | 29 | 1 | 0 | 0 |
| redact-secretProduct measured here · 0.1.0-beta.14 · Published npm package · default detectors1 detector mapped | 29 | 0 | 0 | 0 |
| trufflehogRepository scanner · 3.97.4 · Filesystem scan · verification disabled1 rule targets it | 29 | 2 | 0 | 1 |
Benchmark dossier questions
- Open caveat
- The HRKU- prefix and the 41 and 65 character lengths are provider-stated; the AA start and the body alphabet of the 65-character form are example- and scanner-derived.
Looks like it, but isn't
- Collisions
- the bare-UUID legacy token, the OAuth refresh token and client secret (also bare UUIDs), and app, release, request and authorization ids (public UUIDs printed beside the token in CLI output). An undated 40-hex token in the authentication article may be a stale example.
Scanner rules for this family
| Scanner | Rule | What the rule matches |
|---|---|---|
| gitleaks · rules 8.30.1 | heroku-api-key-v2 | HRKU-AA + 58 characters |
| trufflehog · rules 3.97.4 | heroku/v2 | HRKU-AA + 58 characters |
No rule maps to this family in flare-redact, openredaction.
Fixtures in this family
| Fixture | Kind and evidence | redact-secret |
|---|---|---|
heroku-api-key-authorization-ids-public-idheroku · public-identifier | Must not flagT2 · Tool-corroborated | Quiet |
heroku-api-key-authorizations-create-g1heroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-compose-envheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-env-g1heroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-github-actions-deployheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-netrc-g2heroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-prefixed-shape-bareheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-prefixed-shape-quotedheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-prefixed-shape-unicode-crlfheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-python-heroku3-clientheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-shell-export-api-keyheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-terraform-providerheroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-authorizations-create-g1-separator-twinheroku · boundary-violation | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-bearer-header-g2heroku · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
heroku-api-key-bearer-header-g2-prefix-case-twinheroku · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-env-g1-length-twinheroku · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-generation-note-proseheroku · prose-mention | Must not flagT3 · Project policy | Quiet |
heroku-api-key-label-proseheroku · benign-lookalike | Must not flagT3 · Project policy | Quiet |
heroku-api-key-maskheroku · benign-lookalike | Must not flagT3 · Project policy | Quiet |
heroku-api-key-netrc-template-placeholderheroku · documentation-placeholder | Must not flagT3 · Project policy | Quiet |
heroku-api-key-prefix-onlyheroku · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
heroku-api-key-prefixed-shape-bare-twinheroku · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-prefixed-shape-prefix-bare-twinheroku · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-prefixed-shape-prefix-quoted-twinheroku · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-prefixed-shape-prefix-unicode-crlf-twinheroku · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-prefixed-shape-quoted-twinheroku · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-prefixed-shape-unicode-crlf-twinheroku · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
heroku-api-key-referenceheroku · benign-lookalike | Must not flagT3 · Project policy | Quiet |
heroku-api-key-short-bodyheroku · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
Sources
Documentation and code
- devcenter.heroku.com/articles/oauth
- devcenter.heroku.com/changelog-items/2842
- devcenter.heroku.com/changelog-items/3175
Research log
- redact-secret/redact-secret-benchmarks#235Research issue