Appearance
Signing and trust
Status: target state, not implemented. No package signing, signature verification, or publisher-pinning happens in the current code tree. Trust today is "the registry served the bytes over TLS using a token I authenticated with." This page documents that present state honestly and outlines the target state filed under
WORKSTREAMS/.
Present state — the trust model in code today
mx publish and mx install rely on three things:
- TLS to the registry.
npm publishandnpm packhonorhttps://URLs; certificates are validated by the system trust store. - Authenticated tokens. The publisher's
_authTokenis sent in the.npmrcwritten bypackages/mx-cli/src/utils/npm-registry-client.ts. The token binds an upload to a registry account. - Tarball SHA from the registry.
npm installverifies the downloaded tarball's SHA against the metadata document (dist.shasum,dist.integrity). This only proves the bytes match what the registry claims; it does not prove who created them.
There is no signature on the tarball itself. There is no public-key pinning of publishers. There is no published SBOM beyond what package.json:dependencies discloses.
What we explicitly do NOT do today
- We do not sign tarballs with a publisher key (no
npm publish --provenance-style attestation). - We do not ship signature blobs alongside discovery metadata.
- We do not verify a publisher's identity at install time.
- We do not produce CycloneDX or SPDX SBOMs.
- We do not enforce reproducible builds.
Operator-side mitigations
projects/matrix-3/packages/docs/content/security/npm-publish-safety.md documents the operator-side mitigations that exist today: token rotation cadence, restricted publish scopes (hivecast-admin/ versus open-matrix/), the manual public-npm publish path, and the operator-machine verification that confirms a token works against the right registry endpoint.
These mitigations are necessary but not sufficient. They protect against the mistakes operators make; they do not protect a downstream installer from a compromised registry or a man-in-the- middle that bypasses TLS pinning.
Target state — what signing-and-trust should add
The direction (filed in workstream notes; no committed spec yet):
- Publisher-keyed tarball signatures. Author signs the tarball at publish time with a per-publisher key. The signature ships in the discovery metadata next to
dist.tarball.mx installre-validates before the tarball touches the package store. - Publisher trust roots. Each Host configures which publisher keys it trusts. The default for HiveCast Hosts would trust
@open-matrix/*publishers. Custom orgs configure their own trust roots. - Capability declarations meet trust. When Capability declarations land (P1.15), an unsigned package would be allowed to declare capabilities but a Host would only enforce them on signed packages.
- SBOM emission.
mx publishwould write a CycloneDX SBOM next to the tarball summarizing dependencies. Tools likemx outdatedwould surface transitive vulnerabilities. - Signed runtime records. When Host Service writes a runtime record, the package's signature digest would land in
<runtime>.jsonso audit can confirm what code is running.
Practical advice for authors today
Until signing lands:
- Pin your registry. Don't publish to
lateston a public registry without a separatemx publish --dry-runreview. - Audit
package.json:dependenciesbefore publishing. Phantom deps cause silent failures (CLAUDE.md "phantom dependencies"). - Restrict
package.json:filesto what you mean to ship. A missingfilesentry leads to over-publishing source/secrets. - Use
--dry-runand inspect the tarball before any release that matters. - Treat tokens like passwords. Rotate, scope per environment, never commit. Credentials live under
<MATRIX_HOME>/credentials/, not in~/.npmrc.
See also
- Publishing → npm-compatible publication
- Authoring → Capability declarations
projects/matrix-3/packages/docs/content/security/npm-publish-safety.md
Source: Present-state surface implemented in
projects/matrix-3/packages/mx-cli/src/utils/npm-registry-client.tsandauth-store.ts. Target-state items not yet in code; track throughWORKSTREAMS/once a spec is written.