redact-secret · Report
API key (rubygems_)
rubygems_ + exactly 48 lowercase hex (57 in all); OIDC-exchanged keys share the generator.
Research record
3 events in the review history: 2 observed, 1 reviewed. Latest: observed on 2026-09-29 by automation, project maintainer. Project-maintained review is not independent validation. The family record at this release.
Format
What it looks like
- Descriptive pattern
^rubygems_[0-9a-f]{48}$
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-29rubygems/rubygems.org app/controllers/concerns/api_keyable.rb (d4cfcc9, last changed 2026-03-03): generate_rubygems_key returns "rubygems_#{SecureRandom.hex(24)}"; re-checked 2026-09-29: rubygems_ + exactly 48 lowercase hex (24 random bytes), 57 in all; no checksum
- rubygems/rubygems.org @ d4cfcc961d08cb5f661f2e5dc0081736233b97ec: app/controllers/concerns/api_keyable.rbprovider-documentation · last read 2026-09-29 · latest outcome read · supports rubygems_ + exactly 48 lowercase hex (24 random bytes), 57 in all; no checksum · #L19-L21
Tool corroborated ·
tool-corroboration· current · observed 2026-09-29Pinned 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: rubygems-api-token: \b(rubygems_[a-f0-9]{48}) + a trailing delimiter
- trufflesecurity/trufflehog @ v3.97.4: pkg/detectors/rubygems/rubygems.goscanner-rule-source · last read 2026-09-29 · latest outcome read · supports trufflehog 3.97.4: RubyGems: \b(rubygems_[a-zA0-9]{48})\b (a class typo: a-z, A and 0-9)
Provider documented ·
field-prefix· current · observed 2026-09-29prefix: rubygems_
- rubygems/rubygems.org @ d4cfcc961d08cb5f661f2e5dc0081736233b97ec: app/controllers/concerns/api_keyable.rbprovider-documentation · last read 2026-09-29 · latest outcome read · supports prefix: rubygems_ · #L19-L21
Provider documented ·
field-body· current · observed 2026-09-29body: exactly 48 lowercase hex [0-9a-f] (SecureRandom.hex(24)); 57 in all
- rubygems/rubygems.org @ d4cfcc961d08cb5f661f2e5dc0081736233b97ec: app/controllers/concerns/api_keyable.rbprovider-documentation · last read 2026-09-29 · latest outcome read · supports body: exactly 48 lowercase hex [0-9a-f] (SecureRandom.hex(24)); 57 in all · #L19-L21
Unresolved ·
field-boundary· current · observed 2026-09-29boundary: a key glued to an identifier on either side ([A-Za-z0-9_-]) is not claimed (Handoff boundary decision, not a provider statement.)
- redact-secret/redact-secret @ 4f220ea000b58fa2e0e431ad88dea4eccb393fb0: docs/audits/evidence/1014/rubygems.mdprovider-documentation · last read 2026-09-29 · latest outcome read · supports implementation notes
Provider documented ·
field-transport· current · observed 2026-09-29transport: GEM_HOST_API_KEY; the :rubygems_api_key: line of ~/.gem/credentials; Authorization with the bare key (no scheme)
- redact-secret/redact-secret @ 4f220ea000b58fa2e0e431ad88dea4eccb393fb0: docs/audits/evidence/1014/rubygems.mdprovider-documentation · last read 2026-09-29 · latest outcome read · supports test axes
Provider documented ·
field-metadata-keys· current · observed 2026-09-29metadata-keys: rubygems_version and rubygems_mfa_required are gemspec metadata keys, not credentials (Benign controls: they fail the 48-hex body.)
- redact-secret/redact-secret @ 4f220ea000b58fa2e0e431ad88dea4eccb393fb0: docs/audits/evidence/1014/rubygems.mdprovider-documentation · last read 2026-09-29 · latest outcome read · supports excluded shapes
Tool corroborated ·
field-peer-lag· current · observed 2026-09-29peer-lag: gitleaks 8.30.1 rubygems-api-token is \b(rubygems_[a-f0-9]{48}) followed by a quote, backtick, whitespace, ; or end: it agrees with the grammar and lags only where the key is followed by another byte. trufflehog 3.97.4 RubyGems is \b(rubygems_[a-zA0-9]{48})\b, whose class admits any lowercase letter and A, so it overreaches on a non-hex body. Both labels map to rubygems-api-key
- gitleaks/gitleaks @ v8.30.1: config/gitleaks.tomlscanner-rule-source · last read 2026-10-04 · latest outcome read · supports rubygems-api-token
- trufflesecurity/trufflehog @ v3.97.4: pkg/detectors/rubygems/rubygems.goscanner-rule-source · last read 2026-09-29 · latest outcome read · supports RubyGems
Unresolved ·
listed-references· current · observed 2026-09-29The legacy contract lists 8 references without stating which property each supports.
- redact-secret/redact-secret @ 4f220ea000b58fa2e0e431ad88dea4eccb393fb0: docs/audits/evidence/1014/README.mdprovider-documentation · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract
- github.com/redact-secret/redact-secret/issues/1014issue-or-discussion · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract · #issuecomment-5900447282
- github.com/redact-secret/redact-secret/issues/1014issue-or-discussion · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract
- redact-secret/redact-secret @ 4f220ea000b58fa2e0e431ad88dea4eccb393fb0: docs/audits/evidence/1014/rubygems.mdprovider-documentation · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract
- github.com/redact-secret/redact-secret/issues/860issue-or-discussion · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract · #issuecomment-5852413851
- github.com/redact-secret/redact-secret-benchmarks/issues/528issue-or-discussion · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract
- github.com/redact-secret/redact-secret/issues/1023issue-or-discussion · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract
- rubygems/rubygems.org @ d4cfcc961d08cb5f661f2e5dc0081736233b97ec: app/controllers/concerns/api_keyable.rbprovider-documentation · last read 2026-09-29 · latest outcome read · supports Listed as a reference by the legacy contract · #L19-L21
Provider documented ·
dossier-research· current · observed 2026-09-29Legacy dossier research (verdict ready, tier T1) cited 2 sources; the dossier does not attribute sources to individual properties.
- redact-secret/redact-secret @ 378581770a87751d72e27529796c4f790649fd00: docs/audits/evidence/1014/rubygems.mdproject-research-note · last read 2026-09-29 · latest outcome read · supports Final research evidence recorded by the legacy dossier
- rubygems/rubygems.org @ d4cfcc961d08cb5f661f2e5dc0081736233b97ec: app/controllers/concerns/api_keyable.rbprovider-documentation · last read 2026-09-29 · latest outcome read · supports Cited by the legacy dossier research for this family · #L19-L21
Provider documented ·
taxonomy-sources· current · observed 2026-09-29The legacy taxonomy lists 2 sources for this family. The taxonomy records no date; the dossier researchedAt is used as the observed-at date.
- redact-secret/redact-secret @ 4f220ea000b58fa2e0e431ad88dea4eccb393fb0: docs/audits/evidence/1014/rubygems.mdprovider-documentation · last read 2026-09-29 · latest outcome read · supports Listed as a source for this family in the legacy taxonomy
- rubygems/rubygems.org @ d4cfcc961d08cb5f661f2e5dc0081736233b97ec: app/controllers/concerns/api_keyable.rbprovider-documentation · last read 2026-09-29 · latest outcome read · supports Listed as a source for this family in the legacy taxonomy · #L19-L21
Open questions
No open question is recorded for this revision.
Benchmark dossier notes
- Shape
rubygems_+ exactly 48 lowercase hex (57 in all).- Basis
- T1 under R1:
generate_rubygems_keyreturns"rubygems_#{SecureRandom.hex(24)}". GitHub partner patternrubygems_api_keywith push protection. - Issuance
- not attempted; the grammar is T1 from provider sources, so no key is needed.
- Contract in core
- detector-families.md (row on
main; the Beta.12 detector, redact-secret#1023, merged in redact-secret#1039 and is unreleased).
In this benchmark
- Fixtures
- 39
- Left readable
- 0
- Redacted too much
- 0
- False alarms
- 0
39 fixtures: 16 expect a redaction, 23 must stay quiet. See every row
| Evidence level | Fixtures | Left readable | Too much | False alarms |
|---|---|---|---|---|
| T1Provider-documented | 16 | 0 | 0 | 0 |
| T2Tool-corroborated | 15 | 0 | 0 | 0 |
| T3Project policy | 8 | 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 | 39 | 15 | 1 | 0 |
| gitleaksRepository scanner · 8.30.1 · Directory scan · default rules1 rule targets it | 39 | 0 | 0 | 0 |
| redact-secretProduct measured here · 0.1.0-beta.14 · Published npm package · default detectors1 detector mapped | 39 | 0 | 0 | 0 |
| trufflehogRepository scanner · 3.97.4 · Filesystem scan · verification disabled1 rule targets it | 39 | 0 | 0 | 1 |
Looks like it, but isn't
- Collisions
rubygems_versionandrubygems_mfa_requiredmetadata keys fail the body.
Scanner rules for this family
| Scanner | Rule | What the rule matches |
|---|---|---|
| gitleaks · rules 8.30.1 | rubygems-api-token | rubygems_ + 48 hex |
| trufflehog · rules 3.97.4 | rubygems | rubygems_ + 48 characters |
No rule maps to this family in flare-redact, openredaction.
Fixtures in this family
| Fixture | Kind and evidence | redact-secret |
|---|---|---|
rubygems-api-key-actions-envrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-authorization-no-schemerubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-bare-proserubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-bearer-headerrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-chat-pasterubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-dotenvrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-exportrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-gem-credentials-yamlrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-gem-push-envrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-json-api-keyrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-json-tokenrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-key-shape-barerubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-key-shape-quotedrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-key-shape-unicode-crlfrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-non-hex-letter-twinrubygems · wrong-alphabet | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-sdk-kwargrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-x-api-key-headerrubygems · documented-format-literal | Must redactT1 · Provider-documented | Redacted |
rubygems-api-key-actions-secret-referencerubygems · templated-reference | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-bare-48-hex-encoded-valuerubygems · benign-encoded-value | Must not flagT2 · Tool-corroborated | Quiet |
rubygems-api-key-body-47-twinrubygems · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-body-49-twinrubygems · wrong-length | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-credentials-placeholder-placeholderrubygems · documentation-placeholder | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-ellipsis-placeholderrubygems · documentation-placeholder | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-env-reference-referencerubygems · templated-reference | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-gemspec-metadata-public-idrubygems · public-identifier | Must not flagT2 · Tool-corroborated | Quiet |
rubygems-api-key-hyphen-separator-twinrubygems · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-key-guidance-proserubygems · prose-mention | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-label-proserubygems · benign-lookalike | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-leading-glue-twinrubygems · boundary-violation | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-lockfile-version-public-idrubygems · public-identifier | Must not flagT2 · Tool-corroborated | Quiet |
rubygems-api-key-maskrubygems · benign-lookalike | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-prefix-onlyrubygems · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
rubygems-api-key-referencerubygems · benign-lookalike | Must not flagT3 · Project policy | Quiet |
rubygems-api-key-short-bodyrubygems · benign-lookalike | Must not flagT2 · Tool-corroborated | Quiet |
rubygems-api-key-trailing-letter-twinrubygems · boundary-violation | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-trailing-underscore-twinrubygems · boundary-violation | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-truncated-near-missrubygems · format-near-miss | Must not flagT2 · Tool-corroborated | Quiet |
rubygems-api-key-uppercase-hex-byte-twinrubygems · wrong-alphabet | Must not flagT2 · Tool-corroborated · twin | Quiet |
rubygems-api-key-uppercase-prefix-twinrubygems · prefix-near-miss | Must not flagT2 · Tool-corroborated · twin | Quiet |
Sources
Documentation and code
- github.com/rubygems/rubygems.org/blob/d4cfcc961d08cb5f661f2e5dc0081736233b97ec/app/controllers/concerns/api_keyable.rb#L19-L21
- github.com/redact-secret/redact-secret/blob/4f220ea000b58fa2e0e431ad88dea4eccb393fb0/docs/audits/evidence/1014/rubygems.md
Research log
- redact-secret/redact-secret#1014Research issue
- redact-secret/redact-secret#1023Research issue
- redact-secret/redact-secret#1039Research issue
- redact-secret/redact-secret-benchmarks#528Research issue
- Final evidence, pinned to a commit/redact-secret/redact-secret/blob/378581770a87751d72e27529796c4f790649fd00/docs/audits/evidence/1014/rubygems.md