Skip to content
Agentmart
Submit a tool

mdk-publish-security

Run the pre-publish security audit for every publishable @tetherto/mdk-* package (or any non-private package in an npm monorepo).

Skill by tetherto

IndexedApache-2.0★ 11
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/tetherto-mdk-publish-security

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Run the pre-publish security audit for every publishable @tetherto/mdk-* package (or any non-private package in an npm monorepo). Use when preparing an npm release, when asked to "security check the packages", "audit before publish", "run the publish checklist", or to review packages for auth bypass, injection, command execution, path traversal, SSRF, prototype pollution, unsafe deserialization, secret exposure, crypto mistakes, insecure defaults, RPC trust boundaries, privilege escalation or TOCTOU issues, or to check that packed tarballs install and import cleanly, what consumers get from npm audit without the root overrides, and who owns the npm scope.

Use cases: security, finance

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found
Runs as
Node.js package

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/mdk-publish-security

What's inside

Skill name
mdk-publish-security
Description
Run the pre-publish security audit for every publishable @tetherto/mdk-* package (or any non-private package in an npm monorepo). Use when preparing an npm release, when asked to "security check the packages", "audit before publish", "run the publish checklist", or to review packages for auth bypass, injection, command execution, path traversal, SSRF, prototype pollution, unsafe deserialization, secret exposure, crypto mistakes, insecure defaults, RPC trust boundaries, privilege escalation or TOCTOU issues, or to check that packed tarballs install and import cleanly, what consumers get from npm audit without the root overrides, and who owns the npm scope.
License
Apache-2.0
Metadata
suite: mdk-developer-skill · mdk_version: 0.10.0
Instructions
161 lines in SKILL.md · view on GitHub

Before installing

  • Ships executable scripts

Files (3)

  • SKILL.md
  • vuln-classes.md · references/
  • scan-packages.mjs · scripts/

SKILL.md (first lines)

# Pre-publish security audit

Produces one Markdown report listing every publishable package, every check run
on it, and the issues that must be fixed before `npm publish`. The checks combine
the repo's `PUBLISH_CHECKLIST.md` (security section + per-package extras) and the
publish blockers in `NPM_PACKAGES.md` with a manual review for 18 vulnerability
classes ([`references/vuln-classes.md`](./references/vuln-classes.md)).

This skill never edits package source, never publishes, and never runs install
scripts of dependencies. Without `--smoke` it only reads the checkout and writes
the report. **`--smoke` is not read-only:** `npm pack` runs each package's *own*
`prepack`/`prepare` script (for example it rebuilds `packages/mdk-skill/dist/`),
and the smoke step then installs the tarballs into a temp directory outside the
repo and imports every package entry point and runs every `bin`. That executes
the packages' code, so only run `--smoke` on a checkout you trust.

## 1. Inventory

From the repo root:

```bash
git ls-files '*package.json' | grep -Ev '(^|/)(node_modules|dist|templates|fixtures?)/' \
  | xargs grep -L '"private": true'
```

The filter drops scaffolding templates and generated output, which are not
packages. The scan script applies the same filter.

Cross-check against the table in `NPM_PACKAGES.md` (if present). A package that
is publishable but missing from the doc, or vice versa, is itself a finding.

## 2. Mechanical scan (all packages, one command)

```bash
SCAN_DIR="$(mktemp -d)"   # private dir; never a fixed /tmp path
node <this-skill>/scripts/scan-packages.mjs --audit --smoke --registry --out "$SCAN_DIR/mdk-scan.md"
node <this-skill>/scripts/scan-packages.mjs --audit --smoke --registry --json --out "$SCAN_DIR/mdk-scan.json"
# one package: --pkg backend/core/gateway   (repeatable)
# keep the smoke project for `npm ls <dep>`: --keep-smoke
```

`--out` refuses to overwrite an existing file or follow a symlink. `--audit`,
`--smoke` and `--registry` need network; without them the scan is offline. It runs `npm pack --dry-run --ignore-scripts` per package and checks,
on exactly the files that would ship. "Blocker" refers to the section of that
name in `NPM_PACKAGES.md`:

