Skip to content

Configuration ​

l0-git can be configured via a .l0git.json file in the project root. This file allows you to ignore specific gates, override their severity, and pass gate-specific options.

Schema ​

The configuration file is a JSON object with three primary top-level fields:

FieldTypeDescription
ignorestring[]List of gate IDs to skip entirely.
severityRecord<string, string>Override the default severity for specific gates (error, warning, info).
gate_optionsRecord<string, object>Per-gate options (e.g., exclude_paths, threshold_mb).

Example ​

json
{
  "ignore": ["changelog_present", "pr_template_present"],
  "severity": {
    "readme_present": "info",
    "secrets_scan": "warning"
  },
  "gate_options": {
    "large_file_tracked": { 
      "threshold_mb": 10, 
      "exclude_paths": ["dist/**"] 
    },
    "secrets_scan": { 
      "exclude_paths": ["test/fixtures/**"] 
    },
    "secrets_scan_history": { 
      "enabled": true, 
      "max_blobs": 10000 
    }
  }
}

Inline Overrides ​

For language-specific gates (Dockerfile, Compose, HTML, Markdown, CSS), you can use inline comments to ignore a rule for a specific line or block.

Dockerfile ​

dockerfile
# l0git: ignore from_latest reason: dev base image
FROM node:latest

Docker Compose ​

yaml
services:
  proxy:
    image: traefik:v3
    # l0git: ignore docker_socket_mount reason: required for routing
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

HTML ​

html
<!-- l0git: ignore viewport_no_zoom reason: legacy app requirement -->
<meta name="viewport" content="width=device-width, user-scalable=no">

Markdown ​

markdown
<!-- l0git: ignore image_no_alt reason: decorative image -->
![](./logo.png)

CSS ​

css
/* l0git: ignore thin_font_weight reason: brand identity */
body {
  font-weight: 100;
}

Scan options ​

Every gate that reads file contents accepts the same three options, on top of its own. They exist because a scanner that cannot be told where not to look becomes noise, and noise gets switched off entirely.

OptionDefaultWhat it does
exclude_paths[]Glob patterns (filepath.Match semantics) matched against the path relative to the project root. A match is skipped before the file is read.
skip_default_fixture_pathstrueSkip well-known test and fixture locations.
skip_default_data_filestrueSkip tabular and line-oriented data files.

Why fixtures are skipped by default ​

Test fixtures legitimately contain mock secrets, fake IP addresses and placeholder URLs: that is what makes them fixtures. Scanning them produces findings that are correct about the bytes and wrong about the meaning.

Covered: *_test.go, test_*.py / *_test.py, *.test.{ts,tsx,js,jsx}, *.spec.{ts,tsx,js,jsx}, *_test.rs, *Test.{java,kt}, *_spec.rb, *_test.rb, conftest.py, plus any path traversing test/, tests/, __tests__/, spec/, testdata/, fixtures/ or __fixtures__/.

Set it to false to scan them anyway:

json
{
  "gate_options": {
    "secrets_scan": { "skip_default_fixture_paths": false }
  }
}

Why data files are skipped by default ​

In a .csv of network ranges or a .jsonl of records, the addresses and keys are the payload of the file, not literals embedded in source. Covered: .csv, .tsv, .jsonl, .ndjson, .parquet, .arrow, .feather.

This applies to content-scanning gates only. Metadata gates, large_file_tracked, vendored_dir_tracked and friends, still see these files, because for them the size and the path are the point.

Some gates additionally detect address lists by content: network_scan treats a .txt whose lines are overwhelmingly bare IP or CIDR literals as a data file and gates that on this same flag.

Where the config is read from ​

.l0git.json is read from the project root you pass to lgit check. There is no user-level or global config file, and no merging: one project, one file.

An unparseable .l0git.json is itself reported, by the config parse error gate.

A typo is reported, not absorbed ​

Every key is validated: the top-level fields, and each gate_options sub-tree against the gate that owns it. Unknown keys and wrong types are both rejected:

json
{ "gate_options": { "large_file_tracked": { "treshold_mb": 20 } } }
text
warning: gate_options.large_file_tracked: json: unknown field "treshold_mb"

The warning goes to stderr, and the same text appears in the config_error field of lgit check's JSON. This matters because the failure it replaces was invisible: a mistyped option key used to be discarded and the gate ran on its defaults, so "threshold_mb": "20" quietly stayed 5 and "exclude_path" excluded nothing, with no error, no warning, and exit 0.

A bad key discards more than itself

A problem in the top level (ignore, severity, gate_options) means the whole file fails to parse, so none of your configuration applies, not just the offending key. A problem inside one gate_options sub-tree is contained: only that gate falls back to its defaults.

Either way the run continues and the exit code stays 0. A broken config should not take a whole CI job with it, but it should never be silent, so check stderr, or config_error, if a setting seems not to be taking effect.

Released under the MIT License. · Privacy & legal