Gå til hovedinnhold

Skanning etter secrets

fremforge ser etter committet legitimasjon med gitleaks tre steder:

HvorHva den gjørKan den slås av?
Push-beskyttelseEn pre-receive-hook skanner hver push og avviser den blanktNei
Sjekk på pull requestsfremforge/secret-scan feiler en pull request som legger til en secret, også i arkiver og Git LFS-filerJa, per organisasjon
HistorikkfeiingÉn gang i uken leser gitleaks git hele historikken til hvert repository og lister det som allerede er committetNei

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ørRegel-IDHva den finner
Hetzner Cloudhetzner-cloud-api-tokenEt API-token under et HCLOUD_- eller HETZNER_-navn, inkludert TF_VAR_hcloud_token
Scalewayscaleway-secret-keyEn hemmelig nøkkel under et SCW_- eller SCALEWAY_-navn
Scalewayscaleway-key-pairEn tilgangsnøkkel fulgt av sin secret_key, som i ~/.config/scw/config.yaml
OVHcloudovh-application-secretOVH_APPLICATION_SECRET, OVH_CONSUMER_KEY eller OVH_CLIENT_SECRET
OVHcloudovh-conf-application-secretapplication_secret, consumer_key eller client_secret i en ovh.conf-fil
IONOS Cloudionos-cloud-tokenEt token under et IONOS_-navn
T Cloud / Open Telekom Cloudotc-secret-access-keyEn 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 Cloudotc-terraform-provider-secret-keysecret_key skrevet direkte i en opentelekomcloud-providerblokk
T Cloud / Open Telekom Cloudotc-credentials-csvcredentials.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ørRegel-IDHva den finnerVed push
Supabasesupabase-access-tokenEt personlig tilgangstoken, klassisk eller avgrenset, eller et OAuth-tilgangstoken: sbp_, sbp_oauth_ eller sbp_v0_ fulgt av 40 heksadesimale tegnBlokkerer
Supabasesupabase-secret-keyEn 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 CLIBlokkerer
Lovablelovable-api-keyEn API-nøkkel for et arbeidsområde (lov_…)Blokkerer
Pydanticpydantic-logfire-tokenEt skrivetoken eller en API-nøkkel for Logfire, eller en nøkkel for Pydantic AI Gateway (pylf_v…)Blokkerer
Cloudsmithcloudsmith-api-keyEn API-nøkkel: 40 heksadesimale tegn under et Cloudsmith-navn som CLOUDSMITH_API_KEYBare 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:

  1. Et nøkkelordfilter beholder bare linjene som nevner et passord eller har user:password@ i en URL, omtrent 1 % av linjene.
  2. 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.

FilerPresisjonGjenfinning
Kode (verdier i anførselstegn)0,940,98
Konfigurasjon0,960,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).

