Gitleaks on AWS User Guide
Overview
Gitleaks is the widely used open source scanner for hardcoded secrets. It reads your source code, configuration files and git commit history and reports every hardcoded API key, cloud access key, token, password and private key it finds, using an embedded ruleset of more than 160 detection rules that recognise the credential formats of the major cloud and SaaS providers.
It works in two complementary modes. gitleaks git walks the entire commit history of a repository, so a secret that was committed once and later deleted is still caught - the exact case a working-tree scan misses. gitleaks dir scans plain files and working trees. Every finding names the rule, the file, the line and the offending value, and results can be written as JSON or SARIF for a code review, a dashboard or a pipeline gate.
The cloudimg image is a ready-to-run secret-scanning host, not just the binary. The detection rules are compiled into the scanner, so it needs no network egress at all - this instance can sit in a locked-down subnet with no outbound internet and still scan. git is preinstalled so history scanning works out of the box, a daily timer scans a directory you choose and writes machine-readable JSON and SARIF reports, and read-only self-test fixtures let you prove detection works on your own instance. Backed by 24/7 cloudimg support.
What is included:
- Gitleaks 8.30.1 (
/usr/local/bin/gitleaks), installed from the official release tarball and verified against the upstream SHA256 checksum gitpreinstalled, sogitleaks githistory scanning works immediatelygitleaks-scan-run+gitleaks-scan.timer- a daily scan of your projects, writing JSON + SARIF withlatest.*symlinks for CI pickup- Read-only self-test fixtures under
/usr/share/gitleaks/fixtures(a leaky directory, a leaky git repo and a clean directory) so you can prove the scanner works on your own instance - An appliance configuration at
/etc/gitleaks/scan.conf - 24/7 cloudimg support
This is a command-line product: no web UI, no listening service, no admin account and no password. SSH on port 22 is the only open port, and the SSH key you choose at launch is the only way in.
Prerequisites
- An AWS account with permission to launch EC2 instances
- An EC2 key pair for SSH access
- A security group that allows inbound
22/tcpfrom your management network. No inbound application ports are needed, and no outbound internet is needed for scanning.
m5.large (2 vCPU / 8 GiB RAM) is a comfortable default; scanning very large monorepos or deep histories benefits from more CPU and RAM.
Step 1 - Launch from the AWS Marketplace
Open the product in the AWS Marketplace, choose Continue to Subscribe, accept the terms, then Continue to Configuration and Continue to Launch. Pick your region, instance type, key pair and a security group that allows SSH (22) from your management network, then launch.
Step 2 - Launch from the AWS CLI
aws ec2 run-instances \
--image-id <ami-id-for-your-region> \
--instance-type m5.large \
--key-name <your-key-pair> \
--security-group-ids <sg-allowing-ssh> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=gitleaks}]'
Step 3 - Connect to your instance
Connect over SSH as the login user for your operating system variant:
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 LTS | ubuntu |
ssh ubuntu@<instance-public-ip>
There is no password and no console to log in to - this product has no credentials at all. /etc/gitleaks/credentials on the instance is an informational note that says exactly that, and points at the paths below.
Step 4 - Confirm Gitleaks is installed and scan a directory
gitleaks version
8.30.1
Now scan the shipped leaky self-test fixture as a directory. The -v flag prints the detail of each finding:
gitleaks dir -v --no-banner /usr/share/gitleaks/fixtures/leaky
echo "exit code: $?"
Real output from this image - a deliberately fake GitHub token is detected by the github-pat rule:
Finding: GITHUB_TOKEN=ghp_R8vqZ2mN4pK7wX1yT6bJc3hFdA9sLe5uGoQ0
Secret: ghp_R8vqZ2mN4pK7wX1yT6bJc3hFdA9sLe5uGoQ0
RuleID: github-pat
Entropy: 5.221928
File: /usr/share/gitleaks/fixtures/leaky/config.env
Line: 2
Fingerprint: /usr/share/gitleaks/fixtures/leaky/config.env:github-pat:2
INF scanned ~182 bytes (182 bytes) in 13.3ms
WRN leaks found: 1
exit code: 1

Step 5 - Scan a git repository's full history
This is Gitleaks' headline mode. The shipped leaky-repo fixture has a secret that was committed to history, so only a history scan finds it. gitleaks git walks every commit:
gitleaks git -v --no-banner /usr/share/gitleaks/fixtures/leaky-repo
echo "exit code: $?"
The finding names the commit, author and date, not just the file:
Finding: GITHUB_TOKEN = "ghp_R8vqZ2mN4pK7wX1yT6bJc3hFdA9sLe5uGoQ0
Secret: ghp_R8vqZ2mN4pK7wX1yT6bJc3hFdA9sLe5uGoQ0
RuleID: github-pat
File: settings.py
Line: 2
Commit: 64d1ddb858fee16cdd3a42b2f7b23494403e5742
Author: cloudimg-build
Date: 2026-07-21T11:05:43Z
INF 1 commits scanned.
WRN leaks found: 1
exit code: 1

