Gitleaks 8.30.1
Overview
Gitleaks is a widely used open-source scanner for hardcoded secrets. It reads source code, configuration files and git commit history, and reports every API key, cloud access key, token, password and private key it recognises. Its ruleset is compiled into the scanner.
Gitleaks works in two modes. gitleaks git walks the whole commit history of a repository, so a secret that was committed once and later deleted is still found. gitleaks dir scans plain files and working trees. Results can be written as JSON or SARIF for a pipeline gate, a code review or a dashboard.
This guide covers the Gitleaks 8.30.1 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one software version of the SecureAnyCloud OWASP ZAP and Vulnerability Scanners listing on AWS Marketplace, which you select when you subscribe and launch.
What you get:
- A scheduled scan that cannot phone home. A daily timer scans a directory you choose. The scan runs as its own unprivileged
gitleaksuser inside a systemd sandbox with no network access at all. Every address is denied, including the EC2 instance metadata service. The operating system is read-only to the scan, and it holds no capabilities. Gitleaks fetches nothing remote, because its detection rules are built into the binary, so the instance can scan in a subnet with no outbound internet. - Reports only root can read, with secrets redacted. A report lists the secrets it found. The scheduled scan therefore writes its JSON and SARIF reports with mode
0600into/var/lib/gitleaks/reports(mode0700, owned bygitleaks). Ordinary users cannot read or even list them. Secret values are replaced withREDACTEDby default, and findings keep the rule, file, line and commit. - Self-test fixtures unique to your instance. On first boot, the instance generates its own fake, non-functional GitHub token and AWS access key ID. It builds three small fixtures from them: a leaky directory, a leaky git repository and a clean directory. You can use them to prove that detection works on your own instance. No secret-shaped string is baked into the image.
- A patched build of the scanner. SecureAnyCloud compiles the binary from the official Gitleaks v8.30.1 source with Go 1.26.10 and updated golang.org/x/crypto, golang.org/x/text and klauspost/compress modules. This clears 67 of the 69 Go security advisories that govulncheck reports against the upstream release binary. The build provenance ships on the instance.
- Key-only SSH (no password or keyboard-interactive login, no root login), IMDSv2 only, and a fully patched Ubuntu 24.04 LTS with unattended security upgrades switched on.
- Instance defaults: default user
ubuntu, x86_64 architecture, recommended instance type m5.large.
Gitleaks is a command-line product. There is no web UI, no listening service, no account and no password. SSH on port 22 is the only open port.
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet. Scanning needs no outbound internet access. You only need a way to get your code onto the instance, for example
git cloneover a NAT gateway or a VPC endpoint. - A security group that allows TCP 22 (SSH) from your own networks only. No other inbound port is needed.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Gitleaks 8.30.1 on Ubuntu 24.04 as the software version and select your Region. Choose Launch through EC2, then select m5.large, your key pair and a security group as described above. Size the root volume for the code you will scan.
To launch with the AWS CLI instead, replace the values in angle brackets:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <sg-allowing-22-from-your-network> --subnet-id <subnet-id> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=gitleaks}]'Connect to your instance
Connect over SSH. The SSH user on Ubuntu 24.04 is ubuntu.
ssh -i <your-key.pem> ubuntu@<instance-public-ip>There is no password to look up. The file /etc/gitleaks/credentials is an informational note that says so and lists the paths used in this guide.
Check the installation
Confirm the Gitleaks version and that the scan timer and first-boot service are enabled:
gitleaks version systemctl is-enabled gitleaks-scan.timer gitleaks-firstboot.service systemctl is-active gitleaks-scan.timer8.30.1 enabled enabled activegitleaks-firstboot.service ran once on the first boot of your instance. It generated the self-test fixtures and queued a baseline scan. gitleaks-scan.timer runs the scheduled scan once a day.
Prove detection with the self-test fixtures
Scan the leaky fixture as a directory. The --redact flag keeps the secret values out of your terminal:
gitleaks dir --no-banner --redact /usr/share/gitleaks/fixtures/leaky; echo "exit code: $?"6:13AM INF scanned ~176 bytes (176 bytes) in 14.2ms 6:13AM WRN leaks found: 2 exit code: 1To see what was found, write a JSON report, then list the rule, file and line of each finding:
R=$(mktemp) gitleaks dir --no-banner --redact --log-level error --report-format json --report-path "$R" /usr/share/gitleaks/fixtures/leaky jq -r '.[] | "\(.RuleID) \(.File):\(.StartLine) value: \(.Secret)"' "$R" rm -f "$R"aws-access-token /usr/share/gitleaks/fixtures/leaky/config.env:3 value: REDACTED github-pat /usr/share/gitleaks/fixtures/leaky/config.env:2 value: REDACTEDBoth values in that file are fake. They were generated for your instance alone and are not credentials for anything.
Scan a repository's full git history
The leaky-repo fixture has a token committed to history, which only a history scan can find. Run gitleaks git to walk every commit:
gitleaks git --no-banner --redact /usr/share/gitleaks/fixtures/leaky-repo; echo "exit code: $?"6:13AM INF 1 commits scanned. 6:13AM INF scanned ~149 bytes (149 bytes) in 307ms 6:13AM WRN leaks found: 1 exit code: 1A history finding names the commit, the author and the date, as well as the file:
R=$(mktemp) gitleaks git --no-banner --redact --log-level error --report-format json --report-path "$R" /usr/share/gitleaks/fixtures/leaky-repo jq -r '.[] | "\(.RuleID) \(.File):\(.StartLine) commit \(.Commit[0:12]) \(.Author) \(.Date)"' "$R" rm -f "$R"github-pat settings.py:2 commit b460ca0f76cb sac self-test 2026-10-20T06:09:49ZTo scan one of your own repositories, point gitleaks git at its path:
gitleaks git --redact /path/to/your/repoConfirm a clean scan reports nothing
Scan the clean fixture. Gitleaks should report no leaks and exit with code 0:
gitleaks dir --no-banner /usr/share/gitleaks/fixtures/clean; echo "exit code: $?"6:13AM INF scanned ~165 bytes (165 bytes) in 3.96ms 6:13AM INF no leaks found exit code: 0The scheduled scan and its reports
The scheduled scan reads /etc/gitleaks/scan.conf and scans SCAN_TARGET (default /srv/projects) with gitleaks dir. It writes a JSON report and a SARIF report, plus latest.json and latest.sarif links. Run a scan now and read its log:
sudo systemctl start gitleaks-scan.service
sudo journalctl -u gitleaks-scan.service -n 8 --no-pager -o catgitleaks-scan-run: scanning /srv/projects for hardcoded secrets (redaction 100%) 6:13AM INF scanned ~0 bytes (0) in 3.51ms 6:13AM INF no leaks found gitleaks-scan-run: no leaks found gitleaks-scan-run: reports: /var/lib/gitleaks/reports/gitleaks-scan-20261020T061345Z.json | /var/lib/gitleaks/reports/gitleaks-scan-20261020T061345Z.sarif (latest.json / latest.sarif updated) gitleaks-scan.service: Deactivated successfully. Finished gitleaks-scan.service - Scheduled Gitleaks secret scan of SCAN_TARGET (sac). gitleaks-scan.service: Consumed 1.649s CPU time.The reports belong to the gitleaks user, and only root can read them:
sudo ls -l /var/lib/gitleaks/reports/-rw------- 1 gitleaks gitleaks 3 Oct 20 06:13 gitleaks-scan-20261020T061345Z.json -rw------- 1 gitleaks gitleaks 48983 Oct 20 06:13 gitleaks-scan-20261020T061345Z.sarif lrwxrwxrwx 1 gitleaks gitleaks 35 Oct 20 06:13 latest.json -> gitleaks-scan-20261020T061345Z.json lrwxrwxrwx 1 gitleaks gitleaks 36 Oct 20 06:13 latest.sarif -> gitleaks-scan-20261020T061345Z.sarifAs the ubuntu user without sudo, the directory is closed to you:
$ ls /var/lib/gitleaks/reports ls: cannot access '/var/lib/gitleaks/reports': Permission deniedRead a report with sudo. The file latest.json is a JSON array of findings, empty when nothing was found. The file latest.sarif is SARIF 2.1.0, which GitHub code scanning, GitLab and most IDEs import directly.
sudo jq length /var/lib/gitleaks/reports/latest.json
sudo jq '.runs[0].tool.driver.name' /var/lib/gitleaks/reports/latest.sarif0 "gitleaks"The scan exits 1 when it finds leaks. systemd treats that as a normal result, and the journal line LEAKS FOUND - see <report> tells you which report to open.
To collect reports on another system, copy them off as root, for example with sudo cp into a directory you control. Decide there whether they may leave the instance.
Scan your own code
Put your checkouts under /srv/projects, or point SCAN_TARGET at where they already live. The scheduled scan runs as the gitleaks user, so that user must be able to read everything it scans: files 0644 and directories 0755, or group gitleaks.
If the scan cannot read some entries, it logs a WARNING with their number. It does not report "no leaks" for them.
cd /srv/projects
sudo git clone https://github.com/<your-org>/<your-repo>.git
sudo systemctl start gitleaks-scan.service
sudo jq -r '.[] | "\(.RuleID) \(.File):\(.StartLine)"' /var/lib/gitleaks/reports/latest.jsonFor a one-off scan of something else, run Gitleaks directly as your own user. For example, run gitleaks git --redact ~/work/repo or gitleaks dir --redact ~/work/tree.
Use the exit code in CI
Gitleaks exits 0 when it finds nothing and 1 when it finds leaks. This makes it usable as a merge gate:
gitleaks dir --no-banner /usr/share/gitleaks/fixtures/clean >/dev/null 2>&1; echo "clean fixture exit: $?" gitleaks dir --no-banner /usr/share/gitleaks/fixtures/leaky >/dev/null 2>&1; echo "leaky fixture exit: $?"clean fixture exit: 0 leaky fixture exit: 1Exit codes:
- 0: no leaks found
- 1: leaks found
- Any other value: the scan did not complete
Review what the scan can reach
The scheduled scan's sandbox is defined in its systemd unit. Show the relevant settings with:
systemctl show -p User -p IPAddressDeny -p ProtectSystem -p ProtectHome -p NoNewPrivileges -p CapabilityBoundingSet gitleaks-scan.serviceIPAddressDeny=::/0 0.0.0.0/0 CapabilityBoundingSet= User=gitleaks ProtectHome=read-only ProtectSystem=strict NoNewPrivileges=yesIPAddressDeny=::/0 0.0.0.0/0 is how systemd reports the unit's two deny rules: the instance metadata service (169.254.169.254) and every other address. The scan cannot open any network connection, so a malicious file in a scanned repository cannot use it to reach the instance metadata service or anything else. The first-boot unit carries the same rules.
The only path the scan may write to is /var/lib/gitleaks, so keep REPORT_DIR under it. Gitleaks needs no network for scanning. Only your own git clone or git pull, run as your own user, does.
Configure the scan
The scan reads its settings from /etc/gitleaks/scan.conf. Print the active values with:
grep -v '^#' /etc/gitleaks/scan.conf | grep .SCAN_TARGET="/srv/projects" REPORT_DIR="/var/lib/gitleaks/reports" REDACT_PERCENT=100 GITLEAKS_CONFIG="" REPORT_RETENTION_DAYS=30SCAN_TARGET: the directory the daily scan walks withgitleaks dir.REPORT_DIRandREPORT_RETENTION_DAYS: where reports go (keep it under/var/lib/gitleaks) and how many days of dated reports are kept.REDACT_PERCENT: how much of each secret value is replaced in reports and logs. The default,100, replaces all of it. Set0only if a downstream tool needs the raw value, because the reports then hold live secrets.GITLEAKS_CONFIG: when empty, the ruleset built into Gitleaks is used. Set it to a.tomlfile readable by thegitleaksuser to use your own rules.
The file is read at the start of every scan, so a change takes effect on the next scan. Edit it with sudo nano /etc/gitleaks/scan.conf. To change the schedule, add a drop-in with sudo systemctl edit gitleaks-scan.timer, for example OnCalendar=hourly.
Custom rules. This config keeps the default ruleset and adds one rule of your own:
# /etc/gitleaks/gitleaks.toml (mode 0644) [extend] useDefault = true [[rules]] id = "example-corp-api-key" description = "Example Corp internal API key" regex = '''excorp_[a-z0-9]{32}''' keywords = ["excorp_"]Then set GITLEAKS_CONFIG="/etc/gitleaks/gitleaks.toml" in scan.conf. You can also pass --config <path> to any gitleaks dir or gitleaks git run.
Read the scanner build provenance
Print the build provenance record that ships on the instance:
cat /usr/share/gitleaks/build-provenance/BUILD-PROVENANCE.txtGitleaks 8.30.1 on this image was compiled by sac from the unmodified upstream source at https://github.com/gitleaks/gitleaks.git commit 83d9cd684c87d95d656c1458ef04895a7f1cbd8e (tag v8.30.1), with the module bumps below to clear Go security advisories. Licence: MIT (/usr/share/gitleaks/LICENSE.upstream). Copyright (c) 2019 Zachary Rice. toolchain go1.26.10 linux/amd64, https://go.dev/dl/go1.26.10.linux-amd64.tar.gz sha256 ccfe7ae822d2c2f41f4fe7c956199967a4dac22d0ee0d2b2bfdb440aab3b20c5 modules go get golang.org/x/crypto@v0.57.0 golang.org/x/text@v0.42.0 github.com/klauspost/compress@v1.18.7 (module proxy + sum.golang.org); minimum version selection also raised x/sync v0.23.0, x/sys v0.48.0 and the go directive to 1.26.0 -- exactly the lines in go.mod.diff, guarded at build flags CGO_ENABLED=0 go build -trimpath -tags gore2regex -ldflags "-s -w -X=github.com/zricethezav/gitleaks/v8/version.Version=8.30.1" govulncheck v1.9.0 -mode=binary on the compiled binary: GO-2025-4020 GO-2026-5932 (GO-2026-5932 = golang.org/x/crypto/openpgp, no fixed version exists; GO-2025-4020 = rardecode RAR DoS, reachable only with --max-archive-depth > 0) upstream release binary gitleaks_8.30.1_linux_x64.tar.gz sha256 551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb (go1.24.11; 69 govulncheck advisories; not shipped)The two remaining advisories do not affect default use. No fixed version of golang.org/x/crypto/openpgp exists, and the RAR advisory applies only to archive scanning, which is off unless you pass --max-archive-depth. If you enable archive scanning, scan only archives you trust.
The same directory holds the module list compiled into the binary (buildinfo.txt), the exact go.mod change (go.mod.diff) and the full govulncheck report.
Verify SSH access settings
Confirm that SSH is key-only and that root login is disabled:
sudo sshd -T | grep -E '^(passwordauthentication|kbdinteractiveauthentication|permitrootlogin|pubkeyauthentication) 'permitrootlogin no pubkeyauthentication yes passwordauthentication no kbdinteractiveauthentication noSSH accepts only the key pair you chose at launch (/etc/ssh/sshd_config.d/10-sac-key-only.conf). No account on the image has a password, and nothing else listens on a public address.
Components
Use this list to find the main parts of the installation:
- Gitleaks binary: /usr/local/bin/gitleaks
- Scheduled scan runner: /usr/local/bin/gitleaks-scan-run
- Scan unit and timer: /etc/systemd/system/gitleaks-scan.service, /etc/systemd/system/gitleaks-scan.timer
- Configuration: /etc/gitleaks/scan.conf
- Reports: /var/lib/gitleaks/reports (owned by gitleaks, mode 0700)
- Self-test fixtures: /usr/share/gitleaks/fixtures (regenerate with sudo /usr/local/sbin/gitleaks-selftest-fixtures)
- First-boot script: /usr/local/sbin/gitleaks-firstboot.sh
- Build provenance and licence: /usr/share/gitleaks/build-provenance/, /usr/share/gitleaks/LICENSE.upstream
- Key-only SSH drop-in: /etc/ssh/sshd_config.d/10-sac-key-only.conf
Security recommendations
- Allow port 22 in the security group from your own networks only.
- Keep
REDACT_PERCENT=100unless a tool genuinely needs the raw values. Treat every report as sensitive either way, because it says where your secrets are. - Rotate any real secret Gitleaks finds. Removing it from the latest commit is not enough while it is still in the git history.
- Keep the operating system patched. Unattended security upgrades are on, and
sudo apt-get update && sudo apt-get upgradeapplies everything else. New Gitleaks releases arrive as new versions of this listing.
Support and licensing
Gitleaks is open source under the MIT licence (Copyright (c) 2019 Zachary Rice). A copy is at /usr/share/gitleaks/LICENSE.upstream. There is no per-user or per-CPU licence fee. The AMI price covers SecureAnyCloud's hardening, first-boot setup and support.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24 hour response SLA
Deploy on AWS
Launch Gitleaks 8.30.1 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com