FeltPåkrevdHva det gjør
namejaVises på hvert funn. Opptil 80 tegn.
regexjaRE2-syntaks, opptil 300 tegn.
keywordsneiOpptil 10. Mønsteret kjører bare på innhold som inneholder ett av dem, noe som holder pushene raske.
entropynei0 til 8. Treff med mindre tilfeldighet enn dette, for eksempel plassholdere, rapporteres ikke.
allowlist_pathsneiOpptil 20 sti-glober (*, **, ?) der mønsteret ikke rapporteres. En glob treffer på alle katalognivåer.
repositoryneiEtt repository i organisasjonen, angitt med navn. Utelat det for alle repositoryer.
repository_idneiDet samme, angitt med repository-ID. Oppgi repository eller repository_id, ikke begge.
sampleneiEt 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ørRegler som sjekkesHvor sjekken gårForespørselenDrives fraStandard
fremshAPI-tokener for frem.sh (ffp_)Inne i frem.sh. Ingen eksternt kallTokenets hash mot frem.sh’ tokenlager—På
githubGitHub-tokenerapi.github.comGET /rate_limitUS-operatedAv
gitlabPersonlige tilgangstokener for GitLab.com (et token fra en selvadministrert server gir Unknown)gitlab.comGET /api/v4/personal_access_tokens/selfUS-operatedAv
awsAWS-tilgangsnøklersts.amazonaws.comGetCallerIdentity, som ikke krever noen tillatelseUS-operatedAv
slackSlack-tokenerslack.comPOST /api/auth.test, uten bodyUS-operatedAv
stripeStripe API-nøklerapi.stripe.comGET /v1/balanceUS-operatedAv
hetznerHetzner Cloud API-tokenerapi.hetzner.cloudGET /v1/locationsEU-operatedAv
scalewayHemmelige nøkler for Scalewayapi.scaleway.comGET /account/v3/projects?page_size=1EU-operatedAv
ionosIONOS Cloud API-tokenerapi.ionos.comGET /cloudapi/v6/EU-operatedAv
npmnpm-tilgangstokenerregistry.npmjs.orgGET /-/whoamiUS-operatedAv
openaiOpenAI API-nøklerapi.openai.comGET /v1/modelsUS-operatedAv
anthropicAnthropic API-nøkler (ikke Admin API-nøkler)api.anthropic.comGET /v1/modelsUS-operatedAv
huggingfaceHugging Face-tilgangstokener (ikke eldre api_org_-tokener)huggingface.coGET /api/whoami-v2US-operatedAv
digitaloceanDigitalOcean-tokenerapi.digitalocean.comGET /v2/accountUS-operatedAv
sendgridSendGrid API-nøklerapi.sendgrid.com, deretter api.eu.sendgrid.com, til én svarerGET /v3/scopesUS-operatedAv
mailgunPrivate API-nøkler for Mailgunapi.mailgun.net, deretter api.eu.mailgun.net, til én svarerGET /v3/domainsUS-operatedAv
datadogDatadog API-nøklerDatadogs 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.comGET /api/v1/validateUS-operatedAv
azuredevopsPersonlige tilgangstokener for Azure DevOps. Bare Active eller Unknownapp.vssps.visualstudio.comGET /_apis/profile/profiles/meUS-operatedAv
ovhOVHcloud API-legitimasjon. Bare Active eller Unknowneu.api.ovh.comGET /1.0/auth/currentCredential, signertEU-operatedAv
adafruitAdafruit IO-nøklerio.adafruit.comGET /api/v2/userUS-operatedAv
airtablePersonlige tilgangstokener for Airtableapi.airtable.comGET /v0/meta/whoamiUS-operatedAv
asanaPersonlige tilgangstokener for Asanaapp.asana.comGET /api/1.0/users/meUS-operatedAv
dopplerPersonlige tokener for Dopplerapi.doppler.comGET /v3/meUS-operatedAv
dropboxDropbox-tilgangstokenerapi.dropboxapi.comPOST /2/users/get_current_account, som leser kontoenUS-operatedAv
easypostEasyPost API-nøklerapi.easypost.comGET /v2/addresses?page_size=1US-operatedAv
fastlyFastly API-tokenerapi.fastly.comGET /tokens/selfUS-operatedAv
herokuHeroku API-nøklerapi.heroku.comGET /accountUS-operatedAv
intercomIntercom-tilgangstokenerapi.intercom.io, deretter api.eu.intercom.io, deretter api.au.intercom.io, til én svarerGET /meUS-operatedAv
lobLob API-nøklerapi.lob.comGET /v1/addresses?limit=1US-operatedAv
notionIntegrasjonstokener for Notionapi.notion.comGET /v1/users/meUS-operatedAv
postmanPostman API-nøklerapi.getpostman.com, deretter api.eu.postman.com, til én svarerGET /meUS-operatedAv
readmeReadMe API-nøklerdash.readme.comGET /api/v1US-operatedAv
rubygemsRubyGems API-nøklerrubygems.orgGET /api/v1/gems.jsonUS-operatedAv
shippoShippo API-tokenerapi.goshippo.comGET /addresses/?results=1US-operatedAv
squareSquare-tilgangstokenerconnect.squareup.com, deretter connect.squareupsandbox.com, til én svarerGET /v2/merchants/meUS-operatedAv
brevoBrevo (Sendinblue) API-nøklerapi.brevo.comGET /v3/accountEU-operatedAv
gocardlessGoCardless-tilgangstokener (live)api.gocardless.comGET /creditors?limit=1UK-operatedAv
duffelDuffel-tilgangstokenerapi.duffel.comGET /air/airlines?limit=1UK-operatedAv
cohereCohere API-nøklerapi.cohere.comPOST /v1/check-api-key, Coheres egen nøkkelsjekkCanada-operatedAv
hcpterraformHCP Terraform API-tokener. Bare Active eller Unknownapp.terraform.io, deretter app.eu.terraform.io, til én svarerGET /api/v2/account/detailsUS-operatedAv
pulumiPulumi-tilgangstokener. Bare Active eller Unknownapi.pulumi.comGET /api/userUS-operatedAv
sentrySentry-tokener for brukerautentisering. Bare Active eller Unknownsentry.ioGET /api/0/US-operatedAv
messagebirdMessageBird-tilgangsnøkler. Bare Active eller Unknownrest.messagebird.comGET /balanceEU-operatedAv
typeformPersonlige tilgangstokener for Typeform. Bare Active eller Unknownapi.typeform.com, deretter api.eu.typeform.com, til én svarerGET /meEU-operatedAv

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_limit

Kommandoen 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:

SignalVirkning
Nøyaktig den linjen finnes fortsatt i standardbranchens nåværende kodeSannsynligvis aktiv
Push-beskyttelsen blokkerte samme type secret i dette repositoryet de siste 90 dageneSannsynligvis aktiv
Linjen ble endret eller fjernet senere på standardbranchenMuligens aktiv: å fjerne den tilbakekalte den ikke
Commiten finnes bare på en annen branch enn standardbranchenMuligens aktiv
Committet de siste 90 dageneHever anslaget
Committet for mer enn to år siden, og ikke i den nåværende kodenMindre 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.

Se også