Package Proxy
Thinkst Package Proxy enforces install-time policy for npm, pip, uv, and cargo (minimum package age, upload-method regression, allow and block lists). Attestd adds a live check against confirmed compromise data, one call per unique package@version.
Package Proxy is built by Thinkst Applied Research. See their announcement post and GitHub repository. This guide patches your own Package Proxy fork after Thinkst's deploy button clones it into your account.
Layered install-time defense
Package Proxy catches behavioral signals at install time. Attestd contributes confirmed compromise intelligence via GET /v1/check. The layers are complementary.
| Layer | What it catches | Source |
|---|---|---|
| Age check (10 days) | Fresh malicious versions | Package Proxy |
| Upload-method regression | Maintainer account compromise publishes | Package Proxy |
| Attestd compromise check | Confirmed malware / backdoor versions | Attestd API |
What you need
- Package Proxy deployed from your own fork (Cloudflare Worker). See the Thinkst deploy button.
- An Attestd API key, Solo tier or above. Free tier's 60/min limit is not viable for fleet-wide installs.
wranglerCLI for the KV cache namespace and API key secret.
Add the compromise check to your Package Proxy fork
Hook the Attestd check into file-download handlers, immediately after Package Proxy's existing static blocklist. Static blocklist first (free, instant). Attestd second (one cached call per unique package@version).
- Create a KV namespace for the Attestd response cache.bash
npx wrangler kv namespace create attestd-cache # Add the returned id beside PACKAGE_PROXY_CONFIG in wrangler.jsonc: # "kv_namespaces": [ # { "binding": "PACKAGE_PROXY_CONFIG", "id": "..." }, # { "binding": "ATTESTD_CACHE", "id": "<id from create>" } # ] - Set the API key as a Worker secret.bash
npx wrangler secret put ATTESTD_API_KEY - Extend Package Proxy's
Envinterface so TypeScript knows about the secret and KV binding.typescript// In src/index.ts, extend the existing Env interface: export interface Env { AUDIT_TRACKER: DurableObjectNamespace; PACKAGE_PROXY_CONFIG: KVNamespace; install_logs: D1Database; ASSETS: Fetcher; ATTESTD_API_KEY: string; ATTESTD_CACHE: KVNamespace; } - Add the shared helper as
src/attestd.ts.typescript// src/attestd.ts - shared helper, imported by npm.ts and pypi.ts // Keep this type separate from index.ts to avoid a circular import. export interface AttestdEnv { ATTESTD_API_KEY: string; ATTESTD_CACHE: KVNamespace; } export async function isAttestdCompromised( env: AttestdEnv, ecosystem: "npm" | "pypi", product: string, version: string, ): Promise<boolean> { const cacheKey = `attestd:${ecosystem}:${product}@${version}`; const cached = await env.ATTESTD_CACHE.get(cacheKey); if (cached === "1") return true; if (cached === "0") return false; const url = new URL("https://api.attestd.io/v1/check"); url.searchParams.set("product", product); url.searchParams.set("version", version); url.searchParams.set("ecosystem", ecosystem); let compromised = false; try { const res = await fetch(url.toString(), { headers: { Authorization: `Bearer ${env.ATTESTD_API_KEY}` }, }); if (res.ok) { const body = (await res.json()) as { supply_chain?: { compromised?: boolean } | null; }; compromised = body.supply_chain?.compromised === true; } // Non-OK response: fail open. An Attestd outage must not block installs. } catch { // Network error: fail open. } await env.ATTESTD_CACHE.put(cacheKey, compromised ? "1" : "0", { expirationTtl: 300, }); return compromised; } - Patch
handleNpmFetchinsrc/npm.ts.typescript// After the existing block-list check in handleNpmFetch (src/npm.ts): import { isAttestdCompromised } from "./attestd"; if (Params.env && (await isAttestdCompromised(Params.env, "npm", pName, pVer))) { console.log(`Attestd: ${pName}@${pVer} is a confirmed compromised version -- returning 404`); fireWebhook( Params.config.webhookUrl, `npm:${pName}@${pVer}`, "Attestd flagged this version as a confirmed supply chain compromise.", ); return [new Response("Package/version not found", { status: 404 }), pName, pVer]; } - Patch
handlePypiFetchinsrc/pypi.ts.typescript// After the existing block-list check in handlePypiFetch (src/pypi.ts): import { isAttestdCompromised } from "./attestd"; if (Params.env && (await isAttestdCompromised(Params.env, "pypi", pName, pVer))) { console.log(`Attestd: ${pName}@${pVer} is a confirmed compromised version -- returning 404`); fireWebhook( Params.config.webhookUrl, `pypi:${pName}@${pVer}`, "Attestd flagged this version as a confirmed supply chain compromise.", ); return [new Response("Package/version not found", { status: 404 }), pName, pVer]; } - Redeploy.bash
npx wrangler deploy
Fail open on API errors and timeouts. Package Proxy's age and upload-method checks still apply. Only an explicit supply_chain.compromised === true response blocks the install. An Attestd outage must not become an install outage.
Hard rule: block only when supply_chain.compromised === true. Do not block on risk_state alone. A critical CVE is not the same as a malicious publish.
Example GET /v1/check response for a compromised version:
{
"product": "litellm",
"version": "1.82.7",
"supported": true,
"risk_state": "critical",
"risk_factors": [
"active_exploitation",
"remote_code_execution",
"no_authentication_required",
"internet_exposed_service",
"patch_available",
"supply_chain_compromised"
],
"actively_exploited": true,
"remote_exploitable": true,
"authentication_required": false,
"patch_available": true,
"fixed_version": null,
"confidence": 0.5,
"cve_ids": [
"CVE-2026-33634",
"CVE-2026-35029",
"CVE-2026-35030",
"CVE-2026-40217",
"CVE-2026-42203",
"CVE-2026-42208",
"CVE-2026-42271",
"CVE-2026-47101",
"CVE-2026-47102",
"CVE-2026-49468",
"CVE-2026-59819",
"CVE-2026-59820",
"CVE-2026-59822"
],
"max_epss": 0.8942,
"supply_chain": {
"compromised": true,
"sources": ["osv"],
"malware_type": "malware",
"description": "Malicious code in litellm (PyPI)",
"advisory_url": "https://github.com/BerriAI/litellm/issues/24518",
"compromised_at": "2026-03-24T11:15:14Z",
"removed_at": null,
"source_published_at": "2026-03-24T11:15:14Z",
"observed_at": "2026-04-18T16:49:23.317491Z",
"ingested_at": "2026-04-18T16:49:23.317491Z",
"first_served_at": "2026-08-03T15:34:51.347440Z",
"provenance": null
},
"supply_chain_monitored": true
}Confirm a blocked version
First confirm the API reports the version as compromised, then confirm the patched Worker returns 404 for that version.
curl -sS "https://api.attestd.io/v1/check?product=litellm&version=1.82.7&ecosystem=pypi" \
-H "Authorization: Bearer $ATTESTD_API_KEY" | jq '.supply_chain.compromised'
# -> truepip download litellm==1.82.7 --index-url "https://$USER@$PACKAGE_PROXY_HOST/pypi/" --no-deps
# -> 404 / "Package/version not found" once the patch is deployedWhat this covers
The check covers confirmed supply chain compromise (malware, backdoors, account-takeover publishes), the same signal the production API returns as supply_chain.compromised. Newly registered compromises are covered immediately. There is no sync lag.
It does not cover CVE age, EPSS, or CISA KEV active exploitation for install policy. Use Attestd in CI or via the supply chain API for those signals.