Deployment guide

Gitleaks

Overview

Gitleaks is a widely used open source scanner for hardcoded secrets. It reads your source code, configuration files and git commit history. It 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 recognize the credential formats of the major cloud and SaaS providers.

Gitleaks works in two complementary modes. gitleaks git walks the entire commit history of a repository, so it catches a secret that was committed once and later deleted, which 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. You can write results as JSON or SARIF for a code review, a dashboard or a pipeline gate.

This SecureAnyCloud 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. The VM can sit in a locked-down subnet with no outbound internet and still scan.

What you get:

  • Gitleaks 8.30.1 (/usr/local/bin/gitleaks), installed from the official release tarball and verified against the upstream SHA256 checksum
  • git preinstalled, so gitleaks git history scanning works immediately
  • gitleaks-scan-run and gitleaks-scan.timer, a daily scan of your projects that writes JSON and SARIF reports with latest.* 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 that detection works on your own VM
  • An appliance configuration at /etc/gitleaks/scan.conf
  • 24/7 SecureAnyCloud support

Gitleaks is a command-line product. It has no web interface, 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

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting size.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network. No inbound application ports are needed, and scanning needs no outbound internet.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Gitleaks by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22).

Select Review + create, then Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:gitleaks-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name gitleaks \
  --image sac1647283583153:gitleaks-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

There is no password and no console to sign in to, because this product has no credentials at all. The file /etc/gitleaks/credentials on the VM is an informational note that says exactly that and points to the paths below.

Step 4 - Confirm Gitleaks is installed

gitleaks version
8.30.1

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: $?"

Example output from this image. The github-pat rule detects a deliberately fake GitHub token:

Finding: GITHUB_TOKEN=<set-at-first-boot> 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 12.6ms WRN leaks found: 1 exit code: 1

Step 5 - Scan a git repository's full history

History scanning is Gitleaks' headline mode. The shipped leaky-repo fixture has a secret that was committed to history, so only a history scan finds it. Run gitleaks git, which 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: bcc1b449a6acc1e4f4e0d552aee2ebef08a11266 Author: sac-build Email: build@sac.local Date: 2026-07-19T13:21:25Z Fingerprint: bcc1b449a6acc1e4f4e0d552aee2ebef08a11266:settings.py:github-pat:2 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

Scan the clean fixture. It contains no secrets, so the scan must report nothing and exit with code 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. Use gitleaks git when you also want the full commit history of a repository checked.

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-20260719T132432Z.json lrwxrwxrwx 1 root root ... latest.sarif -> .../gitleaks-scan-20260719T132432Z.sarif

When the target contains a secret, gitleaks-scan-run exits with code 1 and the JSON report lists every finding. GitHub code scanning, Azure DevOps and most IDEs consume SARIF directly, so you can upload latest.sarif as-is.

The scan timer is enabled and armed out of the box, and so is the first-boot provisioning unit. Confirm both:

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 makes it usable as a pipeline gate:

Exit code 0: no leaks found.

Exit code 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. Used as a merge gate, gitleaks git . or gitleaks dir . 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 with gitleaks dir. Point it at your checkouts.
  • GITLEAKS_CONFIG: leave it empty to use the comprehensive embedded default ruleset. To use your own, set it to a .toml config path (see Custom rulesets).
  • REPORT_DIR and REPORT_RETENTION_DAYS: where reports are written and how many days of dated reports are kept.

After you edit the file, 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, then 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: gitleaks-scan.timer runs them daily. Run one on demand with sudo gitleaks-scan-run, and inspect history with journalctl -u gitleaks-scan.service.
  • Reports: /var/lib/gitleaks/reports/latest.json and latest.sarif always point to the most recent scan. Dated reports are pruned after REPORT_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 stays enabled, so the OS keeps receiving security updates automatically.
  • Air-gapped use: scanning requires no egress because the detection rules are built into the binary, so this VM scans fully offline.

Support

SecureAnyCloud provides 24/7 expert support for this image. Contact sales@secureanycloud.com.

Deploy on Azure

Launch Gitleaks on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure