redact-secret · Report
API token
pypi- prefixed base64-encoded macaroon.
Research record
2 events in the review history: 1 observed, 1 reviewed. Latest: observed on 2026-09-22 by automation, project maintainer. Project-maintained review is not independent validation. The family record at this release.
Format
What it looks like
- Descriptive pattern
^pypi-[A-Za-z0-9_-]{85,}$
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-21pypi- prefix, base64-serialized PyMacaroon, {85,} length floor: docs.pypi.org's own detection-format page publishes this contract's exact regex, pypi-[A-Za-z0-9-_]{85,}: the pypi- prefix, a "-" separator, a base64 PyMacaroon serialization, an 85-character floor and no ceiling
- docs.pypi.org/api/secrets/provider-documentation · last read 2026-09-22 · latest outcome read · supports docs.pypi.org's own detection-format page publishes this contract's exact regex, pypi-[A-Za-z0-9-_]{85,}: the pypi- prefix, a "-" separator, a base64 PyMacaroon serialization, an 85-character floor and no ceiling
Tool corroborated ·
tool-corroboration· current · observed 2026-09-21Pinned 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/pypi/pypi.goscanner-rule-source · last read 2026-09-21 · latest outcome read · supports trufflehog 3.97.4: pypi/pypi
Unresolved ·
listed-references· current · observed 2026-09-21The legacy contract lists 1 reference without stating which property each supports.
- pypi.org/help/provider-documentation · last read 2026-09-22 · latest outcome read · supports Listed as a reference by the legacy contract · #apitoken
Provider documented ·
dossier-research· current · observed 2026-09-22Legacy dossier research (verdict ready, tier T1) cited 2 sources; the dossier does not attribute sources to individual properties.
- docs.pypi.org/api/secrets/provider-documentation · last read 2026-09-22 · latest outcome read · supports Cited by the legacy dossier research for this family
- pypi.org/help/provider-documentation · last read 2026-09-22 · latest outcome read · supports Cited by the legacy dossier research for this family · #apitoken
Open questions
No open question is recorded for this revision.
Benchmark dossier notes
- Shape
- prefix
pypi-, then a URL-safe base64 string (letters, digits,-,_) of at least 85 characters, with no upper bound because caveats can be added to the macaroon. Real tokens begin with the encoded macaroon header for the locationpypi.org, which both pinned scanners key on. The extra character in trufflehog's pattern implies an identifier of 36 to 39 bytes, consistent with a UUID. - Basis
- T1.
docs.pypi.org/api/secrets(fetched 2026-09-21) publishes the regexpypi-[A-Za-z0-9-_]{85,}and says the body is a PyMacaroon base64 serialization. The PyPI help page confirms thepypi-prefix is part of the password value and that the identifier is meant to be inspectable. Scanner rules are narrower: trufflehog 3.97.4 requires the macaroon header plus 150 to 157 further characters, and gitleaks 8.30.1 requires the header plus 50 to 1000. Neither verifies the signature by default. - Issuance
- not attempted. Benchmarks#104 decided a structurally faithful synthetic token can be built without any PyPI signing key (nil-UUID identifier, a caveat that says it is a fixture, and a hash-filler signature), so no real token is needed for the positives.
- Contract in core
- detector-families.md.
In this benchmark
- Fixtures
- 26
- Left readable
- 0
- Redacted too much
- 0
- False alarms
- 0
26 fixtures: 9 expect a redaction, 17 must stay quiet. See every row
| Evidence level | Fixtures | Left readable | Too much | False alarms |
|---|---|---|---|---|
| T1Provider-documented | 9 | 0 | 0 | 0 |
| T2Tool-corroborated | 13 | 0 | 0 | 0 |
| T3Project policy | 4 | 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 | 26 | 9 | 0 | 0 |
| gitleaksRepository scanner · 8.30.1 · Directory scan · default rules1 rule targets it | 26 | 0 | 0 | 4 |
| redact-secretProduct measured here · 0.1.0-beta.14 · Published npm package · default detectors1 detector mapped | 26 | 0 | 0 | 0 |
| trufflehogRepository scanner · 3.97.4 · Filesystem scan · verification disabled1 rule targets it | 26 | 0 | 0 | 0 |
Looks like it, but isn't
- Collisions
- the identifier inside the macaroon is meant to be readable and is not itself the secret. Twine and pip use the same
pypi-value as a password, so it appears underTWINE_PASSWORD-style names.
Scanner rules for this family
| Scanner | Rule | What the rule matches |
|---|---|---|
| gitleaks · rules 8.30.1 | pypi-upload-token | pypi-AgEIcHlwaS5vcmc + 50-1000 characters |
| openredaction · rules 1.1.5 | PYPI_TOKEN | pypi- + 100 or more characters |
| trufflehog · rules 3.97.4 | pypi | pypi-AgEIcHlwaS5vcmcCJ + 150-157 characters |
No rule maps to this family in flare-redact.
Fixtures in this family
| Fixture | Kind and evidence | redact-secret |
|---|---|---|
pypi-token-gitlab-ci-variablespypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-noxfile-publishpypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-public-idpypi · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
pypi-token-pypircpypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-shape-1-barepypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-shape-1-length-bare-twinpypi · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-length-quoted-twinpypi · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-length-unicode-crlf-twinpypi · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-quotedpypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-shape-1-unicode-crlfpypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-twine-envpypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-twine-upload-flagpypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-uv-publish-tokenpypi · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
pypi-token-encoded-valuepypi · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
pypi-token-label-prosepypi · benign-lookalike | Must not flagT3 · Project policy | Quiet |
pypi-token-maskpypi · benign-lookalike | Must not flagT3 · Project policy | Quiet |
pypi-token-ordinary-prosepypi · benign-lookalike | Must not flagT3 · Project policy | Quiet |
pypi-token-prefix-onlypypi · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
pypi-token-referencepypi · benign-lookalike | Must not flagT3 · Project policy | Quiet |
pypi-token-shape-1-alphabet-bare-twinpypi · wrong-alphabet | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-alphabet-quoted-twinpypi · wrong-alphabet | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-alphabet-unicode-crlf-twinpypi · wrong-alphabet | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-bare-twinpypi · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-quoted-twinpypi · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-shape-1-unicode-crlf-twinpypi · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
pypi-token-short-bodypypi · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
Sources
Documentation and code
- docs.pypi.org/api/secrets/
- pypi.org/help/#apitoken
Research log
- redact-secret/redact-secret-benchmarks#104Research issue
- redact-secret/redact-secret-benchmarks#107Research issue