| Check | Source | What fails |
| --- | --- | --- |
| `files-allowlist` | Blocker "no `files` allowlist" / checklist "Tarball contents" | No `files` field |
| `tarball-contents` | Checklist "Tarball contents" | tests, mocks, fixtures, db/, `.env`, keys, real `config/*.json`, `.sh` in the tarball |
| `escaping-import` | Blocker "relative `require()`s" | Literal `require('../..')` that resolves outside the package dir |
| `undeclared-dep` | Blocker "missing dependency declarations" / "Tarball smoke test" | Bare import not in `dependencies` (dev-only counts as missing) |
| `dep-source` | Checklist "Versions and lockfile" | `file:`/`workspace:`/`link:`/git deps in a published manifest |
| `loose-range` | Checklist "Version ranges" | `*`, `latest`, `x` or unbounded `>=` in `dependencies` (high for the package's own scope) |
| `private-dep` | Checklist "Version ranges" | Depends on a package that is `"private": true` in this repo |
| `dev-peer` | Checklist "Version ranges" / UI class U10 | A dev tool (`vitest`, `jest`, `@testing-library/*`, `vite`, `typescript`, …) is a required `peerDependency`, so npm 7+ installs it for every consumer |
| `root-override` / `package-overrides` | Checklist "Consumer-view audit" | A dep the root `overrides` patches, or `overrides` in the package itself — neither reaches consumers |
| `publish-access` | Blocker "scoped packages publish as restricted" | Scoped package without `publishConfig.access` |
| `repository` | Blocker "missing `repository` metadata" / provenance | No `repository` |
| `prepack-build` | Blocker "no pre-publish build" | `main`/`bin` points at missing build output with no `prepack` |
| `entry-missing` | Checklist "Tarball smoke test" | A `main`, `exports` or `bin` target is not in the tarball |
| `bin-shebang` | Checklist "Tarball smoke test" | A `bin` file without a `#!` line |
| `exports-map` | Hygiene (low) | No `exports` map, so every shipped file is importable |
| `install-scripts` | Checklist "Install scripts" | `preinstall`/`install`/`postinstall` |
| `secrets` | Checklist "Secrets" | Key/token patterns, hard-coded credentials, private IPs, internal hosts |
| `npm-audit` | Checklist "Dependency audit" (`--audit`) | Moderate+ advisories in prod deps of that workspace |
| `smoke-pack` / `smoke-install` / `smoke-import` / `smoke-bin` | Checklist "Tarball smoke test" (`--smoke`) | Packs every package, installs all tarballs together in a temp project outside the repo, imports each `main`/`exports` entry and runs each `bin --help`. Catches runtime-built paths the static `escaping-import` check misses. A load-time throw that is not a missing module is reported low — confirm it is intentional |
| Consumer-view audit | Checklist "Consumer-view audit" (`--smoke`) | `npm audit --omit=dev` in the smoke project; repo-level line naming the vulnerable packages. The workspace audit can be clean while this is not |
| `registry-unclaimed` / `registry-version` / `registry-owner` | Release checks (`--registry`) | Name not on npm yet; version already published; published name points at a different repository (squat). Also reports `npm whoami` and how many packages the scope already holds |
| SAST leads | Checklist "Static analysis" | Grep hits per vulnerability class in shipped runtime code, including the UI classes (`xss` HTML sinks, `url` navigation sinks and `_blank` without `noopener`, `browser-storage`, `postmessage`) — **triage, do not report raw** |

Then run the repo-wide checks the script does not cover, and record the outcome
(including "tool not installed" — never silently skip):

```bash
npm audit --audit-level=moderate                        # root, all workspaces
npm audit signatures                                    # registry signatures of installed deps
npx --yes audit-ci@7.1.0 --config .github/scripts/audit-ci.jsonc                 # downloads; needs network
npx --yes license-checker@25.0.1 --production --onlyAllow 'Apache-2.0;MIT;ISC;BSD-2-Clause;BSD-3-Clause;0BSD;BlueOak-1.0.0;CC0-1.0;Python-2.0;Unlicense' --excludePrivatePackages   # downloads; needs network
gitleaks detect --no-banner                             # if installed; also on each extracted tarball
semgrep --config p/javascript --config p/nodejs <pkg>   # if installed
grep -rn 'uses:' .github/workflows | grep -v '@[0-9a-f]\{40\}'   # actions not pinned to a SHA
git diff <lastTag> -- '**/package.json'                 # new dependencies since last release
npm view <dep> time.modified deprecated                 # per new dep: age (<7 days is a flag) and deprecation
npm sbom --omit dev --sbom-format cyclonedx -w <name>   # attach one SBOM per package to the report
```

`audit-ci` and `license-checker` are not repo dependencies, so `npx` downloads
and runs them. Keep the exact versions above (bump only to a release that is at
least two weeks old, checked with `npm view <pkg> time --json`), never drop the
`@version`, and record "not run (no network)" when offline.

Scope and account checks need `npm login` as a publisher. Record "not run" if
nobody with publish rights is available; never infer ownership from 404s:

```bash
npm whoami
npm org ls <scope-without-@>                 # you are a member with publish rights
npm profile get                              # "two-factor auth" is auth-and-writes
npm access get status <name>                 # after first publish: public as intended
```

If `--registry` shows the scope has no packages and cannot be listed, the scope
may be unclaimed. Anyone can then register it, and every doc that says
`npm install @scope/...` installs their code. Report it as **High** until the
org exists.

`npm` may be a shell alias/function in the user's profile; scripts call the
binary directly, so do the same (`command npm …`) when results differ.

## 3. Manual review (per package, 18 classes + UI classes for browser packages)

Mechanical checks cannot find auth bypasses or SSRF. For each package:

1. Read its `package.json`, README and entry point; list its boundaries using the
   table in [`references/vuln-classes.md`](./references/vuln-classes.md).
2. Enumerate every route, RPC handler, action, MCP tool and exported function
   that accepts external data. Follow each to its sinks (fs, process, network,
   storage, logs, responses).

From tetherto/mdk, Apache-2.0.

More from tetherto/mdk

Signals

Stars
11
Forks
13
Open issues
0
Last commit (this folder)
Oct 22, 2026 (6 days ago)
Last release
Oct 19, 2026 (9 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
Apache-2.0
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from tetherto

Cite this page

mdk-publish-security skill. Agent Mart. https://agentmart.dev/skills/tetherto-mdk-publish-security (last updated 2026-10-24)