Metadata-Version: 2.4
Name: depenemy
Version: 0.1.1
Summary: Dependency scanner that finds your enemies in the supply chain
Project-URL: Homepage, https://github.com/W3OSC/depenemy
Project-URL: Repository, https://github.com/W3OSC/depenemy
Project-URL: Issues, https://github.com/W3OSC/depenemy/issues
Project-URL: Changelog, https://github.com/W3OSC/depenemy/blob/main/CHANGELOG.md
Author-email: W3OSC <contact@w3osc.com>
License: MIT License
        
        Copyright (c) 2026 W3OSC
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: dependencies,sarif,sbom,scanner,security,supply-chain
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.9
Requires-Dist: anyio>=4.4.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: rich>=13.7.0
Requires-Dist: tomli>=2.0.0; python_version < '3.11'
Requires-Dist: typer>=0.12.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=8.0.0; extra == 'dev'
Requires-Dist: respx>=0.21.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Requires-Dist: types-pyyaml>=6.0.0; extra == 'dev'
Description-Content-Type: text/markdown

<div align="center">

<img src="https://raw.githubusercontent.com/W3OSC/depenemy/main/assets/logos/logo.svg" alt="depenemy" width="380"/>

**Your dependencies could be your enemy.**

Depenemy scans your project for supply chain risks, behavioral issues, and reputation red flags - before they can do damage.

[![CI](https://github.com/W3OSC/depenemy/actions/workflows/ci.yml/badge.svg)](https://github.com/W3OSC/depenemy/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/depenemy)](https://pypi.org/project/depenemy/)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

</div>

---

## Why depenemy?

Modern projects pull in hundreds of dependencies. Each one is a potential entry point for a supply chain attack - a compromised maintainer account, a typosquatted package, an old version with a known CVE, or a package that runs arbitrary code on install.

Depenemy gives you **a single command** that audits all your dependencies across npm, Python, Rust, and Solidity - and tells you exactly what looks suspicious and why.

---

## What it detects

### Behavioral risks

| ID | Name | Description | Severity |
|----|------|-------------|----------|
| B001 | Range specifier | Version uses `^`, `~`, `>=`, `*` - allows unexpected updates | Warning |
| B002 | No version pinned | No version specified at all | Error |
| B003 | Lagging version | Pinned version is significantly behind latest | Warning |

### Reputation signals

| ID | Name | Description | Severity |
|----|------|-------------|----------|
| R001 | Young author account | Package author's GitHub account is < 12 months old | Warning |
| R002 | New package | Package was first published < 6 months ago | Warning |
| R003 | Low weekly downloads | < 1,000 weekly downloads | Warning |
| R004 | Low total downloads | < 10,000 total downloads | Warning |
| R005 | No updates in 2+ years | Last publish was over 2 years ago | Warning |
| R006 | Few contributors | Fewer than 5 contributors on GitHub | Warning |
| R007 | Known vulnerable version | Your version is below a known security patch (OSV/CVE) | Error |
| R008 | Deprecated package | Package is officially marked as deprecated | Warning |
| R009 | Typosquatting suspected | Name is suspiciously close to a popular package | Warning |

### Supply chain risks

| ID | Name | Description | Severity |
|----|------|-------------|----------|
| S001 | Install scripts | Package runs code at install time (`postinstall`, `preinstall`) | Error |
| S002 | No source repository | No GitHub/GitLab link in package metadata | Warning |
| S003 | Archived repository | Source repo has been archived or deleted | Warning |
| S004 | Dependency confusion | Private package name found on public registry | Warning |
| S005 | Known malicious package | Package has a recorded history of malicious activity (OSV) | Error |

---

## Supported ecosystems

| Ecosystem | Manifest files |
|-----------|----------------|
| **npm / Node.js** | `package.json`, `package-lock.json`, `yarn.lock` |
| **Python** | `requirements*.txt`, `pyproject.toml`, `Pipfile` |
| **Rust** | `Cargo.toml` |
| **Solidity** | Foundry / Hardhat (delegates to npm) |

---

## Installation

```bash
pip install depenemy
```

---

## Usage

### CLI

```bash
# Scan your project
depenemy scan .

# Scan a specific file
depenemy scan pyproject.toml

# Output as SARIF (for GitHub Code Scanning)
depenemy scan . --output sarif --output-file results.sarif

# Output as JSON to a custom filename (table scan always writes depenemy-results.json automatically)
depenemy scan . --output json --output-file my-results.json

# Pipe JSON output to another tool
depenemy scan . --output json | jq '.findings'

# Fail the command if any warnings exist (useful in CI)
depenemy scan . --fail-on warning

# List all available rules
depenemy rules
```

**Example output:**
<img width="1070" height="711" alt="image" src="https://github.com/user-attachments/assets/96d22774-9649-4b2e-ba09-c3311df8ae3c" />


---

### GitHub Action

Add to your workflow and results appear automatically as [Code Scanning alerts](https://docs.github.com/en/code-security/code-scanning) on every pull request:

```yaml
- name: Scan dependencies
  uses: W3OSC/depenemy@v0.1.1
  with:
    token: ${{ secrets.GITHUB_TOKEN }}
    fail-on: error
```

---

### Pre-commit hook

Block pushes that introduce risky dependencies. Add to `.pre-commit-config.yaml`:

```yaml
repos:
  - repo: https://github.com/W3OSC/depenemy
    rev: v0.1.1
    hooks:
      - id: depenemy
```

---

## Configuration

Create `.depenemy.yml` in your repository root to customize thresholds, severities, and ignore specific packages:

```yaml
thresholds:
  min_weekly_downloads: 1000       # R003 threshold
  min_total_downloads: 10000       # R004 threshold
  min_author_account_age_days: 365 # R001 threshold
  min_package_age_days: 180        # R002 threshold
  max_stale_days: 730              # R005 threshold
  min_contributors: 5              # R006 threshold
  max_version_lag: 10              # B003 threshold (minor versions)
  typosquatting_distance: 1        # R009 threshold (edit distance)

rules:
  B001: warning   # downgrade range specifier to warning
  R003: false     # disable low downloads check entirely

ignore:
  - name: my-internal-package
    ecosystem: npm
    reason: "Internal fork, not on public registry"
  - name: legacy-tool
    ecosystem: pypi
    reason: "Approved exception, tracked in JIRA-1234"
```

Set a rule to `false` to disable it entirely. All other rules accept `warning` or `error`.

---

## Output formats

| Format | Flag | Best for |
|--------|------|----------|
| Table (default) | `--output table` | Terminal / CI logs |
| SARIF | `--output sarif` | GitHub Code Scanning |
| JSON | `--output json` | Custom integrations, dashboards |

---

## How it works

<img width="619" height="813" alt="image" src="https://github.com/user-attachments/assets/07a028e4-5c1f-402e-804e-c9e63148d0aa" />

API responses are cached for **6 hours** in `.depenemy_cache/` to avoid rate limits on repeated runs. Use `--no-cache` to force fresh data.

---

## GitHub Token

A GitHub token unlocks author account age (R001) and contributor count (R006) checks. Without it, those rules are skipped.

```bash
# CLI
depenemy scan . --github-token ghp_xxxx

# Or via environment variable
GITHUB_TOKEN=ghp_xxxx depenemy scan .
```

In GitHub Actions, `${{ secrets.GITHUB_TOKEN }}` is available automatically.

---

## License

MIT - see [LICENSE](LICENSE)


