@inner-security/scan
v0.1.17
Published
Inner CLI: `@inner-security/scan` zero-auth instant dependency scan + `inner init` to route the 6 package managers through the Inner proxy. A thin client of Inner's Verdict API, gated by an org API key.
Readme
@inner-security/scan — Inner CLI
A thin client of Inner's Verdict API:
npx @inner-security/scan— instant dependency scan. Reads your manifest/lockfile, calls the Verdict API, and prints the protected tally (N packages scanned, K allowed, M blocked).inner init— auto-configures the 6 package managers (npm / pnpm / yarn / pip / poetry / uv) to resolve through the Inner registry proxy.inner setup --token <key>— the one-paste onboarding: does everythinginner initdoes and wires the Inner MCP server into your coding agents (Claude Desktop + Cursor) in a single command.
One-paste setup
npx --yes @inner-security/scan setup --token inner_xxxxxxxx...One command, fully wired: routes all 6 package managers through the Inner proxy (org key written to user-level config, never your repo) and installs the Inner MCP server into Claude Desktop + Cursor so your agents check every package before installing. Copy it from the dashboard Connect page with your key baked in — paste once, you're protected.
All detection, scoring, and auth live server-side. This package ships no
detection logic — it only consumes the Verdict API. A bare npx
@inner-security/scan works without a key: it resolves each package via the
public, edge-cached GET /v1/scan lookup (real cached verdicts; per-IP
rate-limited on cache misses). An Inner org API key (the Datadog model)
unlocks the full path — fresh analysis of never-seen packages, no per-IP cap,
and org policy enforcement.
Install / run
# Instant scan (cwd) — no install needed
npx @inner-security/scan
npx @inner-security/scan --dir ./my-project --json
# Or install globally for the `inner` umbrella CLI
npm i -g @inner-security/scan
inner scan
inner init
inner init --proxy https://proxy.example.com --managers npm,pnpm,pipBins exposed: scan / inner-scan (the scan path) and inner (umbrella CLI
with scan + init). Requires Node >= 20.
API key
Keyless scans serve already-analyzed packages from the public cache; a
package we've never seen comes back unknown (the public route never triggers
analysis), and heavy cache-miss bursts get rate-limited per IP. Your Inner org
API key lifts both — provide it via env:
export INNER_API_KEY=inner_...
npx @inner-security/scanAuthenticated installs — inner init --token
inner init routes the 6 package managers through the Inner proxy. Add
--token <inner_…> and the install traffic is authenticated with your org
key, so the proxy gates it and revoking the key stops the next install:
inner init --token inner_xxxxxxxx...The proxy registry/index routing is written to project-local config
(.npmrc, pip.conf, pyproject.toml, … — safe to commit). The secret key is
written only to user-level config — ~/.npmrc (_authToken, npm/pnpm),
~/.yarnrc.yml (npmRegistries, yarn), ~/.netrc (pip/uv), and poetry's
auth.toml ([http-basic.inner], poetry) — so it never lands in your project
tree or git. Those files are written 0600.
Configurable endpoints
Both hosts are env/flag-configurable and default to Inner's hosted services — the CLI works out of the box. Override them only to point at a different deployment (e.g. self-hosted or local dev):
| What | Flag | Env | Default |
|------|------|-----|---------|
| Verdict API base | --api-url | INNER_API_URL | https://api.getinner.ai |
| Registry proxy base | --proxy (init) | INNER_PROXY_URL | https://registry.getinner.ai |
| Org API key | — | INNER_API_KEY | (none) |
Legacy config self-heal
Machines wired before 0.1.11 may still point at the legacy workers.dev
endpoints (they keep working as a permanent alias). Every inner run
(setup / init / scan / status) quietly migrates Inner-managed lines — routing
and credentials — to the branded domains (registry.getinner.ai /
api.getinner.ai), removing duplicate legacy credential entries rather than
duplicating them. Only Inner's exact legacy hostnames are ever touched. Set
INNER_NO_SELF_HEAL=1 to opt out.
Verdict resolution
- Items are sent to
POST /v1/verdict(VerdictRequest). - The response carries
VerdictEnvelope | PendingResponse. PENDINGitems are polled atGET /v1/verdict/{job_id}with backoff.- Every requested package is bucketed by its envelope
action(ALLOW/BLOCK/REVIEW); unresolved →unknown.
Fail-open cache
Resolved verdicts are written to .inner-cache/ (last-known-good). If the API is
unreachable, the scan falls back to that cache: cached-ALLOW packages still
resolve, everything else surfaces as unknown. The run is marked degraded
rather than failing outright. Pass --no-cache to disable.
Exit codes
0 clean · 1 one or more BLOCKED packages · 2 usage/error.
Package-manager config written by inner init
| Manager | File | Key |
|---------|------|-----|
| npm | .npmrc | registry=<proxy>/npm/ |
| pnpm | .npmrc | registry=<proxy>/npm/ |
| yarn | .yarnrc.yml | npmRegistryServer: "<proxy>/npm/" |
| pip | pip.conf | [global] index-url = <proxy>/pypi/simple/ |
| poetry | poetry.toml | [[tool.poetry.source]] url = <proxy>/pypi/simple/ |
| uv | uv.toml | [[index]] url = <proxy>/pypi/simple/ |
inner init is idempotent and preserves unrelated config lines.
Telemetry
Opt-in and off by default. Set INNER_TELEMETRY=1 to send anonymous usage
events (command completions and result tallies — never package names, file
paths, or your API key) to PostHog. The distinct ID is a SHA-256 hash of
INNER_API_KEY, so the raw key never leaves your machine.
License
MIT © 2026 Inner Security. See LICENSE.
