{"id":19905296,"url":"https://github.com/jonaylor89/jaz","last_synced_at":"2026-02-06T06:00:26.435Z","repository":{"id":36418266,"uuid":"214289048","full_name":"jonaylor89/JAZ","owner":"jonaylor89","description":"Find secrets hidden in commits","archived":false,"fork":false,"pushed_at":"2026-01-16T03:57:54.000Z","size":70,"stargazers_count":23,"open_issues_count":1,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-01-16T18:41:54.236Z","etag":null,"topics":["find-secrets-hidden","jaz","secrets","security","security-audit","security-scanner"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jonaylor89.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["jonaylor89"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null}},"created_at":"2019-10-10T21:29:16.000Z","updated_at":"2026-01-16T03:57:44.000Z","dependencies_parsed_at":"2023-02-18T19:46:03.156Z","dependency_job_id":null,"html_url":"https://github.com/jonaylor89/JAZ","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/jonaylor89/JAZ","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2FJAZ","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2FJAZ/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2FJAZ/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2FJAZ/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jonaylor89","download_url":"https://codeload.github.com/jonaylor89/JAZ/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jonaylor89%2FJAZ/sbom","scorecard":{"id":530589,"data":{"date":"2025-08-11","repo":{"name":"github.com/jonaylor89/JAZ","commit":"ff47e46d0cbd696a1444f552d7788f901fca2688"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 1/19 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":2,"reason":"3 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: topLevel 'contents' permission set to 'write': .github/workflows/release-plz.yml:5","Warn: no topLevel permission defined: .github/workflows/rust.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release-plz.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/jonaylor89/JAZ/release-plz.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-plz.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/jonaylor89/JAZ/release-plz.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release-plz.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/jonaylor89/JAZ/release-plz.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/rust.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/jonaylor89/JAZ/rust.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:4","Warn: containerImage not pinned by hash: Dockerfile:16: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned","Info:   0 out of   2 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v0.0.3 not signed: https://api.github.com/repos/jonaylor89/JAZ/releases/91364011","Warn: release artifact v0.0.3 does not have provenance: https://api.github.com/repos/jonaylor89/JAZ/releases/91364011"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":9,"reason":"1 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: RUSTSEC-2024-0013 / GHSA-22q8-ghmq-63vf"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 13 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T05:37:30.864Z","repository_id":36418266,"created_at":"2025-08-20T05:37:30.864Z","updated_at":"2025-08-20T05:37:30.864Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29153115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-06T02:39:25.012Z","status":"ssl_error","status_checked_at":"2026-02-06T02:37:22.784Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["find-secrets-hidden","jaz","secrets","security","security-audit","security-scanner"],"created_at":"2024-11-12T20:32:27.806Z","updated_at":"2026-02-06T06:00:26.428Z","avatar_url":"https://github.com/jonaylor89.png","language":"Rust","funding_links":["https://github.com/sponsors/jonaylor89"],"categories":[],"sub_categories":[],"readme":"\n# JAZ - Git Repo Secret Scanning  \n\nblog post:\n[https://blog.jonaylor.xyz/discover-hidden-secrets-in-git-repos-with-rust](https://blog.jonaylor.xyz/discover-hidden-secrets-in-git-repos-with-rust)\n\n### Intro\n\nWith the growing importance of open source software and increasing usage of public code repositories like GitHub, it has become increasingly important to protect against accidental secret commiting. While it may seem that doing this is as easy as deleting a key file or removing an oauth token from a configuration file, the bittersweet fact about git is that it'll keep a history of that secret. By searching through the git commit logs, an attacker could find and exploit application secrets. This project set out to create an automated way to find secrets hidden in the git commit history.\n\n### Secrets Scanning\n\nAs of now we are scanning for the following secrets based off common regex patterns identifying them.  More can easily be added once a regex pattern is developed to identify them.\n\n1. Slack Token  \n2. RSA private key  \n3. (OPENSSH) private key  \n4. SSH (DSA) private key  \n5. SSH (EC) private key  \n6. PGP private key block  \n7. Facebook Oauth  \n8. Twitter Oauth  \n9. GitHub  \n10. Google Oauth  \n11. AWS API Key  \n12. Heroku API Key  \n13. Generic Secret  \n14. Generic API Key  \n15. Slack Webhook  \n16. Google (GCP) Service-account  \n17. Twilio API Key  \n18. Password in URL\n \n### Design\n\nIn each object contained in the object database, we scan through and look for regex patterns of common keys provided by an array. If any secrets are found, the script simply prints the secret type to the console and provides the object id.\n\n### Improvements  \n\nThe following is a list of improvements that would be good to add for the future.  In general they make JAZ better or easier to use.\n\n- Threadpool  \n- Config file based scanning  \n- remote scanning  \n- better CI/CD  \n- automated GitHub repo scanning  \n\n### Installation\n\n**From Source**\n```bash\n~$ git clone https://github.com/jonaylor89/JAZ.git\n~$ cd JAZ\n~$ cargo build --release\n```\nThis will build into the `target/release` directory. For debug builds, use `cargo build`.\n\n**Arch Linux**\n```bash\n~$ yay -S jaz\n```\n\n**MacOS**\n```bash\n~$ brew install jaz\n```\n\n**Cargo**\n```bash\n~$ cargo install jaz\n```\n\n### Usage\n\n**Basic Usage**\n```bash\n# Scan current directory (must be a git repository)\n~$ jaz\n\n# Scan a specific repository\n~$ jaz /path/to/repo\n\n# Scan with compiled binary\n~$ ./target/release/jaz /path/to/repo\n```\n\n**Example Output**\n```\n[INFO] /path/to/repo/.git/ state=Clean\n--------------------------------------------------------------------------\n[CRITICAL] object a1b2c3d4e5f6 has a secret of type `AWS API Key`\n[CRITICAL] object f6e5d4c3b2a1 has a secret of type `SSH (OPENSSH) private key`\n[CRITICAL] object 1234567890ab has a secret of type `Slack Token`\n```\n\n**Common Use Cases**\n\n1. **Pre-commit Hook**: Add JAZ to your git hooks to scan before commits\n   ```bash\n   # .git/hooks/pre-commit\n   #!/bin/bash\n   jaz . \u0026\u0026 echo \"No secrets found\" || (echo \"Secrets detected!\" \u0026\u0026 exit 1)\n   ```\n\n2. **CI/CD Pipeline**: Integrate into your build process\n   ```yaml\n   # GitHub Actions example\n   - name: Scan for secrets\n     run: |\n       cargo install jaz\n       jaz .\n   ```\n\n3. **Audit Existing Repositories**: Scan repositories you've inherited\n   ```bash\n   # Scan multiple repos\n   for repo in ~/projects/*/; do\n     echo \"Scanning $repo\"\n     jaz \"$repo\"\n   done\n   ```\n\n**Exit Codes**\n- `0`: No secrets found\n- `1`: Secrets detected or error occurred\n\n### Understanding the Output\n\nJAZ scans all git objects in the repository's object database, not just the current working directory. This means it will find secrets in:\n- All commits in the repository history\n- All branches (local and remote-tracking)\n- Staged and unstaged changes\n- Deleted files that were previously committed\n\n**Object ID Information**\nWhen JAZ finds a secret, it reports the git object ID (SHA-1 hash). You can investigate further with:\n```bash\n# View the object content\ngit show \u003cobject-id\u003e\n\n# Find which commits contain this object\ngit log --all --full-history -- $(git rev-list --all | xargs git ls-tree -r | grep \u003cobject-id\u003e | cut -f2)\n```\n\n**Common Remediation Steps**\n1. **For recent commits**: Use `git reset` or `git rebase` to remove the secret\n2. **For historical commits**: Use `git filter-branch` or `git filter-repo` to rewrite history\n3. **For shared repositories**: Coordinate with your team before rewriting history\n4. **Always**: Rotate/invalidate the exposed secret immediately\n\n### Troubleshooting\n\n**Repository Not Found**\n```\nError: Couldn't open repository\n```\n- Ensure the path points to a valid git repository\n- Check that `.git` directory exists\n- Verify you have read permissions\n\n**Permission Denied**\n```\nError: Permission denied\n```\n- Run with appropriate permissions\n- Check repository ownership and permissions\n\n**Large Repository Performance**\nFor very large repositories, JAZ may take some time to scan all objects. Consider:\n- Using `--depth=1` when cloning if you only need recent history\n- Running JAZ on a dedicated machine for large-scale scanning\n\n### Testing\n\nRun the comprehensive test suite:\n```bash\ncargo test\n```\n\nThis includes tests for all 18 secret types and various edge cases.\n\n### Results\n\nWe scanned common testing repositories for this sort of thing like [Plazmaz/leaky-repo](https://github.com/Plazmaz/leaky-repo) and [dijininja/leakyrepo](https://github.com/digininja/leakyrepo).  In general JAZ found all or most of the secrets.  In the case of dijininja/leakyrepo we found a lot of RSA private keys which is acceptable but technically is a misidentification.  For Plazmaz/leaky-repo we find the majority of the keys although once again misidentify some.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonaylor89%2Fjaz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjonaylor89%2Fjaz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjonaylor89%2Fjaz/lists"}