Skanning etter secrets
fremforge ser etter committet legitimasjon med gitleaks tre steder:
| Hvor | Hva den gjør | Kan den slås av? |
|---|---|---|
| Push-beskyttelse | En pre-receive-hook skanner hver push og avviser den blankt | Nei |
| Sjekk på pull requests | fremforge/secret-scan feiler en pull request som legger til en secret, også i arkiver og Git LFS-filer | Ja, per organisasjon |
| Historikkfeiing | Én gang i uken leser gitleaks git hele historikken til hvert repository og lister det som allerede er committet | Nei |
Funn fra alle tre listes under Sikkerhet › Funn › Skanning etter secrets (/<org>/_admin/security/findings/secrets) og på GET /_app/api/v1/orgs/{org}/code-security/secrets/findings.
En secret som allerede ligger på branchen som pull requesten merges inn i, får ikke sjekken til å feile; se Sjekker på pull requests: bare nye funn blokkerer. Den listes fortsatt, og den ukentlige feiingen og push-beskyttelsen er uendret.
Europeiske skyleverandører
gitleaks’ egne regler dekker flere hundre formater for legitimasjon, men ingen fra de europeiske skyleverandørene. fremforge legger til regler for dem, og de kjører på alle de tre stedene ovenfor:
| Leverandør | Regel-ID | Hva den finner |
|---|---|---|
| Hetzner Cloud | hetzner-cloud-api-token | Et API-token under et HCLOUD_- eller HETZNER_-navn, inkludert TF_VAR_hcloud_token |
| Scaleway | scaleway-secret-key | En hemmelig nøkkel under et SCW_- eller SCALEWAY_-navn |
| Scaleway | scaleway-key-pair | En tilgangsnøkkel fulgt av sin secret_key, som i ~/.config/scw/config.yaml |
| OVHcloud | ovh-application-secret | OVH_APPLICATION_SECRET, OVH_CONSUMER_KEY eller OVH_CLIENT_SECRET |
| OVHcloud | ovh-conf-application-secret | application_secret, consumer_key eller client_secret i en ovh.conf-fil |
| IONOS Cloud | ionos-cloud-token | Et token under et IONOS_-navn |
| T Cloud / Open Telekom Cloud | otc-secret-access-key | En hemmelig tilgangsnøkkel under et navn for hemmelig nøkkel med OTC_, OS_, HW_ eller OBS_, eller et *_SK-navn som inneholder ett av dem |
| T Cloud / Open Telekom Cloud | otc-terraform-provider-secret-key | secret_key skrevet direkte i en opentelekomcloud-providerblokk |
| T Cloud / Open Telekom Cloud | otc-credentials-csv | credentials.csv som konsollen laster ned når du oppretter en tilgangsnøkkel |
Disse tokenene har ikke noe fast prefiks, så en regel treffer bare der leverandørens navn eller filformat sier hva verdien er. En naken streng på 64 tegn eller en UUID andre steder rapporteres ikke. Plassholdere (xxxx…, null-UUID-en) og variabelreferanser (${HCLOUD_TOKEN}) ignoreres. For legitimasjon som disse reglene ikke dekker, legger du til et egendefinert mønster.
Flere detektorer
fremforge legger også til regler for denne legitimasjonen, i tillegg til gitleaks’ egne:
| Leverandør | Regel-ID | Hva den finner | Ved push |
|---|---|---|---|
| Supabase | supabase-access-token | Et personlig tilgangstoken, klassisk eller avgrenset, eller et OAuth-tilgangstoken: sbp_, sbp_oauth_ eller sbp_v0_ fulgt av 40 heksadesimale tegn | Blokkerer |
| Supabase | supabase-secret-key | En hemmelig prosjektnøkkel (sb_secret_…), som omgår Row Level Security. Publiserbare nøkler (sb_publishable_…) er ment for nettlesere og rapporteres ikke, og det gjør heller ikke den publiserte lokale standardnøkkelen til Supabase CLI | Blokkerer |
| Lovable | lovable-api-key | En API-nøkkel for et arbeidsområde (lov_…) | Blokkerer |
| Pydantic | pydantic-logfire-token | Et skrivetoken eller en API-nøkkel for Logfire, eller en nøkkel for Pydantic AI Gateway (pylf_v…) | Blokkerer |
| Cloudsmith | cloudsmith-api-key | En API-nøkkel: 40 heksadesimale tegn under et Cloudsmith-navn som CLOUDSMITH_API_KEY | Bare rapportert |
Hver regel treffer tokenets eget faste prefiks eller format, med grenser for lengde og entropi, så den blokkerer ved push som enhver annen regel, og veiene for overstyring og omgåelse gjelder for den. En Cloudsmith-nøkkel har ikke noe prefiks, så regelen for den blir bare rapportert. En Cloudsmith-nøkkel som er tilordnet et navn som CLOUDSMITH_API_KEY, blir som regel blokkert likevel, av gitleaks’ generiske regel for API-nøkler.
Dette er bare deteksjonsregler. fremforge tilbyr ingen gyldighetssjekk for dem.
Passord i konfigurasjonsfiler
fremforge-password-config finner et passord som er skrevet rett inn i en konfigurasjons- eller skriptfil, for eksempel DB_PASSWORD=… i en .env-fil, password: … i YAML, spring.datasource.password=… eller ENV REDIS_PASS=… i en Dockerfile. Den leser .env-filer, YAML, .properties, .ini, .conf, .cfg, .toml, skall-, PowerShell- og batch-skript, Dockerfiler og compose-filer. Den ser etter en nøkkel som er oppkalt etter et passord (password, passwd, passphrase, pwd, pass), og som har en naken verdi som avslutter linjen. Den utelater:
- referanser til en annen verdi (
${DB_PASSWORD},%(password)s,{{ … }}); - plassholdere (
changeme,example,xxx); - oversettelseskataloger;
- innstillinger som navngir en hash eller en algoritme (
root_password_sha2,password.encoding.alg).
Det er en heuristikk, ikke et tokenformat. Vi målte den på CredData, et offentlig merket datasett med legitimasjon i repositoryer med åpen kildekode, mot gitleaks’ generiske regel for API-nøkler på de samme filene. Den var mer presis og fant flere av de ekte passordene, på data som var holdt utenfor justeringen av den (presisjon 0,97 mot 0,95, gjenfinning 8 % mot 5 % av alle merkede passord). Den blir bare rapportert. Den leser ikke kildekode, og en verdi i anførselstegn i YAML (password: "…") dekkes ikke: de formene ble også målt og slo ikke den generiske regelen.
Passord funnet av en klassifikator (fremforges egne organisasjoner)
Et andre trinn leser kode- og konfigurasjonsfiler etter hardkodede passord som ikke har noe tokenformat, for eksempel db_password = "…" i Python eller password: "…" i YAML. Det kjører i dag bare på fremforges egne organisasjoner. Det er ennå ikke tilgjengelig for kundeorganisasjoner; det er en egen beslutning etter to uker med data om falske positiver.
Det virker i to steg, bak reglene ovenfor, i sjekken på pull requests:
- Et nøkkelordfilter beholder bare linjene som nevner et passord eller har
user:password@i en URL, omtrent 1 % av linjene. - En maskinlæringsklassifikator gir hver av disse linjene en score. Det er modellen fra CredSweeper (Samsung, MIT-lisens), trent på nytt av fremforge. Den kjører inne i skanneren uten nettverkstilgang, og ingen kode eller verdi forlater den.
Et funn har regel-ID-en fremforge-password-ml. Et funn i en teststi (test/, __tests__/, *.test.ts, test_*.py, *_test.go og lignende) beholdes med regel-ID-en fremforge-password-ml-test-path og merkes som sannsynligvis testdata. Begge blir bare rapportert.
Det utelater:
- dokumentasjon, datafiler og alt som ikke er kode eller konfigurasjon;
- oversettelseskataloger;
- konstanter som inneholder et regulært uttrykk om passord, for eksempel
PASSWORD_RE; - linjer som allerede er rapportert av en annen regel.
Hvis klassifikatoren ikke kan kjøre eller bruker mer enn 120 sekunder, rapporterer sjekken funnene fra de andre reglene som vanlig.
Slik ble det målt. Vi trente modellen på nytt på CredDatas utviklingsrepositoryer, med bare dem som har en tillatende lisens, og målte den én gang på repositoryer som var holdt utenfor treningen. Terskelen ble fastsatt før den målingen ble tatt.
| Filer | Presisjon | Gjenfinning |
|---|---|---|
| Kode (verdier i anførselstegn) | 0,94 | 0,98 |
| Konfigurasjon | 0,96 | 0,99 |
Passord i URL-er og i andre filer nådde ikke 0,9 i presisjon og rapporteres ikke. Treningsrepositoryene og lisensene deres er listet i skannerens NOTICE-training-data.md.
Regler som bare rapporteres
cloudsmith-api-key, fremforge-password-config, fremforge-password-ml og fremforge-password-ml-test-path blir bare rapportert. Funnene deres listes under Sikkerhet › Funn › Skanning etter secrets, og de to gitleaks-reglene også i historikkfeiingen (klassifikatoren kjører bare i sjekken på pull requests). I en pull request vises de i fremforge/secret-scan som advisory (not blocking): de feiler aldri sjekken og blokkerer aldri en push. Alle andre regler blokkerer.
Innstillingen
Blokker pull requests som legger til en secret avgjør om sjekken på pull requests kjører. Inntil en organisasjon lagrer et valg, kjører sjekken og blokkerer. Når den er slått av, kjører ikke sjekken, og statusen dens fjernes fra branchbeskyttelsen; push-beskyttelsen og den ukentlige feiingen fortsetter å kjøre. Sett den under Sikkerhet › Funn › Skanning etter secrets eller med PUT /_app/api/v1/orgs/{org}/code-security/secrets/settings og {"enabled": true} (policy:write).
Egendefinerte mønstre
Organisasjonen din kan legge til sine egne formater for secrets: en tokenform som bare du utsteder, et internt nøkkelprefiks, en partners legitimasjon. Hvert mønster blir en ekstra gitleaks-regel på alle de tre stedene ovenfor, så et treff blokkeres ved push, feiler sjekken på pull requests og blir funnet i historikken. Et funn fra et egendefinert mønster har regel-ID-en custom-<name> og viser mønsterets navn.
Legg dem til under Sikkerhet › Policyer › Push-beskyttelse › Egendefinerte mønstre for secrets, eller med POST /_app/api/v1/orgs/{org}/code-security/secrets/custom-patterns (policy:write; GET lister dem, PUT og DELETE på /custom-patterns/{id} endrer og fjerner ett).
| Felt | Påkrevd | Hva det gjør |
|---|---|---|
name | ja | Vises på hvert funn. Opptil 80 tegn. |
regex | ja | RE2-syntaks, opptil 300 tegn. |
keywords | nei | Opptil 10. Mønsteret kjører bare på innhold som inneholder ett av dem, noe som holder pushene raske. |
entropy | nei | 0 til 8. Treff med mindre tilfeldighet enn dette, for eksempel plassholdere, rapporteres ikke. |
allowlist_paths | nei | Opptil 20 sti-glober (*, **, ?) der mønsteret ikke rapporteres. En glob treffer på alle katalognivåer. |
repository | nei | Ett repository i organisasjonen, angitt med navn. Utelat det for alle repositoryer. |
repository_id | nei | Det samme, angitt med repository-ID. Oppgi repository eller repository_id, ikke begge. |
sample | nei | Et eksempel som mønsteret må treffe. Sjekkes når du lagrer, lagres aldri. |
Send "dry_run": true for å validere uten å lagre.
Ett repository eller alle. Et mønster uten repository gjelder for alle repositoryer i organisasjonen. Et mønster med ett gjelder bare for det repositoryet, på alle tre steder, sammen med dem som gjelder for hele organisasjonen. I konsollen velger du repositoryet fra listen, eller Alle repositoryer. Mønsteret er knyttet til selve repositoryet, ikke til navnet: gir du repositoryet nytt navn, beholder det mønsteret. Et repository som slettes og senere opprettes igjen med samme navn, er et nytt repository og arver det ikke. Et mønster hvis repository er slettet eller flyttet til en annen organisasjon, gjelder ingen steder og vises som det til du endrer eller sletter det. Svarene inneholder både repository_id og repository, repositoryets nåværende navn.
# Validate only
curl -sS -X POST "https://frem.sh/_app/api/v1/orgs/$ORG/code-security/secrets/custom-patterns" \
-H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
-d '{"name": "Acme deploy key", "regex": "acme_live_[A-Za-z0-9]{24}", "sample": "KEY=acme_live_abcdefghijklmnopqrstuvwx", "dry_run": true}'
# {"valid": true, "rule_id": "custom-acme-deploy-key"}
# Create (201)
curl -sS -X POST "https://frem.sh/_app/api/v1/orgs/$ORG/code-security/secrets/custom-patterns" \
-H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
-d '{"name": "Acme deploy key", "regex": "acme_live_[A-Za-z0-9]{24}", "keywords": ["acme_live_"], "allowlist_paths": ["test/fixtures/**"]}'
# List
curl -sS "https://frem.sh/_app/api/v1/orgs/$ORG/code-security/secrets/custom-patterns" \
-H "Authorization: Bearer $FREMFORGE_TOKEN"
# Replace (the whole pattern) and delete
curl -sS -X PUT "https://frem.sh/_app/api/v1/orgs/$ORG/code-security/secrets/custom-patterns/$ID" \
-H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
-d '{"name": "Acme deploy key", "regex": "acme_live_[A-Za-z0-9]{32}"}'
curl -sS -X DELETE "https://frem.sh/_app/api/v1/orgs/$ORG/code-security/secrets/custom-patterns/$ID" \
-H "Authorization: Bearer $FREMFORGE_TOKEN"Et avvist mønster svarer 400 med en problem+json-body der type navngir årsaken: invalid-repository, invalid-regex, regex-too-complex, regex-matches-empty, regex-too-broad, sample-not-matched, invalid-name, invalid-keywords, invalid-entropy eller invalid-allowlist-paths. Et andre mønster med samme navn svarer 409 duplicate-name, et mønster nummer 101 too-many-patterns, og nummer 21 uten nøkkelord too-many-without-keywords.
Med Terraform/OpenTofu-provideren:
resource "fremforge_secret_custom_pattern" "acme_deploy_key" {
org = "acme"
name = "Acme deploy key"
regex = "acme_live_[A-Za-z0-9]{24}"
keywords = ["acme_live_"]
allowlist_paths = ["test/fixtures/**"]
# repository = "infra" # one repository only (provider 0.7.0 and later)
}Hvorfor bare RE2. Et mønster kjører inne i push-hooken ved hver push. RE2 har ingen backtracking, så kjøretiden vokser lineært med inndataene, og ingen mønstre kan få en push til å henge. Tilbakereferanser (\1) og lookarounds ((?=, (?!, (?<=) krever backtracking og avvises. Et mønster avvises også når det:
- treffer en tom streng, eller vanlig tekst som
const x = 1;; - gjentas mer enn 256 ganger (
{n,m}), eller nøster grupper mer enn 6 nivåer dypt.
Test et mønster før du lagrer det
Test på repositoryer i skjemaet for å legge til, eller API-et for prøvekjøring, kjører et kandidatmønster over den nyeste commiten på standardbranchen i hvert repository og viser hvor det ville truffet. Ingenting lagres: mønsteret lagres ikke, det opprettes ingen funn, og resultatet beholdes i 24 timer.
Det viser repository, fil, linje, commit og fingeravtrykk for hvert treff, aldri den treffende teksten. Hvert repository telles én gang, i én av tre grupper:
- checked (sjekket);
- could not be checked (kunne ikke sjekkes): kloningen mislyktes, tidsavbrudd, skanningen mislyktes, eller ble ikke nådd innen grensen på 10 minutter;
- skipped (hoppet over): arkivert, et speil, tomt, for stort (over 100 MB, eller en utsjekking over 256 MB), eller over grensen på 200 repositoryer.
Et mønster som er avgrenset til ett repository, testes bare på det repositoryet.
# Start one (202); the body is the same as creating a pattern
curl -sS -X POST "https://frem.sh/_app/api/v1/orgs/$ORG/code-security/secrets/custom-patterns/dry-runs" \
-H "Authorization: Bearer $FREMFORGE_TOKEN" -H 'Content-Type: application/json' \
-d '{"name": "Acme deploy key", "regex": "acme_live_[A-Za-z0-9]{24}", "keywords": ["acme_live_"]}'
# {"id": "…", "status": "queued", …}
# Read it back until status is done (or failed)
curl -sS "https://frem.sh/_app/api/v1/orgs/$ORG/code-security/secrets/custom-patterns/dry-runs/$ID" \
-H "Authorization: Bearer $FREMFORGE_TOKEN"
# {"status": "done", "repositories": {"total": 118, "scanned": 70, "not_checked": 48},
# "matches": [{"repository": "web", "path": "config/partner.txt", "line": 1, "commit": "…", "fingerprint": "…"}], …}Begge krever policy:write, fordi resultatet navngir filer på tvers av alle repositoryer i organisasjonen. Én prøvekjøring per organisasjon kjører om gangen, og en ny kan startes hvert 10. minutt. En kjøring som ingen skanner plukker opp innen 2 minutter, ender som failed med error: expired; start den igjen noen minutter senere. Å starte en registreres i revisjonsloggen som code-security.secret_scan.custom_pattern.dry_run_started. En avvist start svarer med de samme typene som når du oppretter et mønster, eller med dry-run-in-progress (409), dry-run-cooldown (429) eller dry-run-unavailable (503).
Grenser. En organisasjon kan ha opptil 100 mønstre, inkludert dem som er avgrenset til et repository. Høyst 20 av dem kan være uten keywords. Svaret fra listen oppgir begge som limit og limit_without_keywords.
Årsaken er tiden en push tar. Et mønster med nøkkelord kjører bare på innhold som inneholder ett av dem, så det koster nesten ingenting. Et mønster uten nøkkelord kjører på hver del av hver push. Målt med push-hooken vår økte 200 mønstre uten nøkkelord tiden for en push med 100 commits fra omtrent 2 sekunder til 17. Et nøkkelord er som regel secretens faste prefiks.
Når du lagrer eller sletter et mønster, settes en ny skanning av hele historikken til hvert repository i kø, så et nytt mønster også finner det som allerede er committet. Det tar som regel opptil 15 minutter. Endringer registreres i revisjonsloggen som code-security.secret_scan.custom_pattern.created, .updated og .deleted.
Hvis mønstrene ikke kan lastes ved push, for eksempel mens API-et er kortvarig utilgjengelig, skannes pushen likevel med de innebygde reglene, og en linje i revisjonsloggen registrerer at de egendefinerte mønstrene ikke ble brukt. Historikkfeiingen finner deretter det som ble oversett, når det når standardbranchen.
Gyldighetssjekker
En secret som fortsatt virker, haster mer enn en som allerede er rotert. En gyldighetssjekk spør tjenesten som utstedte en oppdaget secret, om den fortsatt er i bruk, og merker funnet Aktiv, Inaktiv eller Ukjent. Aktive funn listes først, i konsollen og i API-et (validity, validity_checked_at).
Hver leverandør er en egen innstilling under Sikkerhet › Policyer › Push-beskyttelse › Gyldighetssjekker, eller PUT /_app/api/v1/orgs/{org}/code-security/secrets/validity-settings/{provider} med {"enabled": true} (policy:write). Før du slår én på, navngir siden verten som sjekken kontakter, og om leverandøren er Driftet i USA, Driftet i EU, Driftet i Storbritannia eller Driftet i Canada. API-et rapporterer det samme som operator_jurisdiction (us, eu, uk, ca, eller null for den interne sjekken). Storbritannia og Canada har begge en beslutning om tilstrekkelig beskyttelsesnivå fra EU; ingen leverandør som drives fra et annet land utenfor EU, tilbys på GET .../validity-settings.
Denne tabellen er listen over leverandører som databehandleravtalen (vedlegg B §B.10) viser til. fremforge tilbyr bare en sjekk for en leverandør i den, hver med én skrivebeskyttet forespørsel til en fast vert, eller, der en leverandør betjener nøklene sine fra regionale verter (SendGrid, Mailgun, Datadog, Intercom, Postman, Square, HCP Terraform, Typeform), til en fast liste over verter som spørres i rekkefølge; du kan ikke legge til en egen URL. En leverandør som legges til senere, starter avslått.
| Leverandør | Regler som sjekkes | Hvor sjekken går | Forespørselen | Drives fra | Standard |
|---|---|---|---|---|---|
fremsh | API-tokener for frem.sh (ffp_) | Inne i frem.sh. Ingen eksternt kall | Tokenets hash mot frem.sh’ tokenlager | — | På |
github | GitHub-tokener | api.github.com | GET /rate_limit | US-operated | Av |
gitlab | Personlige tilgangstokener for GitLab.com (et token fra en selvadministrert server gir Unknown) | gitlab.com | GET /api/v4/personal_access_tokens/self | US-operated | Av |
aws | AWS-tilgangsnøkler | sts.amazonaws.com | GetCallerIdentity, som ikke krever noen tillatelse | US-operated | Av |
slack | Slack-tokener | slack.com | POST /api/auth.test, uten body | US-operated | Av |
stripe | Stripe API-nøkler | api.stripe.com | GET /v1/balance | US-operated | Av |
hetzner | Hetzner Cloud API-tokener | api.hetzner.cloud | GET /v1/locations | EU-operated | Av |
scaleway | Hemmelige nøkler for Scaleway | api.scaleway.com | GET /account/v3/projects?page_size=1 | EU-operated | Av |
ionos | IONOS Cloud API-tokener | api.ionos.com | GET /cloudapi/v6/ | EU-operated | Av |
npm | npm-tilgangstokener | registry.npmjs.org | GET /-/whoami | US-operated | Av |
openai | OpenAI API-nøkler | api.openai.com | GET /v1/models | US-operated | Av |
anthropic | Anthropic API-nøkler (ikke Admin API-nøkler) | api.anthropic.com | GET /v1/models | US-operated | Av |
huggingface | Hugging Face-tilgangstokener (ikke eldre api_org_-tokener) | huggingface.co | GET /api/whoami-v2 | US-operated | Av |
digitalocean | DigitalOcean-tokener | api.digitalocean.com | GET /v2/account | US-operated | Av |
sendgrid | SendGrid API-nøkler | api.sendgrid.com, deretter api.eu.sendgrid.com, til én svarer | GET /v3/scopes | US-operated | Av |
mailgun | Private API-nøkler for Mailgun | api.mailgun.net, deretter api.eu.mailgun.net, til én svarer | GET /v3/domains | US-operated | Av |
datadog | Datadog API-nøkler | Datadogs seks nettsteder i denne rekkefølgen, til ett svarer: api.datadoghq.com, api.datadoghq.eu, api.us3.datadoghq.com, api.us5.datadoghq.com, api.ap1.datadoghq.com, api.ddog-gov.com | GET /api/v1/validate | US-operated | Av |
azuredevops | Personlige tilgangstokener for Azure DevOps. Bare Active eller Unknown | app.vssps.visualstudio.com | GET /_apis/profile/profiles/me | US-operated | Av |
ovh | OVHcloud API-legitimasjon. Bare Active eller Unknown | eu.api.ovh.com | GET /1.0/auth/currentCredential, signert | EU-operated | Av |
adafruit | Adafruit IO-nøkler | io.adafruit.com | GET /api/v2/user | US-operated | Av |
airtable | Personlige tilgangstokener for Airtable | api.airtable.com | GET /v0/meta/whoami | US-operated | Av |
asana | Personlige tilgangstokener for Asana | app.asana.com | GET /api/1.0/users/me | US-operated | Av |
doppler | Personlige tokener for Doppler | api.doppler.com | GET /v3/me | US-operated | Av |
dropbox | Dropbox-tilgangstokener | api.dropboxapi.com | POST /2/users/get_current_account, som leser kontoen | US-operated | Av |
easypost | EasyPost API-nøkler | api.easypost.com | GET /v2/addresses?page_size=1 | US-operated | Av |
fastly | Fastly API-tokener | api.fastly.com | GET /tokens/self | US-operated | Av |
heroku | Heroku API-nøkler | api.heroku.com | GET /account | US-operated | Av |
intercom | Intercom-tilgangstokener | api.intercom.io, deretter api.eu.intercom.io, deretter api.au.intercom.io, til én svarer | GET /me | US-operated | Av |
lob | Lob API-nøkler | api.lob.com | GET /v1/addresses?limit=1 | US-operated | Av |
notion | Integrasjonstokener for Notion | api.notion.com | GET /v1/users/me | US-operated | Av |
postman | Postman API-nøkler | api.getpostman.com, deretter api.eu.postman.com, til én svarer | GET /me | US-operated | Av |
readme | ReadMe API-nøkler | dash.readme.com | GET /api/v1 | US-operated | Av |
rubygems | RubyGems API-nøkler | rubygems.org | GET /api/v1/gems.json | US-operated | Av |
shippo | Shippo API-tokener | api.goshippo.com | GET /addresses/?results=1 | US-operated | Av |
square | Square-tilgangstokener | connect.squareup.com, deretter connect.squareupsandbox.com, til én svarer | GET /v2/merchants/me | US-operated | Av |
brevo | Brevo (Sendinblue) API-nøkler | api.brevo.com | GET /v3/account | EU-operated | Av |
gocardless | GoCardless-tilgangstokener (live) | api.gocardless.com | GET /creditors?limit=1 | UK-operated | Av |
duffel | Duffel-tilgangstokener | api.duffel.com | GET /air/airlines?limit=1 | UK-operated | Av |
cohere | Cohere API-nøkler | api.cohere.com | POST /v1/check-api-key, Coheres egen nøkkelsjekk | Canada-operated | Av |
hcpterraform | HCP Terraform API-tokener. Bare Active eller Unknown | app.terraform.io, deretter app.eu.terraform.io, til én svarer | GET /api/v2/account/details | US-operated | Av |
pulumi | Pulumi-tilgangstokener. Bare Active eller Unknown | api.pulumi.com | GET /api/user | US-operated | Av |
sentry | Sentry-tokener for brukerautentisering. Bare Active eller Unknown | sentry.io | GET /api/0/ | US-operated | Av |
messagebird | MessageBird-tilgangsnøkler. Bare Active eller Unknown | rest.messagebird.com | GET /balance | EU-operated | Av |
typeform | Personlige tilgangstokener for Typeform. Bare Active eller Unknown | api.typeform.com, deretter api.eu.typeform.com, til én svarer | GET /me | EU-operated | Av |
Personlige tilgangstokener for Azure DevOps, Datadog API-nøkler og personlige tilgangstokener for Asana finnes av tre fremforge-regler, azure-devops-pat, datadog-api-key og asana-personal-access-token, som kjører på alle de tre stedene ovenfor.
Noen sjekker kan vise at en secret er i bruk, aldri at den ikke er det. Azure DevOps avviser et gyldig token som er begrenset til én organisasjon eller mangler profil-scopet, så en avvisning der gir Unknown, aldri Inactive. En forespørsel til OVHcloud må signeres med applikasjonsnøkkelen, applikasjons-secreten og forbrukernøkkelen sammen. Sjekken kjører bare når historikkfeiingen finner alle tre i samme fil, for eksempel en ovh.conf, og ethvert annet svar enn suksess gir Unknown. Tokener for HCP Terraform, Pulumi og Sentry kan høre til en selvhostet Terraform Enterprise, Pulumi eller Sentry, som avviser dem på den offentlige tjenesten. MessageBird-nøkler fra den nyere Bird-plattformen kan avvises av MessageBirds opprinnelige API. Et Typeform-token uten konto-scopet kan avvises på samme måte som et dødt. Derfor gir disse fem Active eller Unknown, aldri Inactive.
En secret er inaktiv bare når alle verter sier det. En SendGrid-nøkkel som er låst til EU-regionen, feiler på den globale verten, en Datadog-nøkkel hører til ett av Datadogs nettsteder, og en nøkkel for Intercom, Postman eller Typeform til én av deres regioner; et sandkassetoken for Square feiler i produksjon. Derfor spør sjekken vertene i den viste rekkefølgen og stopper ved den første som svarer at secreten er i bruk. Den gir Inaktiv bare når alle verter avviser den.
Ingen automatisk sjekk: Atlassian, Twilio, Flutterwave, Mailchimp, Telegram, selvadministrert GitLab og T Cloud. Funnene deres har bare Sjekk selv. Et Atlassian-token krever i tillegg nettstedet og kontoens e-postadresse, og en Twilio API-nøkkel krever sin SID. Flutterwave-regelen finner bare testnøkler. En Mailchimp-nøkkel navngir sin egen datasenter-vert, så det finnes ingen fast vert å sjekke. Telegram drives fra utenfor EU, Storbritannia, Canada og USA. En selvadministrert GitLab-server, eller en hvilken som helst annen vert du velger, er et mål som fremforge ikke kontakter på dine vegne. T Cloud er skyen som fremforge selv kjører på, og identitetstjenesten der er bevisst ikke nåbar fra fremforges sjekker. For en T Cloud-nøkkel ber kommandoen OBS om å liste bøttene dine: en nøkkel som ikke er kjent, svarer InvalidAccessKeyId.
En nøkkel som er gyldig, men ikke har lov til å gjøre sjekkens lesing, teller som Active: en Stripe-nøkkel som nektes saldoen, en Scaleway-nøkkel som nektes prosjektene, en Anthropic-nøkkel som avvises med permission_error, en OpenAI-nøkkel som avvises for manglende tillatelser, et Dropbox-token som avvises med missing_scope, eller en nøkkel for Heroku, RubyGems, Square, Asana, GoCardless eller Duffel som avvises med 403. For leverandørene som ble lagt til 2026-10-24, gir bare det nøyaktige svaret hver av dem gir en nøkkel som ikke finnes, Inactive; ethvert annet svar gir Unknown. OpenAIs invalid_api_key er det eneste svaret fra OpenAI som leses som Inactive. Admin API-nøkler for Anthropic og eldre organisasjonstokener for Hugging Face sjekkes ikke, fordi endepunktene ovenfor ikke kan avgjøre om de er i bruk.
Hvordan en sjekk virker, og hva som lagres. Hver sjekk er skrivebeskyttet. Den spør hvem et token tilhører eller om det er gyldig, og endrer aldri noe hos leverandøren. Secreten lagres fortsatt aldri. Mens historikkfeiingen leser et repository, krypterer skanneren hver treffende verdi med en nøkkel som API-et oppretter for akkurat den skanningen. API-et åpner den, kjører sjekken, beholder bare utfallet og tidspunktet for sjekken, og forkaster verdien. Nøkkelen slettes når skanningen er ferdig. Skanneren selv har ingen nettverkstilgang til leverandørene.
Et frem.sh-token sjekkes mot frem.sh’ eget tokenlager, og tilstanden leses direkte: tilbakekaller du tokenet, vises funnet som Inactive med en gang. For de andre leverandørene er tilstanden fra den siste feiingen som leste secreten.
Unknown betyr at leverandøren ikke ga et klart svar, for eksempel et tidsavbrudd eller en ratebegrensning, en AWS-nøkkel der den hemmelige halvdelen ikke ble funnet innen fem linjer fra den, eller en OVHcloud-legitimasjon der de tre delene ikke ble funnet sammen. Unknown vises aldri som Inactive.
Slår du på en leverandør, skannes historikken til hvert repository på nytt, fordi verdien til en funnet secret bare finnes mens feiingen leser den. Slår du den av, slettes leverandørens utfall. Endringer registreres i revisjonsloggen som code-security.secret_scan.validity.updated.
Sjekk selv, og merk det deretter
Du trenger ikke slå på en gyldighetssjekk for å vite om en secret fortsatt virker. For en secret utstedt av en av leverandørene ovenfor, eller av Atlassian, Twilio, Flutterwave, Mailchimp, Telegram, en selvadministrert GitLab-server eller T Cloud, har funnet Check it yourself: leverandørens egen skrivebeskyttede forespørsel som en kommando du kjører i terminalen din, for eksempel for et GitHub-token:
read -rs TOKEN && curl -s -o /dev/null -w '%{http_code}\n' -H "Authorization: Bearer $TOKEN" https://api.github.com/rate_limitKommandoen inneholder aldri secreten. Den venter på at du skriver eller limer den inn, viser den ikke, og holder den utenfor skallhistorikken din. Den går bare til leverandøren, aldri til fremforge. Funnet sier hva kommandoen skriver ut når secreten er i bruk (her 200), og når den ikke er det (401).
Registrer deretter det du fant med Merk som aktiv eller Merk som rotert i funnets meny, eller PUT /_app/api/v1/orgs/{org}/code-security/secrets/findings/{id}/mark med {"mark": "active"}, {"mark": "rotated"} eller {"mark": null} (findings:write). Et funn som er merket aktivt, listes sammen med dem som er i bruk. Hvert sted merkes for seg: en merking hører til ett funn (én fil, linje og commit) og beholdes på tvers av historikkfeiinger, slik en avvisning gjør. Hvis den samme secreten ble funnet i to commits, merker du begge. fremforge lagrer ingenting avledet av secreten som kunne knytte stedene sammen. En merking avviser ikke funnet. Hver merking registreres i revisjonsloggen som code-security.secrets.marked. Findings-API-et returnerer merkingen som mark og kommandoen som self_check.
Roter som standard, og hva du skal rotere først
Behandle hver secret som blir funnet her, som kompromittert, og roter den, med mindre leverandøren eller du har bekreftet at den ikke lenger virker. Å fjerne en secret fra koden tilbakekaller den ikke: den blir liggende i historikken, der alle med lesetilgang kan finne den.
For å hjelpe deg å avgjøre hva du skal rotere først når ingen leverandør har svart, sorteres funnene etter hvor sannsynlig det er at secreten fortsatt er i bruk. Anslaget bruker bare det fremforge allerede vet, aldri selve secreten, og kontakter ingen:
| Signal | Virkning |
|---|---|
| Nøyaktig den linjen finnes fortsatt i standardbranchens nåværende kode | Sannsynligvis aktiv |
| Push-beskyttelsen blokkerte samme type secret i dette repositoryet de siste 90 dagene | Sannsynligvis aktiv |
| Linjen ble endret eller fjernet senere på standardbranchen | Muligens aktiv: å fjerne den tilbakekalte den ikke |
| Commiten finnes bare på en annen branch enn standardbranchen | Muligens aktiv |
| Committet de siste 90 dagene | Hever anslaget |
| Committet for mer enn to år siden, og ikke i den nåværende koden | Mindre sannsynlig aktiv |
Et svar fra leverandøren selv (Aktiv eller Inaktiv) og din egen merking går alltid foran. Anslaget vises, med opptil to av begrunnelsene, på hvert funn som ingen leverandør har svart på og som du ikke har merket. Signalene fra koden registreres av den ukentlige historikkfeiingen, så et funn som ble feid før feiingen som la dem til, viser bare signalet fra push-beskyttelsen til neste feiing. Findings-API-et returnerer det som likely_live (level og reasons), sammen med committed_at. Det er null når en leverandør har svart eller funnet er merket. Det er et anslag, ikke en sjekk: «Less likely live» betyr fortsatt at du skal rotere.
Hva som lagres
Bare et fingeravtrykk av treffet lagres, aldri den treffende teksten. Regelen, stien, linjen og commiten er nok til å åpne filen ved den commiten. En gyldighetssjekk legger til utfallet og tidspunktet. For et frem.sh-token lagres også ID-en til den tilsvarende tokenoppføringen, aldri selve tokenet.
Når en secret blir funnet
Roter legitimasjonen ved kilden først. Å slette linjen gjør ikke lekkasjen ugjort: alle som har historikken, har fortsatt verdien. Fjern den deretter fra koden: Åpne PR med rettelse i funnets Rettelse-kolonne flytter legitimasjon i Go, Python, JavaScript eller TypeScript over i en miljøvariabel, uten AI; se Regelbaserte rettelser. Pull requesten fjerner ikke verdien fra historikken, så rotering kommer først uansett.