Open Source Security

JSR JavaScript Registry Security Model

JSR reimagines JavaScript package distribution with mandatory signing, scoped namespaces, and provenance by default. Here is how the security model works.

Shadab Khan
Security Engineer
5 min read

JSR, the JavaScript registry that grew out of the Deno ecosystem, has matured into something npm's original designers would probably recognize as the registry they wished they had built. Where npm evolved organically and added security controls over time, JSR started with provenance, signing, and scoped namespaces as core assumptions. That design choice shows up throughout the ecosystem: in how packages are published, in how they are consumed, and in how the registry responds to compromise.

This post walks through the JSR security model as it stands in early 2026. We compare it with npm where the contrast is instructive, and we look at the practical implications for teams choosing between the two registries for new projects. The goal is to separate marketing from mechanism and to give security engineers the detail they need to make an informed bet.

What makes JSR different at the registry layer?

JSR is different at the registry layer because every package ships with cryptographic provenance by default. When a maintainer publishes, the registry requires an OIDC token from GitHub Actions, GitLab CI, or a supported trusted publisher, and it records the full build attestation alongside the package. Consumers can verify the attestation with a single command, and the registry will refuse to serve a package whose attestation does not match its declared source.

npm has supported provenance since 2023, but it remains opt-in. JSR makes it mandatory for the standard publish flow, which eliminates the social engineering vector where an attacker convinces a maintainer to publish without provenance. In the first year of JSR's production operation, this design decision blocked at least three known compromise attempts, according to the registry's transparency report.

How does scoping change the attack surface?

Scoping changes the attack surface by eliminating global namespace squatting. Every package on JSR lives under a scope, and scopes are claimed by verified identities, either GitHub users or organizations. A package at @acme/utils is only publishable by a maintainer of the @acme scope, and the scope itself is tied to a verified GitHub organization or a JSR-native organization backed by SSO.

The practical result is that typosquatting is harder and less impactful. An attacker cannot register @acmee/utils and expect casual users to install it by mistake, because the consumer has to type the scope explicitly. The scope also becomes a trust anchor: a team that audits a scope once can assume that future packages under that scope came from the same organization, rather than auditing each package individually.

What does the signing pipeline look like end to end?

The signing pipeline looks like an OIDC-to-Sigstore bridge with registry-side verification. A maintainer runs jsr publish from a trusted CI environment. The CI environment mints an OIDC token, the publish client exchanges it for a signing certificate through the JSR attestation service, and the attestation is uploaded to a transparency log. Consumers can verify the attestation offline using the JSR CLI or through any Sigstore-compatible tooling.

The failure modes are interesting. If the CI environment is compromised, the attacker can still publish, because they can mint a valid OIDC token. The signing pipeline is not a silver bullet against CI compromise. What it does provide is a tamper-evident audit trail: a malicious publish leaves a record in the transparency log, and the record includes the source repository commit that produced it. Investigators can identify the exact commit and revoke downstream, rather than guessing at the provenance of an artifact after the fact.

How does consumption work for enterprise teams?

Consumption works through a hybrid model. JSR publishes packages as native JSR modules for Deno and Bun, and it also mirrors them to npm-compatible tarballs for Node and build-tool consumption. The npm-compatible artifacts carry the same attestations, so teams can consume JSR packages through their existing npm tooling without losing provenance.

Enterprise teams typically configure a pull-through cache, Artifactory, Nexus, or a cloud-native equivalent, that fetches from JSR, re-verifies the attestation, and caches the artifact. The cache becomes the trust boundary: internal consumers only install from the cache, and the cache enforces policy. We have seen teams use this pattern to require that every JSR package have an attestation from a whitelist of trusted repositories, which blocks a surprising number of low-quality transitive dependencies.

How does JSR respond to a compromised package?

JSR responds to a compromised package with an unpublish-and-attest workflow. The registry operators mark the affected version as yanked, and the transparency log records the yank with a reason code. Downstream consumers that have the package cached can query the registry or the log to discover the yank. Because the attestation includes the source commit, the registry can also pre-emptively flag other packages built from the same compromised CI environment.

In one 2025 incident, a maintainer's GitHub account was compromised and used to publish a malicious minor release. The yank landed within four hours of disclosure, and because the attestation tied the publish to a specific CI run, every downstream consumer could identify the exact affected range without guessing. That is a materially better operational experience than the npm equivalent, where incident response often starts with "which versions do we think are affected?"

How Safeguard Helps

Safeguard ingests JSR packages through the same pipeline that handles npm, PyPI, and Maven, so your dependency inventory stays uniform across registries. We verify JSR attestations on ingest, flag packages that lose provenance through mirroring, and record the full chain of custody in the SBOM. Reachability analysis confirms whether a vulnerable JSR package is actually callable from your application, so you can distinguish noise from real risk. TPRM scores each scope as a supplier, and Griffin AI surfaces suspicious publishing patterns, including off-pattern release cadences or sudden scope transfers. Policy gates in CI block installs from scopes that fail your bar, giving you the benefits of JSR's design without trusting the registry alone.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.