
One command grades your whole cloud account — misconfigurations, missing observability, and security posture.
One command grades your whole cloud account — misconfigurations, missing observability, and security posture, ranked by the five things to fix first.
Point it at AWS, Cloudflare, Vercel, Supabase, Render, Fly.io, or Railway and it comes back with a score, what's broken, and a fix for each one — self-contained enough to hand straight to an agent.
npx cloud-doctor
https://github.com/user-attachments/assets/60b610ab-7aee-4c3a-8d9e-83f045c8cc56
That picks a provider, resolves your identity (AWS profile, API token, …), and runs the scan interactively. To skip straight to a provider:
npx cloud-doctor aws --profile prod
npx cloud-doctor cloudflare --yes
npx cloud-doctor vercel --yes
If ~/.npmrc has min-release-age set (supply-chain hardening) and blocks fresh releases:
# =<number>, 0 chosen as example
npm x --min-release-age=0 cloud-doctor -- aws profiles
Prefer the bleeding edge? Alpha builds publish to their own tag: npx cloud-doctor@alpha.
Auth tokens can be set as env vars or you can provide them when the tui asks for it:
CLOUDFLARE_API_TOKEN=cfut_aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ== npx cloud-doctor cloudflare
(don't base64 decode the token)
or
$ npx cloud-doctor cloudflare
Cloudflare credentials are not set — enter them below.
Kept for this run only, never written to disk. Skip these prompts: export CLOUDFLARE_API_TOKEN
dashboard → My Profile → API Tokens
? Cloudflare read-only API token › <input>
Coming soon: Google Cloud, Kubernetes, and Databases (Postgres, MySQL, Redis) — see What's next.
npx cloud-doctor # pick provider (default AWS) → pick identity → scan
npx cloud-doctor aws # AWS fast path
npx cloud-doctor aws --profile prod # non-interactive when unambiguous
npx cloud-doctor aws --yes --json # CI, machine-readable output
npx cloud-doctor aws --yes --json --fail-under 75 # CI gate on the score
npx cloud-doctor cloudflare --yes # needs CLOUDFLARE_API_TOKEN
npx cloud-doctor vercel --yes # needs VERCEL_TOKEN (+ VERCEL_TEAM_ID)
npx cloud-doctor supabase --yes # needs SUPABASE_ACCESS_TOKEN
npx cloud-doctor render --yes # needs RENDER_API_KEY
npx cloud-doctor fly --yes # needs FLY_API_TOKEN (+ FLY_ORG)
npx cloud-doctor railway --yes # needs RAILWAY_API_TOKEN
npx cloud-doctor aws profiles # list ~/.aws/config profiles
npx cloud-doctor aws whoami # show resolved AWS identity
--yes skips prompts (CI-safe); --json prints a stable, schema-versioned report instead of the terminal view; --verbose prints every finding instead of the top offenders; --no-color disables color output.
Scores are never faked: if zero rules could run, the score is null with the label "No checks ran," never a hollow 100.
Tune rules per provider via doctor.config.ts (or doctor.config.json, or cloudDoctor in package.json):
import { defineConfig } from "cloud-doctor/api";
export default defineConfig({
defaultProvider: "aws",
aws: {
profile: "prod",
regions: ["us-east-1", "eu-west-1"],
account: "123456789012",
},
rules: {
"aws/s3-unencrypted-bucket": "off",
"aws/iam-user-access-key": "error",
},
});
"off" disables a rule; "error" / "warning" overrides its severity. Disabled rules are dropped from scoring and disclosed as muted — never silently subtracted.
A thin CLI over a plugin registry — every provider implements the same contract, so the CLI never special-cases one over another.
Each provider implements CloudDoctorPlugin:
discoverIdentities() — list profiles/projects/accounts for the pickerresolveIdentity() — map flags/env/config → identity, no network callsvalidateIdentity() — prove the credentials work (sts:GetCallerIdentity or equivalent)scan() — run the gated rules, return diagnostics + scoreNew providers register in packages/plugins/src/index.ts.
gcloud, k8s, and db are coming soon.
pnpm install
pnpm build
pnpm typecheck
pnpm test
For hands-on rule verification without hitting a real cloud account, the repo ships an http-mock and Moto/fab fixture harness: (ps: fab the cli to generate environment to run against, currently private, the dependency project will be made open-source too)
pnpm mock:up <scenario> # boot a persistent mock instance
eval "$(pnpm -s mock:env <scenario>)" # point env vars at it
pnpm mock:run <scenario> # run the CLI against it
Shoutout to react-doctor
| Provider | Command | Auth |
|---|
| AWS | cloud-doctor aws | AWS SDK credential chain — --profile, AWS_PROFILE, env vars, SSO, web identity |
| Cloudflare | cloud-doctor cloudflare | CLOUDFLARE_API_TOKEN |
| Vercel | cloud-doctor vercel | VERCEL_TOKEN (+ optional VERCEL_TEAM_ID) |
| Supabase | cloud-doctor supabase | SUPABASE_ACCESS_TOKEN |
| Render | cloud-doctor render | RENDER_API_KEY |
| Fly.io | cloud-doctor fly | FLY_API_TOKEN (+ optional FLY_ORG) |
| Railway | cloud-doctor railway | RAILWAY_API_TOKEN (workspace/account token) |
| Package | Role |
|---|
packages/cloud-doctor | CLI (commander, prompts, ora) + programmatic diagnose() API |
packages/core | Plugin registry, scoring, config loading, shared types |
packages/plugin-* | One package per provider — identity discovery + rules |
packages/plugins | Default registry wiring every provider together |