# xgrep

A fast, Semgrep-compatible code scanner written in Go — unified **SAST**, **secret
scanning**, and **software composition analysis (SCA)** in one binary.

xgrep scans codebases using Semgrep YAML rule syntax and tree-sitter for language-aware,
AST-based pattern matching. It optimizes for **accuracy** — when it reports a
vulnerability, it should be real and exploitable — and adds code-intelligence and
AI-agent features on top of scanning. See the
[design goals](docs/01-getting-started/index.md#design-goals).

## Installation

Install xgrep from the [`@mondoohq/xgrep`](https://www.npmjs.com/package/@mondoohq/xgrep)
npm package, which ships prebuilt binaries:

```bash
# Run it straight from npx (no install)
npx @mondoohq/xgrep scan .

# Or add the `xgrep` command to your PATH
npm install -g @mondoohq/xgrep
xgrep scan .
```

> Prebuilt binaries are available for Linux and Windows (amd64 and arm64).
> A Homebrew formula for macOS is coming soon.

### Verifying a release

Each [GitHub release](https://github.com/mondoohq/xgrep/releases) ships a
`checksums.txt` (SHA-256 of every archive, package, **and** the SBOM) signed with
[cosign](https://github.com/sigstore/cosign) keyless (Sigstore), a CycloneDX
**SBOM** (`xgrep_<version>.cyclonedx.sbom.json`), and per-artifact
[SLSA build provenance](https://slsa.dev). To verify (adjust the version):

```sh
# 1. Checksums signature — the cosign cert's identity is xgrep's release
#    workflow, so a valid signature proves CI produced this checksums.txt:
cosign verify-blob \
  --certificate checksums.txt.pem --signature checksums.txt.sig \
  --certificate-identity-regexp '^https://github.com/mondoohq/xgrep' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  checksums.txt

# 2. Confirm your artifact (and the SBOM) match the signed checksums:
sha256sum -c checksums.txt --ignore-missing

# 3. Per-artifact build provenance (authenticates an individual binary, which the
#    checksum signature only covers transitively):
gh attestation verify xgrep_<version>_linux_amd64.tar.gz --repo mondoohq/xgrep
```

## Quick start

xgrep ships with a built-in rule corpus, so no rules file is needed to get started:

![Scanning a Flask app with xgrep — a tainted HTTP parameter reaching a shell command is reported as a command-injection finding](docs/assets/scan.gif)

```bash
# Scan the current directory with the built-in rules (runs the security and secrets rules)
xgrep scan .

# Choose a category (default: security,secrets)
xgrep scan --category correctness .

# High-signal, exploitable-only: drop hardening/advisory findings and non-source
# trees (tests, benchmarks, examples). Recommended for embedding or scanning a
# focused surface such as an AI-agent skill.
xgrep scan --category security --subcategory vuln --xgrepignore .
```

```bash
# Machine-readable output
xgrep scan --json .
xgrep scan --sarif .                          # GitHub Code Scanning
xgrep scan --gitlab -o gl-sast-report.json .  # GitLab SAST

# Bring your own rules: point -f at a rule file or a directory of rules
xgrep scan -f rules.yaml src/
```

A scan target can also be a **remote git repository** — xgrep clones it (shallow,
default branch) into a temp directory and scans it, no manual clone needed:

```bash
xgrep scan github.com/expressjs/express            # host/owner/repo shorthand
xgrep scan https://github.com/expressjs/express    # or a full HTTPS/SSH URL
xgrep scan github.com/expressjs/express --ref 4.18.2   # a branch, tag, or commit
```

See the [remote-repository section](docs/02-code-scanning/cli-reference.md#scanning-a-remote-repository)
for `--ref`, `--depth`, and `--full-clone`.

## Secrets scanning

Secrets scanning is **on by default** — every `xgrep scan` also looks for committed
credentials. xgrep ships **270+ detectors across 150+ providers** (cloud keys,
source-forge and CI tokens, payment/AI/messaging credentials, PEM private keys),
tuned for precision so well-known example values are filtered out.

![xgrep reporting a committed GitHub token and Stripe key, each with revoke-and-rotate remediation guidance](docs/assets/secrets.gif)

```bash
xgrep scan --category secrets .                  # scan the working tree for secrets only
xgrep --history --category secrets .             # walk the full git history — catches secrets
                                                 # committed and later deleted (still compromised)
xgrep --validate --category secrets .            # probe providers to confirm which secrets are live
```

Every finding tells you what leaked and how to respond — revoke, rotate, and move the
value to a secret store. Full details in [Secrets scanning](docs/03-secrets/index.md).

## CI/CD integration

`xgrep ci` is a single command that auto-detects your CI provider, scans only what a
pull/merge request changed, and writes a report for the platform to ingest — no hosted
backend, no upload. Distribute it via the prebuilt
[npm package](https://www.npmjs.com/package/@mondoohq/xgrep).

![xgrep ci on a simulated GitHub Actions pull request: it detects the CI environment, runs a diff-aware scan against the merge-base, writes a SARIF report, and flags the command injection introduced by the change](docs/assets/ci.gif)

**GitHub Actions** → GitHub Code Scanning (SARIF):

```yaml
permissions:
  contents: read
  security-events: write
steps:
  - uses: actions/checkout@v4
    with: { fetch-depth: 0 } # history is needed for diff-aware PR scans
  - run: npm install -g @mondoohq/xgrep
  - run: xgrep ci -o results.sarif
  - if: always()
    uses: github/codeql-action/upload-sarif@v3
    with: { sarif_file: results.sarif }
```

**GitLab CI** → Vulnerability Report (GitLab SAST):

```yaml
xgrep-sast:
  image: node:lts
  script:
    - npm install -g @mondoohq/xgrep
    - xgrep ci -o gl-sast-report.json # GitLab SAST format is auto-selected under GitLab CI
  artifacts:
    reports:
      sast: gl-sast-report.json
```

Install options, diff-aware PR scans, exit-code gating, and gradual rollout are in
[CI integration](docs/07-integrations/ci.md).

## Telemetry

xgrep collects **anonymous** usage telemetry to help prioritize engine and rule work
(ADR-0261). It records only aggregate usage — command name, version, OS/arch, language
mix, rule categories, and timing — and **never** your code, file paths, repository
names, findings detail, hostname, or username. Scans run entirely locally regardless;
telemetry is a separate, fire-and-forget metrics push.

It is on by default but trivially disabled, and is **off automatically in CI**:

```bash
xgrep telemetry status   # show whether it's on, and why
xgrep telemetry off      # opt out (persisted to your user config)
xgrep --no-telemetry …   # disable for a single run
DO_NOT_TRACK=1 xgrep …   # honored (consoledonottrack.com)
```

> Note: telemetry is currently **dark-launched** — the upstream collector is not yet
> live, so nothing is sent regardless of the setting. `xgrep telemetry status` shows the
> current state.

## Update checks

Release builds check whether a newer xgrep is published and, if so, print a one-line
notice after `xgrep version` and at the end of an interactive scan. The check asks
Mondoo's install service for the latest version for your platform
(`https://install.mondoo.com/package/xgrep/<platform>/<arch>/<filetype>/latest/version`),
sends nothing about your code or your scan, caches the answer for 24 hours, and never
delays or fails a scan if the service is slow or unreachable. Machine-readable output
(`--json`, `--sarif`, `--quiet`, a piped report) never carries the notice.

Behind a corporate proxy it stays out of your way: the lookup honors `HTTPS_PROXY` /
`NO_PROXY` like any Go program, and if it still cannot get through — refused, blackholed,
TLS intercepted by a CA the machine does not trust — it is deadline-bounded, silent, and
remembered for an hour, so a locked-down network is never asked more than once an hour
and nothing ever fails because of it.

```bash
XGREP_UPDATE_CHECK=0 xgrep …          # never check
DO_NOT_TRACK=1 xgrep …                # honored here too
XGREP_INSTALL_BASE_URL=https://… xgrep …  # ask an internal mirror instead
```

## Documentation

Full documentation lives in [`docs/`](docs/README.md):

- **[Getting started](docs/01-getting-started/index.md)** — install and run your first scan.
- **[Code scanning](docs/02-code-scanning/index.md)** — the SAST engine: CLI reference, output
  formats, supported languages, file filtering, Semgrep compatibility, and writing custom rules.
- **[Secrets](docs/03-secrets/index.md)** — find committed credentials (on by default), across
  git history and encoded payloads, with live-credential validation.
- **[Dependencies](docs/04-dependencies/index.md)** — generate an SBOM and query your
  project's dependencies (software composition analysis).
- **[Code intelligence](docs/05-code-intelligence/index.md)** — `xgrep inspect` and the code graph.
- **[IDE integration](docs/06-ide/index.md)** — xgrep in your editor: zero-config in VS Code,
  and over LSP everywhere else.
- **[Integrations](docs/07-integrations/index.md)** — MCP and CI.
- **[AI agents](docs/08-ai-agents/index.md)** — using xgrep as an agent backend (see also
  [`AGENTS.md`](AGENTS.md)).
