TRUSTIVAN finds credentials committed to a repository — including ones deleted in a later commit, which is still a live leak, because everyone who ever cloned the repository has them. This page names every detector, the outbound calls validity checking makes (and how to turn them off), the push-protection command, the remediation workflow, and what today’s implementation does not do.

Detectors

Each rule is a format-specific pattern, and every one that has a checksum or a structural check verifies it — a plausible-looking string in a test fixture or a vendor’s own documentation is not a finding. Test keys are reported, not filtered. A sk_test_… Stripe key routinely reads real customer data copied in for debugging, and a repository whose practices leak the test key will leak the live one. Severity is a triage decision, not a detection one. Two files, two leaks. The same credential committed to two files is two findings with two remediations — each file has to be edited. Renaming a file that contains an already-leaked credential is tracked as two observations of one credential today, because rename detection is deliberately disabled during the history walk (a similarity heuristic is itself attacker-influenced input). The credential’s own identity (a salted digest of its bytes) is identical either way, which is what makes rotation trackable by digest rather than by location — see Remediation below.

Validity checking

Finding a credential and knowing it still works are different facts. For five rules with a safe, read-only “who am I” endpoint, TRUSTIVAN can ask the credential’s own provider: Every one of those five URLs is a literal string in TRUSTIVAN’s code. None is built from anything a scan observes — not the host, not the path — so nothing in a repository can redirect the check anywhere else. The credential travels in exactly the header or body position its own provider’s auth scheme documents, is never logged, and is discarded the instant the provider answers; only the verdict (live, invalid, or unknown) and a timestamp are stored. A network failure or a 5xx resolves to unknown, never to invalid — an outage must never read as “this credential is dead.” Not covered, and there is no plan to fake it: AWS keys, GCP keys, private keys, database URLs and the generic high-entropy rule have no validity check. An AWS access key ID alone cannot authenticate to anything — it needs its paired secret key, which this scanner does not correlate across a file — and “validating” a database URL would mean TRUSTIVAN connecting to a host a customer’s repository named, which is exactly the server-side request forgery every other outbound path in this product exists to refuse.

Turning it on, and off

Off by default, for every organization. Turning it on makes TRUSTIVAN present your own discovered credentials to their own providers on your behalf — that’s a decision only an owner or admin can make, and only a human, never an API key:
GET the same path to read the current setting. Turning it off stops every future check; verdicts already recorded on existing findings are not erased, because a credential that was live an hour ago is still evidence. A confirmed-live credential is raised to critical severity — this is no longer “a string shaped like a key,” it is one the provider accepted moments ago.

Push protection

trustivan secrets scan --staged runs the same detector set locally, against exactly the lines about to be committed, with no network call at all. It’s the other half of the product: everything above tells you about a leak that already happened; this stops one from happening.
Exit code 0 means clean, 1 means a secret was found (the commit should stop), 2 means the command itself could not run (no git, not a repository). Only added lines are scanned — a secret already in the file before this commit is the history engine’s job, not this command’s, and re-flagging it on every unrelated commit that happens to touch the same file is how a push-protection hook gets disabled.

Pre-commit hook

CI

Note that CI usually checks out a merge commit with nothing staged — run this against a pull request’s diff (git diff origin/main...HEAD) with your own wrapper, or rely on gate’s repository-target scan, which reads the full clone rather than the index.

Remediation

POST /api/v1/findings/:id/rotate records that a credential has been rotated or revoked — who, when, and a required note. This is not a status change: the finding stays open, because the credential is still readable in the repository’s history regardless of what you do to it at the provider, and marking it “resolved” would misrepresent that. What you get is a durable record — a secret_rotated timeline event and a badge on the finding — so a rotated credential doesn’t sit in the backlog looking unaddressed.
Every finding carries provider-specific rotation guidance in its description — which console, which button — rather than a generic “rotate it” that leaves you to go find that out yourself. Fingerprints are stable across all of this. Marking a secret rotated, recording a validity verdict, or a cosmetic difference in how a path is spelled across engines and platforms never changes a finding’s identity — a rotated secret does not reappear as a new finding, and your suppression or triage history survives. A genuine rename to a different path is deliberately still a different finding (see “two files, two leaks” above).

Limitations, stated honestly

  • AWS, GCP, private keys, database URLs and the generic rule have no validity check — see above.
  • A file rename is tracked as two observations, not one continuous finding, because rename detection is disabled during the history walk.
  • Shallow clones are refused by default. A credential introduced before a shallow clone’s earliest commit cannot be found in it, and TRUSTIVAN will not report a shallow scan as a clean one.
  • secrets scan --staged only reads the git index. It does not scan history, and it is not a replacement for the git-history engine — it is the complement to it.