npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mediaforge/blastradius

v0.2.1

Published

What can the credentials on this machine actually destroy?

Downloads

492

Readme

BlastRadius

What can the credentials on this machine actually destroy?

Secret scanners answer "is there a credential here, and is it live?" BlastRadius answers the two questions that actually predict an incident:

  1. What is the worst thing this credential can do?
  2. Can the coding agent running here reach it?
$ blastradius --resolve

CATASTROPHIC Railway ****...a4f1
             can delete databases, volumes, or bucket contents
             can delete backups or snapshots
             ↳ can destroy data AND its backups — unrecoverable
             found in scripts/legacy-deploy.sh:14
             fix: scope this token to the single service it deploys

SEVERE       Stripe  sk_l********CCCC
             can move real money — charges, refunds, or transfers
             found in env STRIPE_KEY
             fix: replace this unrestricted live key with a restricted key

2 credentials reachable, worst case: CATASTROPHIC

Why

Picture an agent doing something routine. It hits a credential mismatch. Rather than stopping, it goes looking for something that will authenticate — and finds a token in a file that has nothing to do with the task it was given.

Someone created that token months ago for one narrow job. Nobody noticed it also carried authority over the entire platform account, because the platform never offered a way to scope it down. One API call later the production volume is gone, and so are the backups, because they were stored inside the volume they were supposed to protect.

Nothing in that loop knew what the credential it picked up could do. That is the gap — not detection, which is well served, but consequence modelling.

This is not a thought experiment. It has happened, in nine seconds, with a thirty-hour recovery — see Real-world incidents.

Install & use

Requires Node 20+. No dependencies.

npx @mediaforge/blastradius            # no install — discover only, offline, inert
npx @mediaforge/blastradius --resolve  # ask each provider what its credential can do

# or install it, after which the command is just `blastradius`
npm install -g @mediaforge/blastradius

blastradius                  # discover only — offline, nothing leaves the machine
blastradius --resolve        # ask each provider what its credential can actually do
blastradius --resolve --json # machine-readable, for CI (schema `version: 2`)
blastradius --providers      # what's supported, and when it was last verified

Discovery and resolution are separate on purpose. Discovery is inert. Resolution authenticates with every credential it found — a materially different act that touches third-party accounts and can trip fraud detection. Making that the default would be the same class of surprise this tool exists to report on.

CI gate

blastradius --resolve --fail-on severe

Exit 0 clean, 1 at or above threshold, 2 error. Credentials whose privileges could not be determined fail by default — --allow-unknown opts out. A gate that passes on "we couldn't tell" teaches people to trust a green tick that means nothing.

What it will not do

  • It never prints a raw secret. Everything user-facing is fingerprinted.
  • It never sends a credential anywhere except the issuing provider. Enforced mechanically: each provider module declares its apiHosts and a guard blocks everything else.
  • It never reports "unknown" as "safe." If privileges cannot be resolved, the report says so loudly.
  • It does not claim a clean bill of health. An empty result means "nothing matched the providers we ship", and says exactly that.

Where it looks

Not just the repo. The question is what an agent could find if it went looking, so the search covers the working tree including gitignored files, the process environment, and — the part repo-only scanners miss entirely — agent and MCP configuration. A credential in an MCP server's env block is the most agent-reachable place a secret can sit.

--no-env and --no-agent-config narrow it; --no-heuristic turns off the search for credentials in formats BlastRadius does not recognise.

Supported providers

| Provider | What it can tell you | |---|---| | GitHub | Classic PAT scopes, in full. Fine-grained PATs report unresolved — the API does not expose their permissions. | | Stripe | Live vs test mode. Restricted keys report unresolved rather than being guessed at. | | Railway | Full capability, confidently. Railway has no token scopes at all, so an account token can delete a volume and the backups stored with it. | | Supabase | Key class, entirely offline — service_role and sb_secret_ bypass RLS; management tokens can delete whole projects. | | Vercel | Account-level reach. Vercel has no project-level scoping, so a token reads decrypted env vars and can delete projects. | | Cloudflare | Liveness only. Cloudflare will not tell a token its own permissions, so every live token reports unresolved — see below. |

