Skip to main content
relic guard stops secrets from reaching your git history. It runs two checks:
  • Dotenv files: flags committed or staged .env, .env.local, .env.production, *.env, and .dev.vars files.
  • Relic values: decrypts your linked project’s secrets on your device and searches for exact occurrences of their values in the content being committed.
Matching happens locally. File contents are never sent anywhere, and findings show only the secret’s key name, the file, the line, and a masked preview such as sk********.

Quick Start

1

Link your project

Run relic init at the repository root so the guard knows which project’s secrets to match. Without relic.toml, only the dotenv check runs.
2

Install the pre-commit hook

Every git commit now runs relic guard scan --staged and is blocked when it finds a leak.
3

Scan the existing tree

Scanning

Without --staged or --range, the guard scans the given paths (default: the current directory). Inside a git repository it scans tracked files plus untracked files that aren’t gitignored, so a gitignored local .env is not reported. Examples:

Exit Codes

Output

With --json, each finding includes type (dotenv or value), file, and for value findings line, column, secrets (key and environment), and preview. Range scans add the commit SHA.

Value Matching

The guard decrypts secrets the same way relic run does, then builds an Aho-Corasick automaton over all values and scans every file in a single pass. Decrypted values stay in memory for the duration of the scan and are never written to disk. To avoid noise, it skips values that:
  • are shorter than the minimum length (default 8)
  • are booleans, numbers, or common literals like production
  • point at local hosts, such as http://localhost:3000 or postgres://user:[email protected]/db
  • repeat a single character

When Values Can’t Be Loaded

If you’re logged out, offline, or the repository has no relic.toml, the dotenv check still runs and the output says that value matching was skipped. The commit is not blocked for that reason. Pass --require-values to fail instead, which is useful in CI. Value loading times out after 20 seconds so a slow network can’t hang your commit.

Authentication

Service account exports are rate limited to 6 requests per minute with a burst of 3. Each -e flag costs one request, so pass at most three environments per CI run.

Ignoring Findings

Add a relic-guard-ignore comment anywhere on a line to skip value findings on that line:
To skip whole files or directories, create a .relicguardignore file at the repository root. It uses gitignore syntax:

Configuration

Add a [guard] section to relic.toml:
.env.example, .env.sample, and .env.template (and names like .env.local.example) are always allowed.

Pre-commit Hooks

relic guard install writes .git/hooks/pre-commit. If a pre-commit hook already exists, it’s moved to pre-commit.pre-relic and still runs first. relic guard uninstall restores it. If the repository uses a hook manager, the guard prints the snippet to add instead of writing hooks:
lefthook.yml
For lefthook, relic guard install offers to add this for you. Pass --yes to skip the prompt.
The installed hook skips the scan with a warning when relic isn’t on your PATH, so teammates without Relic can still commit.

CI

Scan every commit in a pull request so a secret that was added and later removed is still caught. Use a service account for value matching.
.github/workflows/leak-guard.yml
fetch-depth: 0 is required. A shallow clone doesn’t contain the base branch, so the range can’t be resolved.
Pull requests from forks don’t receive repository secrets. Drop --require-values if you accept fork contributions; the dotenv check still runs for them.
Last modified on October 12, 2026