To scan one of your own repositories, point gitleaks git at its path:
gitleaks git -v /path/to/your/repo
Step 6 - Confirm a clean scan reports nothing
The clean fixture contains no secrets and must report nothing (exit 0):
gitleaks dir --no-banner /usr/share/gitleaks/fixtures/clean
echo "exit code: $?"
INF scanned ~165 bytes (165 bytes) in 2.6ms
INF no leaks found
exit code: 0
Step 7 - Scan your own projects
Put your checkouts under /srv/projects (the default scan target) or point the configuration at wherever they already live, then scan the tree as files:
gitleaks dir -v /srv/projects
Use gitleaks dir for a working tree or plain files, and gitleaks git when you want the full commit history of a repository checked as well.
Step 8 - Scheduled scans and machine-readable reports
gitleaks-scan-run is the scheduled entry point. It reads /etc/gitleaks/scan.conf, scans SCAN_TARGET, and writes both a JSON and a SARIF report with latest.* symlinks. Run it once by hand against the clean fixture to see the reports appear:
sudo gitleaks-scan-run /usr/share/gitleaks/fixtures/clean
ls -l /var/lib/gitleaks/reports/latest.json /var/lib/gitleaks/reports/latest.sarif
[gitleaks-scan-run] scanning /usr/share/gitleaks/fixtures/clean for hardcoded secrets
INF no leaks found
[gitleaks-scan-run] no leaks found
[gitleaks-scan-run] reports: ... (latest.json / latest.sarif updated)
lrwxrwxrwx 1 root root ... latest.json -> .../gitleaks-scan-20260721T110650Z.json
lrwxrwxrwx 1 root root ... latest.sarif -> .../gitleaks-scan-20260721T110650Z.sarif
When the target contains a secret, gitleaks-scan-run exits 1 and the JSON report lists every finding. SARIF is the format GitHub code scanning, AWS CodeCatalyst, Azure DevOps and most IDEs consume directly, so latest.sarif can be uploaded as-is.

The scan timer is enabled and armed out of the box, and so is the first-boot provisioning unit:
systemctl is-enabled gitleaks-scan.timer gitleaks-firstboot.service
enabled
enabled
Step 9 - The exit-code contract (CI integration)
gitleaks follows a simple, documented exit-code contract, which is what makes it usable as a pipeline gate:
| Exit code | Meaning |
|---|---|
0 |
No leaks found |
1 |
Leaks found |
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: 1
A non-zero exit fails a CI job automatically, so gitleaks git . or gitleaks dir . as a merge gate blocks any change that introduces a secret.
Configuration
The scheduled scan reads /etc/gitleaks/scan.conf:
grep -v '^#' /etc/gitleaks/scan.conf | grep .
SCAN_TARGET="/srv/projects"
REPORT_DIR="/var/lib/gitleaks/reports"
GITLEAKS_CONFIG=""
REPORT_RETENTION_DAYS=30
SCAN_TARGET- the directory the daily scan walks (scanned as files withgitleaks dir). Point it at your checkouts.GITLEAKS_CONFIG- leave empty to use Gitleaks' comprehensive embedded default ruleset. To use your own, set it to a.tomlconfig path (see below).REPORT_DIR/REPORT_RETENTION_DAYS- where reports are written and how many days of dated reports are kept.
After editing, restart the timer:
sudo systemctl restart gitleaks-scan.timer
Custom rulesets
Gitleaks ships a comprehensive default ruleset compiled into the binary, so most users need no configuration. To add your own rules or allowlists, write a .toml config that extends the default and point the appliance at it:
sudo gitleaks generate config > /etc/gitleaks/gitleaks.toml # start from a template, then edit
sudo sed -i 's#^GITLEAKS_CONFIG=.*#GITLEAKS_CONFIG="/etc/gitleaks/gitleaks.toml"#' /etc/gitleaks/scan.conf
sudo systemctl restart gitleaks-scan.timer
You can also pass --config <path> to any manual gitleaks dir or gitleaks git run.
Maintenance
- Scans: run daily by
gitleaks-scan.timer; run one on demand withsudo gitleaks-scan-run. Inspect history withjournalctl -u gitleaks-scan.service. - Reports:
/var/lib/gitleaks/reports/latest.jsonandlatest.sarifalways point at the most recent scan; dated reports are pruned afterREPORT_RETENTION_DAYS. - Upgrades: download a newer release tarball from the Gitleaks releases, verify it against the published
checksums.txt, and replace/usr/local/bin/gitleaks. - Security patches: unattended-upgrades remains enabled, so the OS continues to receive security updates automatically.
- Air-gapped use: nothing about scanning requires egress - the detection rules are built into the binary, so this instance scans fully offline.
Support
cloudimg provides 24/7 expert support for this image. Contact support@cloudimg.co.uk.