Kingfisher is a secrets scanner published by MongoDB, under the Apache-2.0 license and written in Rust, that does not stop at detection: it checks that a secret is active, maps what it can reach, then can revoke it. Where the three previous scanners of the module stop at the finding, at verification or, for TruffleHog, at a permissions analysis, Kingfisher chains five steps in a single tool: detect, validate, map, triage, revoke. This lesson walks through all five, with emphasis on the last three, which Gitleaks, Betterleaks and TruffleHog do not cover, or not in the same way.
What you will learn
- Scan a folder, the history of a repository and an organization with Kingfisher, then read the result.
- Tell an active, inactive, inconclusive and merely assumed-valid secret apart.
- Map the blast radius of a valid secret with
--blast-radius, and know when to do it. - Revoke a supported secret with
kingfisher revoke, knowing the limits of the action. - Wire the tool into a pre-commit hook and into GitHub Actions, using its exit codes.
- Tie the lesson to the SOCLE: the requirement SOCLE-SEC-GEN-6 (in French), secret leak detection and response procedure, finds its detection and response tooling here.
Prerequisites
This lesson assumes what the three previous lessons of the module teach: why a committed secret stays readable in Git history, what a false positive is, and why a secret is validated with its provider. If these notions are fuzzy, read Gitleaks and then TruffleHog first, and the guide on secrets in code and Git history. You also need to be able to read a YAML file and run commands in a terminal.
On the workstation side, plan for Docker, Homebrew or uv, your choice, and a throwaway Git repository. No provider account is needed for the first experiments: the secret used here is fake.
Five steps in a single tool
A classic scanner returns a list of candidates: strings that look like a key. Kingfisher extends that list in five steps, which its documentation sums up as "Detect, Validate, Map, Triage, Revoke". The diagram below puts them in order, with the command behind each one. Look mostly at the second box, which turns a list of candidates into a list of proven secrets, and at the last one, in red, the only one that changes something at a third party.
The first two steps exist elsewhere, in a similar form. Validation is what TruffleHog calls verification and what Betterleaks enables with its dedicated option: it sends the secret to the provider to find out whether it works. TruffleHog can also analyze the permissions of some credentials. What Kingfisher brings together, according to its README, is mapping of access, a report viewer and revocation for the supported providers, all in the free version, with no separate paid offer.
The Kingfisher repository also publishes comparative scan times, where the tool comes first on every repository tested. They come from a 16-core macOS machine and are not a benchmark of the current version, as the repository itself states: measure on your own repositories before relying on them.
Installing Kingfisher
Three routes are enough to get started. Homebrew and the PyPI package install the binary on the workstation; the container image avoids any installation and suits CI.
# Homebrew (macOS, Linux)brew install kingfisher
# PyPI package that ships the binaryuv tool install kingfisher-bin==2.16.0
# Container image: version tag and digestdocker run --rm \ ghcr.io/mongodb/kingfisher:2.16.0@sha256:76ffeabd207296512359dccf740587e76f2dcd6821d3e53431a734627cb510aa \ --versionThe command prints the installed version.
kingfisher 2.16.0The following examples call kingfisher directly. The image needs three more settings, otherwise the report is lost or refused: it runs as user 10001 with the working directory /app, which is not your folder. So mount the repository in /src, pass your own user ID with -u so that the report belongs to you, and write it under /src.
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD":/src \ ghcr.io/mongodb/kingfisher:2.16.0@sha256:76ffeabd207296512359dccf740587e76f2dcd6821d3e53431a734627cb510aa \ scan /src --format json --output /src/findings.jsonThe findings.json file appears in the current folder. For the viewer, the server must listen on all interfaces of the container (--address 0.0.0.0), and the port is published on your workstation's loopback only (-p 127.0.0.1:7890:7890): no other computer on the network can reach it. The container has no browser, so open http://127.0.0.1:7890 yourself.
docker run --rm -u "$(id -u):$(id -g)" -p 127.0.0.1:7890:7890 -v "$PWD":/src \ ghcr.io/mongodb/kingfisher:2.16.0@sha256:76ffeabd207296512359dccf740587e76f2dcd6821d3e53431a734627cb510aa \ view /src/findings.json --address 0.0.0.0First scan on a fake manifest
To see the validation statuses without risk, create a throwaway repository with a fake Kubernetes manifest. The token below has the shape of a GitHub personal token but matches no account: the provider will reject it.
mkdir demo-kingfisher && cd demo-kingfishergit init --quietcat > secret.yaml <<'EOF'apiVersion: v1kind: Secretmetadata: name: ci-githubstringData: token: ghp_R7kQ2mZ9xT4vB8nW1cL6yD3sF5hJ0aPeUgXiEOFgit add secret.yamlgit -c user.name=demo -c user.email=demo@example.org commit --quiet -m "add a fake secret"Then run the scan. By default, Kingfisher scans the full history of the repository (--git-history full) and attempts live validation. The exit code matters as much as the display, which is why it is printed.
kingfisher scan . --format json --output findings.jsonecho "exit code: $?"The scan found something. The code 200 means "visible findings". The code 205, "visible and validated findings", is reserved for secrets proven active: the provider rejected the fake token, so it does not apply here.
exit code: 200The findings.json report then carries, for the fake token, the validation status verified_inactive and the provider's response (excerpt):
{"outcome":"verified_inactive","status":"Inactive Credential","response":"{\"reason\":\"Unauthorized\",\"result\":\"invalid\"}"}With --no-validate, the same scan also returns the code 200, but the status becomes not_attempted ("Not Attempted") and no request goes to GitHub.
Open the report to read the status. In the JSON, the field to use in automation is finding.validation.outcome, which carries a stable value, whereas the displayed label may change.
kingfisher view findings.jsonThe viewer starts locally on 127.0.0.1:7890 and opens the browser (with the image, use the container view command given above). Since the token is fake, the expected result is the Inactive Credential status, with the value verified_inactive. The JSON report contains exactly this information, which you can also read without a browser:
grep -o '"outcome":"[a-z_]*"' findings.json"outcome":"verified_inactive"If you get the Inconclusive Validation status instead, the provider did not answer (workstation offline, rate limit): see the troubleshooting section below. Then delete the test repository.
cd .. && rm -rf demo-kingfisherReading the validation verdict
Validation is the heart of the tool, and its result is not reduced to "active or not". The Kingfisher documentation distinguishes several statuses, and the triage of alerts depends on them. The table below lists the main ones; the machine value is the one to test in a script.
| Displayed status | Machine value | What it proves |
|---|---|---|
| Active Credential | verified_active | A validator proved the secret works: handle it first. |
| Inactive Credential | verified_inactive | The provider rejected the secret: it is dead, but still needs cleaning up. |
| Inconclusive Validation | unavailable | The check did not complete (timeout, limit, server error): neither proof of activity nor of inactivity. |
| Assumed Valid (Not Live-Validated) | assumed | The secret is very probably real, but nobody tested it live. |
| Not Attempted | not_attempted | No validation produced: no validator for this rule, or --no-validate. |
A filter selects what stays in the report. The --validation-filter option accepts three values: all, which keeps everything and is the default; active, which keeps only secrets proven active; and actionable, which adds assumed-valid secrets and those recognized by a local computation. The --only-valid option is an alias of --validation-filter active, and the two cannot be combined.
# Keep only the secrets proven activekingfisher scan . --validation-filter active --format jsonWhen all the secrets in the repository are dead, the resulting report has an empty findings array ({"findings":[],"audit":{...). On the fake token, the exit code is still 200, because the code counts the findings before the filter. To decide on a block, test the content of the report or the code 205, not the code 200 alone.
Why not filter on active systematically? Because an inactive secret is not necessarily harmless: copied elsewhere, it may still open another service, and the history keeps it readable. The filter is there to order the fixes, not to erase findings.
Mapping the blast radius
Knowing that an AWS key is active does not tell you whether it opens a test bucket or the whole production environment. The --blast-radius option, whose alias is --access-map, answers that question for the supported secret types: it identifies the owner of the secret (user, role, service account), its recorded permissions and the visible resources. For AWS, it also follows the roles the key can assume; for GCP, the service accounts it can impersonate.
kingfisher scan . --only-valid --blast-radius --format json --output findings.jsonThe JSON report is the same as usual, enriched with an access_map field for each active secret of a supported provider. The output therefore depends on a really active secret: the mapping queries the provider's API with the secret, and a fake token gives nothing to map. With the fake token of the lesson, the command returns the code 200 and a report with an empty findings array, with no access_map field at all, because --only-valid drops everything that is not proven active. To see a real map, you need an active secret and an account you are allowed to inspect.
Three precisions prevent misreading the result. The mapping is read-only and "best effort": an access that was not observed is not an impossible access, because the policies and candidate paths give context without proving each access. It runs network requests on top of validation, and the documentation says to use it only if you are authorized to inspect the targeted account. Finally, it only applies to supported providers: the documentation counts forty-three at this tag, and the list is authoritative, not this figure.
To inspect a single known secret without scanning a repository, the standalone kingfisher blast-radius command produces the same map from a rule and the secret supplied directly. Use --aws-region or --gcp-project to widen discovery to other regions or projects. With the fake token of the lesson, kingfisher blast-radius --rule github-pat <token> fails cleanly, with the exit code 1:
Error: Blast-radius mapping failed for all rules matching 'github-pat':- betterleaks.github-pat: Identity mapping failed: GitHub access-map: user lookup failed with HTTP 401 UnauthorizedRevoking a secret
When an active secret is found and its owner cannot be found, has left or is unreachable, waiting for rotation prolongs the exposure. The kingfisher revoke command disables the secret directly with the provider, without going through the employee who created it. It is an explicit action: no scan ever revokes anything.
kingfisher revoke --rule github-pat "$COMPROMISED_TOKEN"The command prints a success or failure message for each rule applied. The exit code is 0 if at least one rule revoked the secret, and 1 if all failed or if an error occurred. With the fake token of the lesson (ghp_R7kQ...), the output of 2.16.0 is:
Rule: Uncovered a GitHub Personal Access Token, potentially leading to unauthorized repository access and sensitive content exposure. (betterleaks.github-pat)Result: REVOKEDStatus: 202Response: {
}The exit code is 0. Keep in mind what this proves: the provider accepted the request (HTTP 202), not that the token existed. A fake token gets the same REVOKED. After a revocation, check the status of the secret with the provider rather than relying on the message alone.
Revocation is deliberately conservative. Kingfisher only offers the action when it can identify the exact key and gather the values the provider requires; at this tag, the documentation counts 34 revocation rules for 15 provider families (AWS, GitHub, GitLab, npm, Cloudflare, Hugging Face, among others), and the capabilities file in the repository is the reference list. For a secret outside the list, you must go through the provider's console.
Choosing the scan target
A local repository is only one of the targets. The kingfisher scan command accepts subcommands that enumerate organizations, storage and collaboration tools, each with its token in an environment variable prefixed KF_. The table gives the most useful ones; the full list is in the repository's integrations guide.
| Target | Command | Authentication |
|---|---|---|
| Local folder or repository | kingfisher scan . | none |
| Remote repository | kingfisher scan https://github.com/org/repo.git | KF_GITHUB_TOKEN if private |
| GitHub organization | kingfisher scan github --organization org | KF_GITHUB_TOKEN |
| GitLab group | kingfisher scan gitlab --group group --include-subgroups | KF_GITLAB_TOKEN |
| Container image | kingfisher scan docker image:tag | KF_DOCKER_TOKEN if the registry is private |
| S3 bucket | kingfisher scan s3 my-bucket | --profile or KF_AWS_KEY and KF_AWS_SECRET |
| Issues and wikis | kingfisher scan jira and kingfisher scan confluence | KF_JIRA_TOKEN, KF_CONFLUENCE_TOKEN |
| Messages | kingfisher scan slack "api_key OR password" | KF_SLACK_TOKEN |
Before scanning an organization, the --list-only option prints the repositories that would be scanned, without scanning anything. It is a good habit: a token that sees a thousand repositories would scan them all, and it is better to know it beforehand.
KF_GITHUB_TOKEN="$READ_TOKEN" kingfisher scan github --organization my-org --list-onlyThe command prints the clone URL of each repository of the organization visible with this token, one per line, with no scan result. With three repositories, the output of 2.16.0 is:
https://github.com/my-org/billing-api.githttps://github.com/my-org/infra-terraform.githttps://github.com/my-org/marketing-site.gitCounting the lines gives the number of repositories the scan would go through. The command queries the forge's API, so it does not work offline. If your workstation has no network, you get the exit code 1 and a DNS resolution error instead of the list.
On history, the default is to go through everything. Three options bound it: --git-history none scans only the current state of the files; --since-commit <ref> scans the commits added since a reference, which suits a pull request review; --staged scans the changes waiting to be committed. The --path-prefix, --skip-path-prefix and --file-extension options also restrict the paths.
Choosing the output format
The format is set with --format, and --output writes to a file instead of the screen. Four formats cover the essentials: json for scripts, sarif for a forge's security tab, html for a standalone audit report, and pretty for the terminal. A fifth, toon, is designed to be handed to an AI agent.
The viewer is not limited to Kingfisher reports: it also reads the reports of Gitleaks and TruffleHog and merges them while deduplicating. If you already have these scanners in place, kingfisher view gitleaks.json trufflehog.jsonl gives a common triage table without changing your pipelines.
Wiring Kingfisher into the pipeline
The exit codes make Kingfisher usable in automation: they distinguish a secret that was merely found from a secret proven active.
| Code | Meaning |
|---|---|
0 | No visible finding. |
200 | Visible findings. |
205 | Visible and validated findings. |
1 | Fatal scan error. |
2 | Invalid arguments. |
3 | Nothing to scan. |
These codes allow a two-level policy. Blocking the merge on 205 only avoids bothering teams over dead secrets, while blocking on 200 as well is stricter and suits a sensitive repository. A scan can continue after a read error and return a success code with partial coverage: in production, also check audit.summary.scan_partial and audit.summary.scan_failed in the JSON report.
Pre-commit hook
The pre-commit framework runs checks before each commit. The Kingfisher repository does publish ready-to-use hooks, but the kingfisher-auto hook downloads the latest version of the binary without verifying its checksum, and the kingfisher-docker hook pulls the latest image: neither of them is pinned, even if rev is. We set them aside here in favor of a local hook, which runs the digest-pinned image with language: docker_image. The framework then mounts the repository in /src and passes your user ID, which settles two of the Docker route pitfalls seen above. A third is specific to the --staged option: to scan the indexed files, Kingfisher creates a snapshot with git commit-tree, and Git refuses to do so without an identity. The framework does not pass your Git configuration to the container, hence the four GIT_* variables at the head of the entry, which provide a service identity unrelated to yours.
repos: - repo: local hooks: - id: kingfisher name: kingfisher language: docker_image entry: >- -e GIT_AUTHOR_NAME=kingfisher -e GIT_AUTHOR_EMAIL=kingfisher@localhost -e GIT_COMMITTER_NAME=kingfisher -e GIT_COMMITTER_EMAIL=kingfisher@localhost ghcr.io/mongodb/kingfisher:2.16.0@sha256:76ffeabd207296512359dccf740587e76f2dcd6821d3e53431a734627cb510aa scan . --staged --quiet --no-update-check pass_filenames: falseInstall the hook with pre-commit install. At each commit, --staged limits the scan to the files waiting to be committed (pass_filenames: false only prevents the framework from appending their names to the command), and the commit is refused if the exit code is not 0. The repository must already contain at least one commit: without it, the scan fails on a Git error. In both Git failure cases (no commit, no identity), the hook shows Passed and the commit goes through, secret included: see the troubleshooting section.
Here is what git commit prints in a repository that already has a commit, when secret.yaml, which contains the fake token of the lesson, is staged but not yet committed, with Kingfisher 2.16.0 (the output is shortened). Without network access, the provider does not answer, hence the inconclusive status.
kingfisher...............................................................Failed- hook id: kingfisher- exit code: 200
GITHUB-PAT => [BETTERLEAKS.GITHUB-PAT] |Finding.........: ghp_R7kQ2mZ9xT4vB8nW1cL6yD3sF5hJ0aPeUgXi |Description.....: Uncovered a GitHub Personal Access Token, potentially leading to unauthorized repository access and sensitive content exposure. |Fingerprint.....: 667680336578602825 |Confidence......: high |Entropy.........: 5.22 |Validation......: Inconclusive Validation |__Response......: Betterleaks validation request failed |Language........: YAML |Line Num........: 6 |Path............: secret.yaml...The hook's exit code is 200, so the commit is refused: git log shows no new commit. With network access, the Validation line shows Inactive Credential for this fake token, and the code stays 200. With no secret in the index, the hook shows Passed and the commit is created.
GitHub Actions workflow
The following workflow scans the commits of a pull request with the pinned image. The base SHA goes through an environment variable rather than being inserted into the command, so that no GitHub context data is interpreted as shell. The step fails on any non-zero code.
name: secretson: pull_request:
permissions: {}
jobs: kingfisher: runs-on: ubuntu-24.04 permissions: contents: read steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: fetch-depth: 0 persist-credentials: false
- name: Scan the pull request commits env: BASE_SHA: ${{ github.event.pull_request.base.sha }} run: | code=0 docker run --rm -v "$PWD":/src \ ghcr.io/mongodb/kingfisher:2.16.0@sha256:76ffeabd207296512359dccf740587e76f2dcd6821d3e53431a734627cb510aa \ scan /src --since-commit "$BASE_SHA" --quiet --no-update-check --format json || code=$? echo "exit code: $code" exit "$code"The step prints exit code: 0 when the pull request adds no secret, and exit code: 200 or 205 with a failed step otherwise. If the second commit of the pull request adds the fake token, the JSON report is printed first, then the last line reads:
exit code: 200If the second commit adds no secret, the report starts with {"findings":[],"audit":... and the last line reads exit code: 0. The minimal permissions, the pinned SHA, persist-credentials: false and passing the context through env follow the rules of actionlint and zizmor: run both tools on your own workflows before merging them.
To block only on validated secrets, replace the last line with a test that fails only if code equals 205. On a pull request coming from a fork, validation sends the secret it found to a third party: if the content is not trusted, add --no-validate.
Troubleshooting
The symptoms below are the ones you meet while following the lesson. Two of them look alike: a 200 code while the report is empty, and a 0 code while Git failed. In both cases the exit code alone misleads, and it is the report that says what really happened.
| Symptom | Likely cause | Fix |
|---|---|---|
manifest unknown when pulling the image | Tag written v2.16.0 with a v | Use ghcr.io/mongodb/kingfisher:2.16.0, without v. |
With the image, findings.json is not found, or Permission denied | Without -u, the container runs as user 10001 and writes to /app; its mounted /src is not writable | Pass -u "$(id -u):$(id -g)" and --output /src/findings.json. |
kingfisher view in the container, nothing in the browser | No published port, or server bound to 127.0.0.1 inside the container | Add -p 127.0.0.1:7890:7890 and --address 0.0.0.0. |
Exit code 3 | No repository or file to scan (user without repositories, everything excluded) | Check the target with --list-only and the exclusions. |
Exit code 200 although everything seems dead | The code counts the findings before the filter, so it stays 200 even when the report is empty | Add --validation-filter active to empty the report, then block on the code 205 or on a non-empty findings array. |
Git command failed (exit status: 128) with --staged, yet code 0 | Repository with no commit at all, or container without a Git identity (the pre-commit hook does not pass your configuration): Git cannot create the snapshot of the indexed files | Make a first commit, and add -e GIT_AUTHOR_NAME=... -e GIT_AUTHOR_EMAIL=... -e GIT_COMMITTER_NAME=... -e GIT_COMMITTER_EMAIL=... before the image, with -u "$(id -u):$(id -g)" outside pre-commit; do not rely on the exit code alone, run pre-commit run --verbose to see the error. |
Inconclusive Validation status | Provider unreachable, timeout or rate limit | Rerun the scan after a few minutes; do not conclude the secret is dead. |
Not Attempted status everywhere | --no-validate active, or no validator for the rule | Remove --no-validate; for a rule without a validator, check by hand. |
| Error when combining options | --only-valid and --validation-filter together | Keep only one of the two. |
| Green pipeline although a repository was not read | Partial scan that returns a success code | Read audit.summary.scan_partial in the JSON report. |
--since-commit finds nothing in CI | Shallow clone without the base commit | Clone with fetch-depth: 0. |
Gitleaks, Betterleaks, TruffleHog or Kingfisher: which one should you choose?
All four scanners detect secrets, and their differences are mostly about what they do after detection: verify, measure, revoke. Kingfisher is the only one to document these three steps together in a stable version, but the table also shows what the others do better or differently, for example the breadth of sources of TruffleHog or the simplicity of Gitleaks.
The table compares the four scanners on what matters when you choose: where they look, what they do with a secret they find, and how they fit into a delivery pipeline. Every cell comes from the tool's own documentation at the version shown in the header. When that documentation says nothing about a capability, the cell reads "not documented": this does not prove the tool is unable to do it, only that its documentation does not announce it.
| Criterion | Gitleaks 8.30.1 | Betterleaks 1.9.0 | TruffleHog 3.99.7 | Kingfisher 2.16.0 |
|---|---|---|---|---|
| Git repository and history | yes, gitleaks git (via git log -p) | yes, betterleaks git | yes, trufflehog git | yes, history included |
| Remote repository, organization | not documented (three modes: git, dir, stdin) | GitHub (organization, user, PRs, issues, Actions, releases), GitLab (group, project, merge requests), Hugging Face | GitHub (--org), GitLab, Hugging Face | GitHub, GitLab, Azure Repos, Bitbucket, Gitea, Hugging Face |
| Files and directories | yes, gitleaks dir | yes, betterleaks dir | yes, trufflehog filesystem | yes |
| Container image | not documented | not documented | yes, trufflehog docker | yes, kingfisher scan docker |
| Other sources | standard input | standard input, S3 (including Cloudflare R2) | S3, GCS, Postman, Jenkins, Elasticsearch, CircleCI, Travis CI, syslog, standard input | S3, GCS, Azure Blob Storage, Jira, Confluence, Slack, Teams, Postman |
| Checks that a secret is active | not documented | yes, through a validate expression in the rule, opt-in only, --validation in 1.9.0 (-v or --validate in version 2); statuses valid, invalid, revoked, unknown, error | yes, by calling the provider's API, enabled by default (--no-verification turns it off) | yes, enabled by default (--no-validate turns it off) |
| Measures the blast radius | not documented | not documented in 1.9.0; the version 2 preview adds -a or --analyze (account, capabilities and severity of valid tokens) | yes, trufflehog analyze (permissions and reachable resources) for some credential types | yes, --blast-radius for the supported providers (identities, permissions, resources) |
| Revokes a secret | not documented | not documented in 1.9.0 (revocation only appears there as a status returned by validation); the version 2 preview announces betterleaks revoke | not documented | yes, kingfisher revoke, for the supported providers |
| Pre-commit hook | yes, pre-commit hooks provided | yes, pre-commit hooks provided | yes, documented (hooksPath, pre-commit framework, Husky) | yes, install script and pre-commit framework |
| CI integration | gitleaks-action action (separate repository), Docker image | Docker image ghcr.io/betterleaks/betterleaks; no dedicated action in the README | GitHub action trufflesecurity/trufflehog, Docker image | Docker image ghcr.io/mongodb/kingfisher; no dedicated action in the documentation |
| Output formats | JSON, CSV, JUnit, SARIF, template | JSON, CSV, JUnit, SARIF, template (JSONL for validate) | text, JSON, SARIF, GitHub Actions format | human-readable text, JSON, JSONL, BSON, TOON, SARIF, HTML |
| License | MIT | MIT | AGPL-3.0 | Apache-2.0 |
| Language | Go | Go | Go | Rust |
Survey carried out on 2026-10-30 on the latest published version of each tool. Versions move fast: check the date before relying on a cell.
The right tool depends first on what you want to do with a secret once it is found. To block a commit or a merge, all four will do, and Gitleaks is enough when its rules are mastered and it is already in place. To tell live secrets from leftover examples, you need a tool that validates: Betterleaks (opt-in), TruffleHog or Kingfisher. To know what an active token opens up, TruffleHog (analyze) and Kingfisher (--blast-radius) answer, each on the providers it supports; Betterleaks adds a comparable analysis in its version 2, still a preview. To act without waiting for the owner of the secret, only Kingfisher documents revocation from the command line in the stable versions surveyed; Betterleaks announces one for its version 2 as well.
If the target goes beyond the repository (issues, chat, images, buckets), look at the "Other sources" row: the scope varies a lot from one tool to another. An AGPL-3.0 license can also weigh in the choice depending on how your organization uses the tool. Finally, a scanner that finds nothing proves nothing: test the one you pick on a repository containing a known fake secret before wiring it into CI. To freeze what already exists and block only new findings, the detect-secrets guide (in French) covers a baseline approach, and the comparison of secret detection tools widens the view to other candidates.
Key takeaways
- Kingfisher chains five steps in one tool: detect, validate, map, triage, revoke, with one command per step.
- Only validation, mapping and revocation leave your machine: run them only on accounts you are allowed to inspect.
- A secret is classified as active, inactive, inconclusive or assumed valid; in a script, test
finding.validation.outcomerather than the displayed label. - The exit code distinguishes
200(visible finding) from205(validated finding), which lets you block only on proven secrets. --blast-radiusmaps in read-only and best-effort mode: an access absent from the result is not an impossible access.kingfisher revokeis cautious and explicit; it replaces neither rotation nor an access audit.- The image is pulled without a
v(2.16.0) and pinned by digest, in CI as in the pre-commit hook: the hooks supplied by the repository are not. - For the SOCLE-SEC-GEN-6 requirement, a Kingfisher scan wired into CI or a hook on your repositories provides only the first half of the evidence, the detection system. The other half is a written response procedure: even if Kingfisher can revoke, that procedure says who decides, when to run
kingfisher revokeand what follows (rotation, audit, history cleanup).
Knowledge check
Check that you have the essentials of this guide. The questions only cover what has just been explained here.
Knowledge check
Check what you have learned with this interactive quiz
How it works
- The timer starts when you click Start
- Multiple choice, true/false and short answer questions
- You can move between questions
- Detailed results are shown at the end
Starts the quiz and the timer
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: SAST: analysing source code to find flaws
A new full quiz with random questions
Work again only on the questions you missed