Copied to clipboard

All posts

6 min read By Sergii Shcherbak

omerta 0.1.0: catch .env secrets leaking into git

omerta keeps your own secrets out of git, whatever their format, and finds the ones that got in. Its first release is out. What it does, what 0.1.0 has, why it matters, and how to use it.

v0.1.0

omerta is our open-source check for secrets in git. It reads the values of a project's env files and fails when one of them is in git: staged for the next commit, in a tracked file, or anywhere in the history. Its first release, 0.1.0, is out today.

This post is the short version: what omerta does, what the first release has, why it matters, and how to use it. The details are in its repository. The examples share one invented application: an agent that books repair visits for a company that services home appliances. It texts customers through an SMS gateway and keeps photos of the faults in a cloud storage bucket, and its .env has the gateway's key and the bucket's name.

What omerta does

In the project's directory, one command:

terminal
uvx omerta check --all
Copied to clipboard

It takes the values of the env files at the project's root that git does not track, .env and .env.*, and searches every tracked file for each of them: as it is written, and as it would be in a URL, in a JSON string and in base64, in text, in binary files and in file names. An env file that git tracks is a finding in itself. Without --all, omerta check searches what is staged for the next commit.

Pattern scanners, such as gitleaks and TruffleHog, look for what looks like a key: a format that one of their rules describes. omerta looks for your keys. It does not need to know what a value looks like, so it finds a small provider's key, a bucket's name or an organisation's ID as surely as a key with a well-known prefix, and it has nothing to say about a checksum that only looks like one.

The repair agent's tests recorded a call to the SMS gateway, and the recording has the gateway's key in its URL, percent-encoded. This is omerta's report on the agent's repository:

text
app/photos.py:1: BUCKET (from .env)
tests/visit.yaml:4: SMS_KEY (from .env)

Each line names the file, the line and the variable, and never the value. The check fails while anything is found, so a commit or a CI job stops there. omerta runs offline: it has no network code.

omerta's launch video, with music. An env file holds an OpenAI key and the name of a storage bucket, and the film says that your secrets live in .env. The key is pasted into the code of src/client.py, one paste away from git, and a commit would keep it in the history for good. Then omerta's name and its line, catch .env secrets leaking into git, your own values and not lookalikes. A commit runs omerta, which fails and stops it, naming OPENAI_API_KEY in src/client.py and in a test's recording and never printing the key. Strings that only look like keys fade away, and the project's own values stay, a bucket's name, a database password and an organisation's ID. Each is found in any form, as written or encoded in a URL, in JSON or in base64. omerta checks the staged changes, every tracked file and the whole history. The film ends on omerta's name, the command uvx omerta check --all and the address of its repository.

Launch video

A first release

0.1.0 brings the two checks, omerta check for the files and omerta history for every commit, tag and commit message, the four forms of each value, a pre-commit hook, and settings in .omerta.toml or in pyproject.toml. Every form of every value is searched for in one pass over each file, with Hyperscan. Its two dependencies, python-dotenv and hyperscan, see the values in cleartext, so both are pinned to exact versions: a new release of either reaches omerta's users only through a release of omerta. It runs on Python 3.11 and later. What it reads and runs, and what it never does with a value, is its security model.

Why it matters

Most secrets that leak have no format that a rule could describe. GitGuardian, which sells secret detection, counted 28.65 million new secrets in public GitHub commits in 2025, by its own detectors, and wrote in 2024 that keys from well-known providers, which often follow specific patterns, "account for less than 40% of all the secrets we uncover. This means that most leaks don't adhere to a simple, recognizable pattern".

What has no pattern is judged by its context, and context can mislead. GitHub, whose secret scanning now finds such secrets with a model of its own, explains: "Structured credentials often include a distinctive prefix, length, alphabet, or checksum. Generic secrets may not." Its model decides by where a value is ("Context is the deciding signal"), and it counts "The same password-shaped value in a test fixture" among the likely harmless lookalikes. That is a fair guess for most fixtures, and a wrong one for the repair agent's recording, which has the real key. omerta does not guess: it knows the values. It finds the values of your env files and nothing else, so a key that is in no env file is still a pattern scanner's to find, and the two are used together.

Deleting a key from git does not take it back. On 27 May 2026 a configuration file of OpenCode, a coding agent, was committed to a public repository of LiteLLM's, with the master key to a deployment of its Agent Platform in it. LiteLLM's account of what followed: "The error was quickly identified, the commit force-pushed over, and we identified the exposed keys as requiring revocation. However, key revocation did not occur for the master key." On 10 October an attacker used the key, and from it reached tokens that let them publish a compromised release of litellm to PyPI on 21 October, where it stayed for nearly two hours. In LiteLLM's words: "This incident has provided a strong illustration of the risks associated with failing to rotate a potentially exposed key."

A check before the commit keeps the values of your env files out of git. A value that is in git already has to be revoked and replaced, wherever the commit went since.

How to use it

To install it as a tool:

terminal
uv tool install omerta
Copied to clipboard

Before each commit. omerta check searches what is staged, which makes it a pre-commit hook. With pre-commit:

.pre-commit-config.yaml
repos:
  - repo: https://github.com/shcherbak-ai/omerta
    rev: v0.1.0
    hooks:
      - id: omerta

The repository has the same for Husky, Lefthook and a plain git hook.

Values that are not secrets. omerta searches for the values of the env files, secret or not, so DB_HOST=localhost is found too. A variable that holds no secret is left out:

.omerta.toml
ignore = ["DB_HOST"]

What is in the history already. Once, over the whole history:

terminal
uvx omerta history
Copied to clipboard

It reports each value at the commit where it entered a file, even where a later commit removed it. The repair agent's recording was deleted in a later commit, and omerta history still finds the key in the commit that recorded it.

In CI. CI has no .env to take values from, so there omerta finds the env files that were committed. The repository has a workflow for GitHub Actions.

Questions to ask

Whether the check is omerta, a pattern scanner or both, these questions show whether it covers your project.

  1. Which of your secrets have a format that a scanner's rules know, and which have none?
  2. Does the check run before a commit, or only once it has been pushed?
  3. Does it search the history, or only the files as they are now?
  4. Would it find a key in a test's recording, encoded in a URL?
  5. Does its report print the secret that it found?
  6. When a key is found in the history, who revokes it, and how soon?

We only publish tools we use ourselves and can recommend to others. Each reflects how we build, and omerta reflects one word of it: governed. We build AI agents to fit your enterprise, each verified, constrained, and governed.

Copied to clipboard

Check what you kept

Key in the door?

Five sheds stand beside the path, each with its key left in the door, as a value of an env file is about to go into git. Every question you get right takes a key out, and the door locks.

5 questions · 2 minutes

Question