DEV Community

Petter_Strale
Petter_Strale

Posted on • Originally published at strale.dev

One API Call to Know If Your Dependency Is Safe

A coding agent just suggested adding a package to your project. You've never heard of it. How do you decide whether to trust it?

Most developers either accept the suggestion blindly or spend fifteen minutes checking GitHub stars, last commit date, the npm advisory database, and whatever license file happens to exist. Agents can't do either — they need a structured signal, fast.

The data exists. It's just scattered.

The information you need to evaluate a dependency already exists across public APIs. OSV.dev maintains a comprehensive vulnerability database covering CVEs and GitHub Security Advisories across npm, PyPI, Go, Rust, and more. Google's deps.dev aggregates dependency graphs, license metadata, and OpenSSF Scorecard results — the 18-check security health assessment that most developers have never heard of despite it covering over a million projects. The npm and PyPI registries themselves tell you when a package was last published, whether it's deprecated, and how many maintainers it has.

The problem isn't data availability. It's that these are five or six separate HTTP calls with different request formats, different response schemas, and different failure modes. An agent checking one dependency has to call OSV.dev with a POST body specifying ecosystem and version, then hit deps.dev's REST API to get the linked GitHub project, then make another call to deps.dev for the OpenSSF Scorecard, then query the registry for freshness signals. Then it has to synthesize all of that into a decision. Multiply that by forty dependencies in a lockfile and you've built an integration project, not a quick check.

What we built

package-security-audit aggregates all of the above into a single API call. You pass a package name and optionally a version and ecosystem. It calls OSV.dev, deps.dev, and the relevant registry in parallel, normalizes everything, and returns a 0–100 risk score with the evidence behind it.

curl -X POST https://api.strale.io/v1/do \
  -H "Authorization: Bearer $STRALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "capability_slug": "package-security-audit",
    "inputs": { "name": "express", "version": "4.18.2" }
  }'
Enter fullscreen mode Exit fullscreen mode

Here's what comes back (trimmed to the output fields):

{
  "output": {
    "name": "express",
    "version": "4.18.2",
    "ecosystem": "npm",
    "risk_score": 94,
    "risk_level": "low",
    "vulnerabilities": {
      "total": 2,
      "critical": 0,
      "high": 0,
      "medium": 0,
      "low": 2,
      "details": [
        {
          "id": "GHSA-qw6h-vgh9-j6wx",
          "severity": "low",
          "summary": "express vulnerable to XSS via response.redirect()",
          "fixed_in": "4.20.0"
        },
        {
          "id": "GHSA-rv95-896h-c2vc",
          "severity": "moderate",
          "summary": "Express.js Open Redirect in malformed URLs",
          "fixed_in": "4.19.2"
        }
      ]
    },
    "license": {
      "spdx": "MIT",
      "is_osi_approved": true,
      "is_copyleft": false
    },
    "freshness": {
      "latest_version": "5.2.1",
      "is_latest": false,
      "is_deprecated": false,
      "days_since_last_release": 121
    },
    "maintainers": 5,
    "dependency_count": 0
  },
  "provenance": {
    "source": "osv.dev + deps.dev + registry",
    "fetched_at": "2026-04-02T10:30:33.440Z"
  }
}
Enter fullscreen mode Exit fullscreen mode

Express 4.18.2 scores 94/100 — low risk. Two low-severity vulnerabilities, both with known fix versions. MIT license, five maintainers, not deprecated. The only flag: it's not the latest version (5.2.1 is out). An agent can read that response and make a decision in milliseconds. The whole call took 486ms.

The second capability, license-compatibility-check, handles a different question: given a set of licenses across your dependency tree, are they all compatible with your use case?

curl -X POST https://api.strale.io/v1/do \
  -H "Authorization: Bearer $STRALE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "capability_slug": "license-compatibility-check",
    "inputs": {
      "licenses": ["MIT", "Apache-2.0", "GPL-3.0-only"],
      "use_case": "commercial"
    }
  }'
Enter fullscreen mode Exit fullscreen mode
{
  "output": {
    "compatible": false,
    "use_case": "commercial",
    "license_count": 3,
    "licenses_analyzed": [
      { "input": "MIT", "type": "permissive", "compatible_with_use_case": true },
      { "input": "Apache-2.0", "type": "permissive", "compatible_with_use_case": true },
      { "input": "GPL-3.0-only", "type": "strong_copyleft", "compatible_with_use_case": false }
    ],
    "conflicts": [
      {
        "licenses": ["GPL-3.0-only"],
        "reason": "GPL-3.0-only is strong copyleft — requires distributing your source code under the same license. Incompatible with proprietary commercial distribution.",
        "severity": "error"
      }
    ],
    "summary": "1 compatibility conflict(s) found for commercial use. Strong copyleft licenses detected."
  }
}
Enter fullscreen mode Exit fullscreen mode

It covers 30+ SPDX licenses and knows the specific compatibility rules that trip people up — GPL-2.0 and GPL-3.0 are mutually incompatible unless "or-later" is used, Apache-2.0 conflicts with GPL-2.0-only, and AGPL in any dependency makes your entire SaaS project AGPL-bound. Purely algorithmic, 8ms response time.

The dependency-risk-check solution chains both: security audit plus license compatibility in a single call for €0.25.

How it works under the hood

The security audit makes four parallel requests. OSV.dev gets queried with the specific package version and ecosystem to find known vulnerabilities. deps.dev provides the license, dependency count, and a link to the source repository. If that repository is on GitHub, a second deps.dev call fetches the OpenSSF Scorecard — an automated assessment of 18 security practices including branch protection, code review, dependency update tooling, and fuzzing coverage. The registry API supplies freshness and deprecation data.

Penalties are applied to a starting score of 100: critical CVEs cost 25 points each, deprecated packages lose 20, packages not updated in over two years lose 20, and missing licenses lose 15. The floor is zero. If any upstream source is temporarily unavailable, the remaining sources still produce a partial score rather than failing the entire call.

Every response includes provenance metadata — which sources were queried and when — so the agent or human reviewing the decision can trace where the data came from.

For agent builders

The practical use case is making npm install or pip install a decision an agent can make autonomously. With Strale's MCP server, a coding agent can check any package before adding it — no configuration, no API keys to manage beyond the Strale key.

npx strale-mcp
Enter fullscreen mode Exit fullscreen mode

Any MCP-compatible client (Claude Code, Cursor, Windsurf, or anything else speaking the protocol) can call package-security-audit directly. The agent gets back structured JSON it can reason over: a numeric risk score, specific vulnerabilities with fix versions, and a clear compatible/incompatible verdict on licensing. That's enough to make an autonomous yes/no decision, or to surface a warning to the developer when the score is marginal.

package-security-audit costs €0.15 per call. license-compatibility-check costs €0.05. That's cheap enough to check every dependency in a typical lockfile for under €10.

Both capabilities are live now. The API docs have the full input/output schemas, or you can browse the capability catalog to see them alongside the 270+ other capabilities available. The source is at github.com/strale-io.

Top comments (0)