secretlint: Practical Credential Scanning for Node.js Projects
Pluggable linting tool to prevent committing credential.
At a glance
- What is it?
- secretlint is a pluggable CLI that scans project files for credentials, supports pre-commit and CI integration, and offers Node.js, Docker, and single-executable distribution paths. It is a useful preventive control, but its results depend on rule coverage, configuration, and the files included in each scan.
- Who is it for?
- secretlint fits repositories that want credential findings checked before commits and during CI, especially teams already using Node.js 22+ and willing to tune rules and ignore files. It is a poor fit when operating-system file monitoring is the main requirement, or when a clean scan would be mistaken for proof that no credentials exist.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why secretlint belongs in a Repository Workflow
secretlint addresses a specific preventive problem: finding credential-like data in files before or after it enters a repository. It is aimed at developers and teams that want a lint-style check for secrets rather than reviewing an entire diff manually. The README lists project scanning, CI integration, pre-commit enforcement, custom rules, and configuration as core capabilities. That scope is narrower than general secret management. secretlint does not store credentials, rotate exposed keys, or replace a password manager. Its role is to inspect files and report matching content.
The CLI treats detection as a lint result. An empty result and exit status `0` indicate that the checked inputs produced no lint errors. Exit status `1` means errors were found, while `2` reports an unexpected or fatal error. This contract makes the command suitable for automation, although an important distinction remains: a clean scan only covers the inputs, rules, configuration, and file selection used for that invocation. The README's statement that a successful scan means the project is secure is broader than the technical guarantee visible in the CLI behavior.
Credential masking is enabled by default, which reduces accidental disclosure in terminal output. It can be disabled with `--no-maskSecrets`, but the option removes a protective default and should be treated as an explicit reporting choice. Outputs can also be written as JSON, GitHub annotations, or several other formatter formats, allowing teams to route results according to their local workflow.
How secretlint Processes Files, Globs, and Configuration
The documented flow begins with a CLI input, which may be a file, directory, or glob. Secretlint uses `picomatch` glob behavior. The README specifically says to wrap glob patterns in double quotation marks so the shell does not expand them first. Inputs are checked against `.gitignore` by default as of v13, while `--no-gitignore` disables that behavior. This is significant for generated files and build output: scanning `dist/**/*` in a repository where that path is ignored requires an explicit decision about whether those artifacts belong in the security check.
Configuration can use `.secretlintrc.json`, `.secretlintrc.yml`, or `.secretlintrc.js`. The `--init` command creates `.secretlintrc.json` from `package.json`, while `--secretlintrcJSON` accepts configuration as a JSON string. Rules are pluggable, and the Docker image includes `@secretlint/secretlint-rule-preset-recommend`, `@secretlint/secretlint-rule-pattern`, and `@secretlint/secretlint-formatter-sarif`. The README excerpt does not provide a complete rule configuration example, so it does not establish exactly how a custom rule is registered or which default rules the recommended preset contains.
Standard input is also supported. `--stdinFileName` supplies a filename hint because some rules depend on the apparent file type. This makes piping possible, but it also means callers must pass a meaningful name. Literal paths can be enforced with `--no-glob`, which is relevant for paths containing characters interpreted by glob matching, such as grouped route segments or bracketed parameters.
Installing secretlint and Running the First Scan
For an existing Node.js 22+ project, the documented local setup installs the CLI and recommended rules as development dependencies:
npm install secretlint @secretlint/secretlint-rule-preset-recommend --save-devThis keeps the scanner in the project's dependency record rather than relying on a global installation. The README warns that a global installation can cause some rules to break. After installation, initialize the configuration file:
npx secretlint --initThen scan all quoted inputs below the current directory:
npx secretlint "**/*"A successful invocation without findings returns `0`. Findings return `1`, subject to the documented exception that finding lint errors while `--output` is specified also results in `0`. For a report that a CI script can save and later parse, the README gives this pattern:
npx secretlint "**/*" --format=json --output=secretlint-report.jsonThe exit-code exception means consumers should not treat exit status alone as a complete report-delivery mechanism when `--output` is present.
The quickest supported path requires an existing Docker installation:
docker run -v `pwd`:`pwd` -w `pwd` --rm -it secretlint/secretlint secretlint "**/*"The README says this image works without configuration by design. For hosts without Node.js, the Releases page also provides a single-executable binary. After downloading it, the documented sequence is to make it executable, initialize configuration, and scan the project:
chmod +x ./secretlint
./secretlint --init
./secretlint "**/*"Commit Enforcement, CI Reports, and Output Control
The repository describes secretlint as suitable for both pre-commit checks and CI services. The architecture supports that claim through ordinary exit statuses, ignored-file handling, multiple formatters, and an output path. A team can reject a commit or CI job when the CLI returns `1`, but the excerpt does not include a project-specific hook installation command or a complete CI workflow. It therefore supports the integration model without documenting a turnkey configuration for a particular hook manager or CI vendor.
Formatter selection is an explicit part of the CLI. `--format=github` emits GitHub Actions annotations, while `--format=json` creates a structured report. Other documented formatters include `checkstyle`, `compact`, `junit`, `tap`, `unix`, `pretty-error`, `mask-result`, and `table`. The default is `stylish`. Teams should select a format based on the consumer, not merely on readability. A JSON file can be archived or parsed, while GitHub annotations are intended for display within that CI environment.
Masked output does not change the underlying need to handle a finding carefully. A credential may already be present in Git history, build artifacts, logs, or local configuration. The documented masking option applies to Secretlint's reported output, not to all copies of the source value. The README does not document revocation, history rewriting, or rollback behavior, so those response steps must not be inferred from the scanner.
secretlint's File Selection Boundaries and Failure Modes
The largest practical limitation is that detection depends on the selected rules and the supplied inputs. The README describes custom rules and a recommended preset but does not enumerate every credential type covered by that preset. A zero exit status therefore cannot be interpreted as a guarantee that every possible secret is absent. It says only that the invoked rule set found no errors in the processed files.
Shell expansion is another common source of confusion. Passing an unquoted `"**/*"` pattern can let the shell expand it before secretlint sees it. The documented double quotes preserve the glob for picomatch. Conversely, paths with glob syntax may require `--no-glob` so they are treated literally. For STDIN scans, an inaccurate or missing filename can prevent filename-sensitive rules from selecting the expected behavior.
There is also a subtle automation issue around output. Exit status `0` can mean either that no errors were found or that errors were found while `--output` was specified. CI logic that needs both failure enforcement and a persisted report must account for that documented behavior. Finally, `.gitignore` is respected by default. If ignored build artifacts contain credentials, the scan will omit them unless the operator explicitly uses `--no-gitignore` and chooses an input that reaches those files.
Docker, Node.js, and Binary Trade-offs
These are distribution choices rather than separate scanning engines. Docker provides a prepared environment containing Node.js and built-in packages, including the recommended rule preset, pattern rules, and SARIF formatter. It also works without project configuration by design. The trade-off is an external container runtime and a volume-mounted working directory. The exact Docker image contents and build details are delegated to `publish/docker`.
The Node.js path integrates naturally with `package.json` and development dependency management. It requires Node.js 22+, while the single-executable binary requires no separate Node.js installation. The README prefers project-local npm installation and cautions against global installation because some rules may break there. The binary removes the runtime prerequisite but requires users to download a release artifact and manage its executable permission.
Compared with a simple editor secret scanner, secretlint offers a consistent CLI, reusable configuration, pluggable rules, exit codes, and CI-oriented output. Compared with a specialized credential-management service, it performs local file inspection and reporting rather than credential storage or rotation. Compared with checking only changed lines in a pre-commit hook, a full `npx secretlint "**/*"` invocation scans the supplied project tree, while `.gitignore` and input selection determine how broad that tree actually is. The excerpt does not provide benchmark data, so it does not support a claim that one distribution mode is faster than another.
Maintenance Signals and MIT License Implications
The repository is not archived. Its last push was on 2026-10-15, and the listed releases include v13.0.7 on 2026-10-03, v13.0.6 on 2026-09-25, and v13.0.5 on 2026-08-27. These are concrete signs of recent repository and release activity. The repository also includes a Renovate configuration and CI scripts for build and test orchestration, but the excerpt does not document dependency-update policy or a detailed support window for older releases.
The root `package.json` identifies the repository version as 13.0.7 and the project license as MIT. The single-executable route adds an operational concern that npm users do not have: deciding when to download a new binary and replace the previous executable. The Node.js route instead requires normal dependency installation, while Docker users must decide when to pull a newer image. The documentation does not state automated upgrade instructions for either distribution, so upgrade frequency remains a local operational choice rather than a project guarantee.
The MIT license permits use, modification, distribution, and private use under its terms, subject to preserving its notice and disclaimer. That is a statement about the published license, not legal advice for a particular organization or deployment.
Editorial conclusion
secretlint fits repositories that want credential findings checked before commits and during CI, especially teams already using Node.js 22+ and willing to tune rules and ignore files. It is a poor fit when operating-system file monitoring is the main requirement, or when a clean scan would be mistaken for proof that no credentials exist. Before adoption, verify the selected rule preset against representative files, confirm that `.gitignore` behavior matches the intended scan boundary, and test that exit status `1` blocks the commit or CI stage that should reject findings.
Frequently asked questions
How do I install secretlint in a Node.js project?
With Node.js 22+, install `secretlint` and `@secretlint/secretlint-rule-preset-recommend` as development dependencies. Then run `npx secretlint --init` to create `.secretlintrc.json`.
Does secretlint scan an entire project?
You can request a broad scan with `npx secretlint "**/*"`. The README says to use double quotes so the glob reaches secretlint, and notes that `.gitignore` files are respected by default.
Can secretlint run without Node.js?
Yes. The README documents Docker and a single-executable binary as alternatives that do not require a separate Node.js installation. The binary is downloaded from the Releases page and made executable with `chmod +x ./secretlint`.
How does secretlint behave in CI?
The CLI supports output formatters, including `github` and `json`, and documents exit statuses for findings and unexpected errors. The README does not provide a complete CI workflow or hook installation command.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/secretlint-secretlint)Was this useful?