Skip to main content

slopgate

A CI gate against slopsquatting and hallucinated dependencies for Python, npm, and Go.

LLMs hallucinate plausible package names. Attackers pre-register them. An AI coding agent then adds the dependency with no human at the install checkpoint. slopgate is the checkpoint: it runs in CI, looks at the dependencies a change introduces, and fails the build on the ones that carry a slopsquat signature.

It has zero third-party runtime dependencies. A tool that guards your dependency surface shouldn't widen it.

✗ BLOCK   pypi:reqeusts          name does not exist on the registry and closely
                                 resembles 'requests' — typo/slopsquat signature
✗ BLOCK   pypi:hallucinated-pkg  name does not exist on the registry —
                                 likely a hallucinated dependency
! WARN    npm:lodahs             resembles popular package 'lodash'
✓ ok      pypi:requests          (silent unless --verbose)

Why this exists, and what makes it different

Most "AI supply chain" material tells you to write a policy and inventory your shadow AI. This is the control that actually runs in the pipeline. The hard part of a tool like this isn't the plumbing — it's the signal-to-noise discipline. A gate that flags every new package gets disabled on the first false positive, and then you have no gate. So slopgate is built around one rule: block only on the intersection of signals that actually describes the attack; warn on the rest; pass everything else silently.

The threat model (read this — the thresholds are yours to own)

A brand-new package is not inherently malicious. A name near a popular one is not inherently malicious. The slopsquat signature is the intersection:

Verdict Signature
BLOCK Name doesn't exist on the registry (hallucination or typo)
BLOCK Freshly registered and resembles a popular package (the bullseye)
BLOCK Freshly registered and no source repo and a single version (throwaway publish)
WARN Resembles a popular package but is established (could be a known squat — needs eyes, not an auto-fail)
WARN Recently published, on its own
WARN Registry lookup failed — never block on a transport error
OK Everything else, silently

The default thresholds live in slopgate/score.py and are deliberately conservative:

  • fresh_days = 14 — the window slopsquat registrations live in.
  • young_days = 90 — worth a warning, not a block.
  • immature_versions = 2 — below this, a package is "immature".

These are starting points, not gospel. They encode a risk tolerance; yours may differ. The similarity corpus in slopgate/corpus.py is the other knob: it's a curated set of the most-impersonated packages per ecosystem, kept small to hold the false-positive rate down. Swap in a real top-N-by-downloads list for production — bigger corpus catches more and warns more, and that trade-off is your call.

Install

pip install slopgate
# or, from source:
pip install git+https://github.com/nullracodes/slopgate

Use

slopgate scan .                       # scan every manifest under cwd
slopgate scan requirements.txt        # one file
slopgate scan . --strict              # warnings fail the build too
slopgate scan . --offline             # name-similarity only, no registry calls
slopgate scan . --ignore my-internal-pkg another-internal-pkg
slopgate scan . --format sarif --output slopgate.sarif

In a PR, evaluate only the dependencies the PR adds — the signal-to-noise contract:

slopgate scan . --added-only --base-ref origin/main

Exit codes: 0 clean, 1 at least one BLOCK (or any WARN under --strict), 2 usage error.

Supported manifests

  • PyPI: requirements*.txt (follows -r/-c includes, detects --hash= pins), pyproject.toml (PEP 621 and Poetry)
  • npm: package.json (+ lockfile presence for hash-pinning detection)
  • Go: go.mod (+ go.sum presence)

No PHP, no Java — out of scope, on purpose.

SARIF findings include the manifest line number where a manifest format exposes it (requirements, go.mod), so GitHub maps each finding to a line, not just a file.

GitHub Actions

A ready-to-use workflow ships in .github/workflows/slopgate.yml. It runs on PRs that touch a manifest, evaluates only newly-added deps, uploads SARIF to the Security tab, and fails the check on a BLOCK.

A note on building this with an AI coding agent

This tool was scaffolded with an AI coding agent; the irony is not lost on me. If you do the same, dogfood the thesis: pin every dependency the agent proposes, review the dependency diff before install, don't run package operations on auto-approve, and sandbox the agent. The most honest demo of a slopsquatting gate is catching the moment your own agent reaches for a package that doesn't exist.

License

MIT.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

slopgate-0.1.0.tar.gz (21.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

slopgate-0.1.0-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file slopgate-0.1.0.tar.gz.

File metadata

  • Download URL: slopgate-0.1.0.tar.gz
  • Upload date:
  • Size: 21.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for slopgate-0.1.0.tar.gz
Algorithm Hash digest
SHA256 de357b2a8c73c710495a0d34590b94bac54e13d2dcb181fea69252b60973ed33
MD5 15221b5d23c7aa33bae6217a7127ec1c
BLAKE2b-256 10af6de50e89ce2771627c3bb7182c7c3e812ffffebcc07d6b14ef576b39f35f

See more details on using hashes here.

Provenance

The following attestation bundles were made for slopgate-0.1.0.tar.gz:

Publisher: release.yml on nullracodes/slopgate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file slopgate-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: slopgate-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for slopgate-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f9efaa7ef7ba243ebc14a71689f046dfaf1a2afe72c31e5b92e7f274934b699c
MD5 25e182cb4999ae213c8f75f1ea17c1a6
BLAKE2b-256 2991ea7edb1ff3776fcda47d45b85d00b168c484b647811d6435a1ed9fb99717

See more details on using hashes here.

Provenance

The following attestation bundles were made for slopgate-0.1.0-py3-none-any.whl:

Publisher: release.yml on nullracodes/slopgate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page