Run blastradius --providers for the lastVerified date on each, stamped by its last green run against the live API. Reports go stale visibly rather than silently.

Coverage is deliberately narrow. A wrong "this token is harmless" is worse than no answer, so providers ship only when they can be contract-tested — see CONTRIBUTING.md.

Cloudflare is worth calling out, because it is the honest case. Its /user/tokens/verify endpoint returns {id, status, expires_on} and nothing else — no policies, no permission groups. A token cannot read its own permissions. So BlastRadius tells you the credential is real and reachable, and says plainly that it cannot determine the blast radius. Inventing a scope mapping to produce a tidier report would be exactly the confident-and-wrong output this tool exists to prevent.

Docker

docker compose up -d changelog-watch          # provider changelog watcher (no credentials)
docker compose --profile contract up -d       # weekly live-API contract tests
TARGET=/srv/myapp docker compose --profile scan run --rm scan

Only the landing page listens on a port, and it serves static files. No service here accepts a credential over a network. BlastRadius is a CLI, and a hosted service that accepts other people's credentials is a non-goal — it would make this tool the thing it warns about. What the compose file hosts is the drift machinery that keeps provider modules correct. See DRIFT-AND-OSS-PLAN.md.

Note that a containerised scan sees only the mounted path — not the host environment or ~/.claude MCP config, which are the most agent-reachable places a credential sits. It is strictly less thorough than running the CLI on the host. Use it for CI over a checkout.

Free, and staying free

BlastRadius is not a product and has no paid tier planned. Reasoning is recorded in STATUS.md; the maintenance strategy that makes a free tool sustainable is in DRIFT-AND-OSS-PLAN.md.

Support posture

Stated plainly so it does not have to be inferred:

  • Maintained on a best-effort basis, by one person. There is no SLA, no support contract, and no guaranteed response time. Issues are read; not all of them get fixed.
  • Provider coverage is intentionally narrow and will stay that way. Requests for a new provider are welcome, but the bar is the coverage invariant in CONTRIBUTING.md: a module that cannot be kept correct will not be added, because a wrong "this token is harmless" is worse than no answer.
  • Correctness reports get priority over everything else. If BlastRadius told you a credential was safe and it was not, that is the bug that matters most — say so and it goes to the front.
  • No warranty. This is a diagnostic aid, not a security audit. It reports what each provider's own API says about a credential and, where it cannot determine something, says so. Do not treat a clean report as a clean bill of health; it is not one, and the tool will tell you as much.

Agent hooks

The exit code is the contract, so it composes with whatever hook mechanism your agent already has:

blastradius --resolve --fail-on catastrophic || echo "refusing to continue"

Exit 1 at or above the threshold, 0 below it, 2 on error.

Telling an agent what it can reach

In the reference incident, nothing in the loop knew what the credential it picked up could do. That is a knowledge gap, and it is one a session-start hook can close. For Claude Code, in .claude/settings.json:

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "blastradius --resolve --fail-on catastrophic || true",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

The output becomes context, so the agent begins every session already knowing that the token in scripts/deploy.sh can delete your volumes and the backups inside them. Drop --resolve if you do not want a session start authenticating against live accounts; you lose the severities and keep the inventory.

|| true is deliberate. Without it a catastrophic finding aborts the session before you can read why.

Be clear about what this does and does not do. It informs; it does not enforce. An agent that knows a token is dangerous is less likely to reach for it, and that is worth having — but a hook cannot make a reachable credential unreachable. Only the remediation each finding prints does that.

A skill would be weaker still. A skill is instructions a model may or may not follow, and the failure this tool describes is an agent doing something nobody told it to. Asking the failure mode to police itself is not a control. A hook at least runs whether the model cooperates or not.

Resolution is sequential and each provider gets a 10-second timeout, so budget roughly ten seconds per unreachable credential — hence the generous hook timeout above. A runtime guard that intercepted individual tool calls would be a different tool, with a per-agent integration surface this project has decided against carrying.

Development

npm test              # unit suite, offline, no credentials needed
npm run test:contract # live provider APIs — needs test credentials, see CONTRIBUTING.md
npm run changelog:scan # check provider changelogs for auth-relevant changes