← use cases/AI Agents

Catch hallucinated dependencies before your agent installs them

AI agents invent package names and cannot reason about real-world exploitation risk from CVSS numbers alone. They need deterministic signals for CVE risk, supply chain compromise, and package name integrity, including when the model hallucinated the dependency name itself.

why the naive approach fails

An agent that installs whatever the model suggests is already past the point where advisory text helps. The failure modes are concrete.

  • Models invent package names that look plausible. A typosquat or hallucinated name can land malware before any CVE exists for it.
  • CVSS scores require interpretation. An agent branching on "severity: HIGH" still has to decide whether that means block, warn, or proceed.
  • CVE databases list vulnerabilities. They do not return a single field that means "do not install this version."
  • Supply chain compromises often have no CVE at publish time. A CVE-only tool returns clean while the package is already compromised.
what to branch on

Map these fields directly into tool return values. No scoring step between the API and the agent.

FieldMeaning for this use case
risk_stateCategorical verdict: none, low, medium, high, or critical. Branch on critical and high without reading CVSS.
actively_exploitedTrue when Attestd has confirmed active exploitation for this product@version. Prefer block over warn when true.
supply_chain.compromisedTrue for confirmed malicious publishes, including packages with no CVE. Independent of risk_state.
typosquatReturned when the product name is unsupported and resembles a known package. kind hallucination covers model-invented names. resembles is the package to prefer instead.
fixed_versionUpgrade target when a patch exists. Give the agent a concrete next version, not just a block.
the request
bash
curl "https://api.attestd.io/v1/check?product=redis&version=6.0.9" \
  -H "Authorization: Bearer $ATTESTD_API_KEY"
integration
agent_tool.py
import os
import attestd

client = attestd.Client(api_key=os.environ["ATTESTD_API_KEY"])

def check_software_safety(product: str, version: str) -> dict:
    """
    Tool available to the agent for checking software risk state.
    Returns structured, deterministic data. No interpretation needed.
    """
    try:
        risk = client.check(product, version)
    except attestd.AttestdUnsupportedProductError as e:
        if e.typosquat and e.typosquat.detected:
            return {
                "safe_to_deploy": False,
                "action": "block_deployment",
                "typosquat_kind": e.typosquat.kind,
                "prefer": e.typosquat.resembles,
            }
        return {"safe_to_deploy": False, "action": "unknown_risk"}

    if risk.supply_chain and risk.supply_chain.compromised:
        return {
            "safe_to_deploy": False,
            "action": "block_deployment",
            "reason": "supply_chain_compromised",
        }

    return {
        "safe_to_deploy": risk.risk_state == "none",
        "risk_state": risk.risk_state,
        "actively_exploited": risk.actively_exploited,
        "recommended_version": risk.fixed_version or version,
        "action": (
            "block_deployment"
            if risk.risk_state == "critical"
            else "warn"
            if risk.risk_state == "high"
            else "proceed"
        ),
    }

# Agent receives structured output. No ambiguity in the signal
result = check_software_safety("redis", "6.0.9")
# result["action"] → "block_deployment" | "warn" | "proceed"
how to wire it
  1. 01

    Expose /v1/check as an agent tool

    Wrap Attestd in a function the agent can call before install or deploy. Keep the tool schema narrow: product, version, and a small action enum.

  2. 02

    Require a check before package install

    In the agent loop, refuse to run pip install, npm install, or equivalent until check_software_safety returns proceed. Treat unknown_risk and typosquat as block.

  3. 03

    Pass the corrected name back to the model

    When typosquat.kind is hallucination, return resembles to the agent so it can retry with the real package instead of inventing another name.

operational outcome

Agents make deployment decisions with ground truth, not guesses.

Attestd returns the same answer every time for the same inputs. There is no probability and no scoring interpretation. When an agent invents a package name, typosquat.kind hallucination tells it what to install instead. An agent calling Attestd either gets proceed, block, or a corrected package name.

in the wild

The first documented fully autonomous AI ransomware attack used a known Langflow CVE. An agent exploited CVE-2025-3248, pivoted through the Docker socket to the host, and encrypted production data with no human in the loop.

The same operator returned with a compiled Go payload targeting AI model files. 19 days later, ENCFORGE targeted roughly 180 file types including model weights, vector indexes, and training datasets.

NVD published CVE-2025-3248 more than a year before either attack. The signal existed as raw CVE data. What was missing was a synthesized condition an agent could act on. That is the machine-speed argument: autonomous attackers and autonomous installers operate in the same time domain. A human-readable advisory digest does not.