How to Apply Reserved-Namespace Starter Packs

Beginner 10 minutes Security Engineers / Platform Engineers Security & Policy

Turn on one-click dependency-confusion protection with the curated reserved-namespace packs shipped in configs/reserved_namespaces_defaults.yaml.

Overview

Dependency-confusion (Birsan 2021) is still one of the cheapest and most effective supply-chain attacks: an attacker enumerates internal package names that leak through lockfile diffs, commit messages, or error logs, then publishes look-alikes to the public registries. If any developer or CI runner resolves against the public registry with higher priority, the attacker’s code runs.

Chainsaw protects against this with the reservedNamespaces condition — but the protection is only as good as the patterns you register. The v0.16 release ships a curated list of starter packs in configs/reserved_namespaces_defaults.yaml and a one-click “Apply recommended namespaces” action in the dashboard.

Prerequisites

  • Admin or Manager role in Chainsaw
  • A short list of your organisation’s package-name identifiers (e.g., npm scope @acme, Maven group com.acme, Go module path github.com/acme)

Step 1: Open the Reserved Namespaces Editor

Navigate to Policies → Reserved Namespaces. If your tenant has no reserved namespaces configured, the onboarding banner will prompt you to apply the recommended packs.

Step 2: Apply the Starter Packs

Click Apply recommended packs. The dashboard loads the curated list from GET /api/policies/recommended-namespaces and seeds the editor with patterns grouped by ecosystem. You’ll see placeholders like ${ORG} or ${COMPANY} — replace them with your organisation’s identifiers before saving.

# Example subset of the seeded list — replace ${ORG} before saving
- pattern: "@${ORG}/*"
  ecosystem: npm
  action: block
- pattern: "com.${ORG}.*"
  ecosystem: maven
  action: block
- pattern: "${ORG}-*"
  ecosystem: pypi
  action: block
- pattern: "github.com/${ORG}/*"
  ecosystem: gomod
  action: block
Placeholders are intentional. The recommended packs are a starting template, not a default-on configuration — a pattern like @${ORG}/* left unreplaced would block nothing. The dashboard refuses to save patterns that still contain ${…} placeholders.

Step 3: Verify the Block

From a machine that points at your proxy, attempt to resolve a name that matches your reserved pattern against a public registry. You should see a 403 with a policy-violation reason and the matching pattern.

# Example — with @acme reserved, this should fail
npm install @acme/not-a-real-package

The dashboard’s Traffic view will show the blocked request with the reservedNamespaces condition as the matched rule.

Step 4: Extend the Packs

The seeded patterns cover the canonical dependency-confusion surface for each ecosystem you have proxied. Add patterns for:

  • Every internal npm scope your org uses
  • Every Maven groupId and Gradle coordinate
  • Every Go module path under your VCS organisation
  • Every PyPI / RubyGems prefix convention
  • Every internal Docker namespace (${REGISTRY}/${ORG}/*)

Each pattern is scoped to an ecosystem and an action (block, warn). Use warn for patterns you’re still validating, block once you’re confident no legitimate upstream package matches.

Step 5: Cross-Reference the Matrix

For the authoritative list of ecosystems where reservedNamespaces applies (format-agnostic — all of them), see the Policy × Proxy Compatibility Matrix, which chainsaw policy preflight prints from your server → the ReservedNamespaces condition.

Next Steps