Skip to content

Dependencies

dependencies

Dependency rules — vulnerability scanning and hygiene checks.

DependencyAuditRule dataclass

Bases: ProjectRule

Scan dependencies for known vulnerabilities via pip-audit.

Scoring: 100 - (vuln_count * 15), min 0.

Source code in packages/axm-audit/src/axm_audit/core/rules/dependencies.py
@dataclass
@register_rule("deps")
class DependencyAuditRule(ProjectRule):
    """Scan dependencies for known vulnerabilities via pip-audit.

    Scoring: 100 - (vuln_count * 15), min 0.
    """

    @property
    def rule_id(self) -> str:
        """Unique identifier for this rule."""
        return "DEPS_AUDIT"

    def check(self, project_path: Path) -> CheckResult:
        """Check dependencies for known CVEs."""
        try:
            data = _run_pip_audit(project_path)
        except FileNotFoundError:
            return CheckResult(
                rule_id=self.rule_id,
                passed=False,
                message="pip-audit not available",
                severity=Severity.ERROR,
                details={"vuln_count": 0, "score": 0},
                fix_hint="Install with: uv add --dev pip-audit",
            )
        except RuntimeError as exc:
            return CheckResult(
                rule_id=self.rule_id,
                passed=False,
                message=str(exc),
                severity=Severity.ERROR,
                details={"vuln_count": 0, "score": 0},
                fix_hint="Check pip-audit installation: uv run pip-audit --version",
            )

        vulns = _parse_vulns(data)
        vuln_count = len(vulns)
        score = max(0, 100 - vuln_count * 15)

        return CheckResult(
            rule_id=self.rule_id,
            passed=score >= PASS_THRESHOLD,
            message=(
                "No known vulnerabilities"
                if vuln_count == 0
                else f"{vuln_count} vulnerable package(s) found"
            ),
            severity=Severity.WARNING if score < PASS_THRESHOLD else Severity.INFO,
            details={
                "vuln_count": vuln_count,
                "score": score,
                "top_vulns": [_summarize_vuln(v) for v in vulns[:5]],
            },
            fix_hint=("Run: pip-audit --fix to remediate" if vuln_count > 0 else None),
        )
rule_id property

Unique identifier for this rule.

check(project_path)

Check dependencies for known CVEs.

Source code in packages/axm-audit/src/axm_audit/core/rules/dependencies.py
def check(self, project_path: Path) -> CheckResult:
    """Check dependencies for known CVEs."""
    try:
        data = _run_pip_audit(project_path)
    except FileNotFoundError:
        return CheckResult(
            rule_id=self.rule_id,
            passed=False,
            message="pip-audit not available",
            severity=Severity.ERROR,
            details={"vuln_count": 0, "score": 0},
            fix_hint="Install with: uv add --dev pip-audit",
        )
    except RuntimeError as exc:
        return CheckResult(
            rule_id=self.rule_id,
            passed=False,
            message=str(exc),
            severity=Severity.ERROR,
            details={"vuln_count": 0, "score": 0},
            fix_hint="Check pip-audit installation: uv run pip-audit --version",
        )

    vulns = _parse_vulns(data)
    vuln_count = len(vulns)
    score = max(0, 100 - vuln_count * 15)

    return CheckResult(
        rule_id=self.rule_id,
        passed=score >= PASS_THRESHOLD,
        message=(
            "No known vulnerabilities"
            if vuln_count == 0
            else f"{vuln_count} vulnerable package(s) found"
        ),
        severity=Severity.WARNING if score < PASS_THRESHOLD else Severity.INFO,
        details={
            "vuln_count": vuln_count,
            "score": score,
            "top_vulns": [_summarize_vuln(v) for v in vulns[:5]],
        },
        fix_hint=("Run: pip-audit --fix to remediate" if vuln_count > 0 else None),
    )

DependencyHygieneRule dataclass

Bases: ProjectRule

Check for unused/missing/transitive dependencies via deptry.

Scoring: 100 - (issue_count * 10), min 0.

Source code in packages/axm-audit/src/axm_audit/core/rules/dependencies.py
@dataclass
@register_rule("deps")
class DependencyHygieneRule(ProjectRule):
    """Check for unused/missing/transitive dependencies via deptry.

    Scoring: 100 - (issue_count * 10), min 0.
    """

    @property
    def rule_id(self) -> str:
        """Unique identifier for this rule."""
        return "DEPS_HYGIENE"

    def check(self, project_path: Path) -> CheckResult:
        """Check dependency hygiene with deptry."""
        try:
            issues = _run_deptry(project_path)
        except FileNotFoundError:
            return CheckResult(
                rule_id=self.rule_id,
                passed=False,
                message="deptry not available",
                severity=Severity.ERROR,
                details={"issue_count": 0, "score": 0},
                fix_hint="Install with: uv add --dev deptry",
            )
        except (RuntimeError, json.JSONDecodeError) as exc:
            is_runtime = isinstance(exc, RuntimeError)
            msg = f"deptry failed: {exc}" if is_runtime else "deptry output parse error"
            return CheckResult(
                rule_id=self.rule_id,
                passed=False,
                message=msg,
                severity=Severity.ERROR,
                details={"issue_count": 0, "score": 0},
                fix_hint="Check deptry installation: uv run deptry --version",
            )

        issue_count = len(issues)
        score = max(0, 100 - issue_count * 10)

        return CheckResult(
            rule_id=self.rule_id,
            passed=score >= PASS_THRESHOLD,
            message=(
                "Clean dependencies (0 issues)"
                if issue_count == 0
                else f"{issue_count} dependency issue(s) found"
            ),
            severity=Severity.WARNING if score < PASS_THRESHOLD else Severity.INFO,
            details={
                "issue_count": issue_count,
                "score": score,
                "top_issues": [_format_issue(i) for i in issues[:5]],
            },
            fix_hint=("Run: deptry . to see details" if issue_count > 0 else None),
        )
rule_id property

Unique identifier for this rule.

check(project_path)

Check dependency hygiene with deptry.

Source code in packages/axm-audit/src/axm_audit/core/rules/dependencies.py
def check(self, project_path: Path) -> CheckResult:
    """Check dependency hygiene with deptry."""
    try:
        issues = _run_deptry(project_path)
    except FileNotFoundError:
        return CheckResult(
            rule_id=self.rule_id,
            passed=False,
            message="deptry not available",
            severity=Severity.ERROR,
            details={"issue_count": 0, "score": 0},
            fix_hint="Install with: uv add --dev deptry",
        )
    except (RuntimeError, json.JSONDecodeError) as exc:
        is_runtime = isinstance(exc, RuntimeError)
        msg = f"deptry failed: {exc}" if is_runtime else "deptry output parse error"
        return CheckResult(
            rule_id=self.rule_id,
            passed=False,
            message=msg,
            severity=Severity.ERROR,
            details={"issue_count": 0, "score": 0},
            fix_hint="Check deptry installation: uv run deptry --version",
        )

    issue_count = len(issues)
    score = max(0, 100 - issue_count * 10)

    return CheckResult(
        rule_id=self.rule_id,
        passed=score >= PASS_THRESHOLD,
        message=(
            "Clean dependencies (0 issues)"
            if issue_count == 0
            else f"{issue_count} dependency issue(s) found"
        ),
        severity=Severity.WARNING if score < PASS_THRESHOLD else Severity.INFO,
        details={
            "issue_count": issue_count,
            "score": score,
            "top_issues": [_format_issue(i) for i in issues[:5]],
        },
        fix_hint=("Run: deptry . to see details" if issue_count > 0 else None),
    )