Deleting the line does not delete the key.

A committed credential is in the history from the moment it lands. The commit that removes it changes nothing about who can read it, so the only real remediation is rotation.

AWS access key IDGitHub tokenGitHub fine-grained PATGoogle API keyGoogle OAuth access tokenSlack tokenSlack webhook URLStripe secret keySendGrid API keyTwilio API keyTwilio account SIDPrivate key committed to source
01 · Where they hide

Not only in application code.

BUILD AND CI FILES

Pipeline definitions, compose files and Dockerfiles hold credentials as often as source does, and they are rarely reviewed as carefully.

EVERY LANGUAGE, NOT THE PARSED ONES

The scan reads files directly rather than only the code it could parse into entities. That distinction is not academic, see below.

CONFIG THAT LOOKS LIKE SAMPLE DATA

A key with a plausible-looking placeholder around it still authenticates if it is real. Documentation keys are recognised and ignored.

02 · How we knowOUR OWN REPOSITORY

The first version of this missed most files.

Our secret scanner originally ran only over code it had parsed into entities, which silently skipped Go, JavaScript, TypeScript, PHP, Ruby, Rust and Swift. When we fixed it to read files directly, the very first full run found a live access token committed in our own repository. We rotated it and shipped the fix. A scanner that quietly covers less than you think is worse than no scanner, because you stop looking.

03 · What a finding tells you

Rotate first. Then remove it.

ROTATE

Assume it is known. Anyone with clone access, at any point since the commit, has had it.

THEN REMOVE

Take it out of the working tree and move it to a secret store, so the next commit does not reintroduce it.

THEN GATE

Run the scan in CI so the next one fails the build instead of reaching the default branch.