Nosey Parker is a command-line tool that finds secrets and sensitive information in textual data. It is useful both for offensive and defensive security testing.
Key features:
- It natively scans files, directories, and Git repository history
- It uses regular expression matching with a set of 157 patterns chosen for high signal-to-noise based on experience and feedback from offensive security engagements
- It deduplicates its findings, grouping matches together that share the same secret, which in practice can reduce review burden by 100x or more compared to other tools
- It is fast: it can scan at hundreds of megabytes per second on a single core, and is able to scan 100GB of Linux kernel source history in less than 2 minutes on an older MacBook Pro
- It scales: it has scanned inputs as large as 20TiB during security engagements
An internal version of Nosey Parker has found secrets in hundreds of offensive security engagements at Praetorian. The internal version has additional capabilities for false positive suppression and a rule-free machine learning-based detection engine. Read more in blog posts here and here.
Nosey Parker is available in Homebrew:
$ brew install noseyparker
Prebuilt binaries are available for x86_64 Linux and x86_64/aarch64 macOS on the latest release page. This is a simple way to get started and will give good performance.
A multiplatform Docker image is available for the latest release for x86_64 and aarch64:
$ docker pull ghcr.io/praetorian-inc/noseyparker:latest
A multiplatform Docker image is available for the most recent commit for x86_64 and aarch64:
$ docker pull ghcr.io/praetorian-inc/noseyparker:main
A multiplatform Alpine-based Docker image is available for the latest release for x86_64 and aarch64:
$ docker pull ghcr.io/praetorian-inc/noseyparker-alpine:latest
A multiplatform Alpine-based Docker image is available for the most recent commit for x86_64 and aarch64:
$ docker pull ghcr.io/praetorian-inc/noseyparker-alpine:main
Note: The Docker images run noticeably slower than a native binary, particularly on macOS.
Nosey Parker is available in the Arch User Repository.
Nosey Parker does not currently provide native binaries for Windows (#121). It is possible to run on Windows using WSL1 and the native Linux release.
This has been tested with several versions of Ubuntu Linux on x86_64 and with macOS on both x86_64 and aarch64.
Required dependencies:
cargo
: recommended approach: install from https://rustup.rscmake
: needed for building thevectorscan-sys
crate and some other dependenciesboost
: needed for building thevectorscan-sys
crate (supported version>=1.57
)git
: needed for embedding version information into thenoseyparker
CLIpatch
: needed for building thevectorscan-sys
cratepkg-config
: needed for building thevectorscan-sys
cratesha256sum
: needed for computing digests (often provided by thecoreutils
package)zsh
: needed for build scripts
2. Build using the create-release.zsh
script
$ rm -rf release && ./scripts/create-release.zsh
If successful, this will produce a directory structure at release
populated with release artifacts.
The command-line program will be at release/bin/noseyparker
.
Nosey Parker is essentially a special-purpose grep
-like tool for detection of secrets.
The typical workflow is three phases:
- Scan inputs of interest using the
scan
command - Report details of scan results using the
report
command - Review and triage findings
The scanning and reporting steps are implemented as separate commands because you may wish to generate several reports from one expensive scan run.
Running the noseyparker
binary without arguments prints top-level help and exits.
You can get abbreviated help for a particular command by running noseyparker COMMAND -h
.
More detailed help is available with the help
command or long-form --help
option.
The prebuilt releases also include manpages that collect the command-line help in one place. These manpages converted into Markdown format are also included in the repository here.
If you have a question that's not answered by this documentation, feel free to start a discussion.
Most Nosey Parker commands use a datastore, which is a special directory that Nosey Parker uses to record its findings and maintain its internal state.
A datastore will be implicitly created by the scan
command if needed.
Each input that Nosey Parker scans is called a blob, and has a unique blob ID, which is a SHA-1 digest computed the same way git
does.
Each blob has one or more provenance entries associated with it. A provenance entry is metadata that describes how the input was discovered, such as a file on the filesystem or an entry in Git repository history.
Nosey Parker is a rule-based system that uses regular expressions.
Each rule has a single pattern with at least one capture group that isolates the match content from the surrounding context.
You can list available rules with noseyparker rules list
.
A collection of rules is organized into a ruleset.
Nosey Parker's default ruleset includes rules that detect things that appear to be hardcoded secrets.
Other rulesets are available; you can list them with noseyparker rules list.
When a rule's pattern matches an input, it produces a match. A match is defined by a rule, blob ID, start byte offset, and end byte offset; these fields are used to determine a unique match identifier.
Matches that were produced by the same rule and share the same capture groups are grouped into a finding. In other words, a finding is a group of matches. This is Nosey Parker's top-level unit of reporting.
If you are using the Docker image, replace noseyparker
in the following commands with a Docker invocation that uses a mounted volume:
docker run -v "$PWD":/scan ghcr.io/praetorian-inc/noseyparker:latest <ARGS>
The Docker container runs with /scan
as its working directory, so mounting $PWD
at /scan
in the container will make tab completion and relative paths in your command-line invocation work.
Nosey Parker has built-in support for scanning files, recursively scanning directories, and scanning the entire history of Git repositories.
For example, if you have a Git clone of CPython locally at cpython.git
, you can scan its entire history with the scan
command.
Nosey Parker will create a new datastore at np.cpython
and saves its findings there.
(The name np.cpython
is nonessential; it can be whatever you want.)
$ noseyparker scan --datastore np.cpython cpython.git
Found 28.30 GiB from 18 plain files and 427,712 blobs from 1 Git repos [00:00:04]
Scanning content ████████████████████ 100% 28.30 GiB/28.30 GiB [00:00:53]
Scanned 28.30 GiB from 427,730 blobs in 54 seconds (538.46 MiB/s); 4,904/4,904 new matches
Rule Distinct Groups Total Matches
───────────────────────────────────────────────────────────
PEM-Encoded Private Key 1,076 1,192
Generic Secret 331 478
netrc Credentials 42 3,201
Generic API Key 2 31
md5crypt Hash 1 2
Run the `report` command next to show finding details.
Nosey Parker can also scan Git repos that have not already been cloned to the local filesystem.
The --git-url URL
, --github-user NAME
, and --github-org NAME
options to scan
allow you to specify repositories of interest.
For example, to scan the Nosey Parker repo itself:
$ noseyparker scan --datastore np.noseyparker --git-url https://github.com/praetorian-inc/noseyparker
For example, to scan accessible repositories belonging to octocat
:
$ noseyparker scan --datastore np.noseyparker --github-user octocat
These input specifiers will use an optional GitHub token if available in the NP_GITHUB_TOKEN
environment variable.
Providing an access token gives a higher API rate limit and may make additional repositories accessible to you.
See noseyparker help scan
for more details.
To see details of Nosey Parker's findings, use the report
command.
This prints out a text-based report designed for human consumption:
$ noseyparker report --datastore np.cpython
Finding 1/1452: Generic API Key
Match: QTP4LAknlFml0NuPAbCdtvH4KQaokiQE
Showing 3/29 occurrences:
Occurrence 1:
Git repo: clones/cpython.git
Blob: 04144ceb957f550327637878dd99bb4734282d07
Lines: 70:61-70:100
e buildbottest
notifications:
email: false
webhooks:
urls:
- https://python.zulipchat.com/api/v1/external/travis?api_key=QTP4LAknlFml0NuPAbCdtvH4KQaokiQE&stream=core%2Ftest+runs
on_success: change
on_failure: always
irc:
channels:
# This is set to a secure vari
Occurrence 2:
Git repo: clones/cpython.git
Blob: 0e24bae141ae2b48b23ef479a5398089847200b3
Lines: 174:61-174:100
j4 -uall,-cpu"
notifications:
email: false
webhooks:
urls:
- https://python.zulipchat.com/api/v1/external/travis?api_key=QTP4LAknlFml0NuPAbCdtvH4KQaokiQE&stream=core%2Ftest+runs
on_success: change
on_failure: always
irc:
channels:
# This is set to a secure vari
...
(Note: the findings above are synthetic, invalid secrets.)
Additional output formats are supported, including JSON, JSON lines, and SARIF (experimental), via the --format=FORMAT
option.
Nosey Parker prints out a summary of its findings when it finishes scanning. You can also run this step separately:
$ noseyparker summarize --datastore np.cpython
Rule Distinct Groups Total Matches
───────────────────────────────────────────────────────────
PEM-Encoded Private Key 1,076 1,192
Generic Secret 331 478
netrc Credentials 42 3,201
Generic API Key 2 31
md5crypt Hash 1 2
Additional output formats are supported, including JSON and JSON lines, via the --format=FORMAT
option.
To list URLs for repositories belonging to GitHub users or organizations, use the github repos list
command.
This command uses the GitHub REST API to enumerate repositories belonging to one or more users or organizations.
For example:
$ noseyparker github repos list --user octocat
https://github.com/octocat/Hello-World.git
https://github.com/octocat/Spoon-Knife.git
https://github.com/octocat/boysenberry-repo-1.git
https://github.com/octocat/git-consortium.git
https://github.com/octocat/hello-worId.git
https://github.com/octocat/linguist.git
https://github.com/octocat/octocat.github.io.git
https://github.com/octocat/test-repo1.git
An optional GitHub Personal Access Token can be provided via the NP_GITHUB_TOKEN
environment variable.
Providing an access token gives a higher API rate limit and may make additional repositories accessible to you.
Additional output formats are supported, including JSON and JSON lines, via the --format=FORMAT
option.
See noseyparker help github
for more details.
Nosey Parker has a few third-party integrations:
- Nosey Parker is packaged in Homebrew
- Nosey Parker is packaged in Arch Linux
- A GitHub Action that runs Nosey Parker is available
- DefectDojo includes a parser for Nosey Parker v0.16 JSON
- Nemesis includes support for Nosey Parker
If you have an integration you'd like to share that's not listed here, please create a PR.
Feel free to ask questions or share ideas in the Discussions page.
Contributions are welcome, especially new regex rules. Developing new regex rules is detailed in a separate document.
If you are considering making significant code changes, please open an issue or start a discussion first.
This project has a number of pre-commit hooks enabled that you are encouraged to use.
To install them in your local repo, make sure you have pre-commit
installed and run:
$ pre-commit install
These checks will help to quickly detect simple errors.
Nosey Parker is licensed under the Apache License, Version 2.0.
Any contribution intentionally submitted for inclusion in Nosey Parker by you, as defined in the Apache 2.0 license, shall be licensed as above, without any additional terms or conditions.
Nosey Parker also includes vendored copies of several other packages released under the Apache License and other permissive licenses; see LICENSE
for details.