Skip to content

feat(cli): add verify and verify-signature commands - #2107

Merged
netomi merged 2 commits into
mainfrom
feat/cli-verify-commands
Aug 27, 2026
Merged

feat(cli): add verify and verify-signature commands#2107
netomi merged 2 commits into
mainfrom
feat/cli-verify-commands

Conversation

@netomi

@netomi netomi commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Closes #993.

What

Adds two ovsx CLI commands for checking a downloaded .vsix package's signature - no server-side changes needed, since the registry already exposes everything they need (files.signature / files.publicKey on any signed version's metadata).

ovsx verify <extension.vsix>

Resolves the namespace/name/version from the package's own manifest, fetches the matching version's signature and public key from the registry, and verifies the Ed25519 signature over the raw package bytes using Node's built-in crypto - the same check VS Code itself performs on install. No proprietary signing dependency required.

  • On success: ✅ This package is identical to ns.ext v1.2.3 as published to <registry>.
  • On failure: explains the package doesn't match what that registry published, and may have been tampered with or come from elsewhere.

ovsx verify-signature -i <pkg> -m <manifest> -s <signature> -k <publicKey>

The fully offline counterpart, mirroring vsce verify-signature's exact command shape for a package/manifest/signature trio already on disk - no registry involved. The one deliberate deviation from vsce: a public key must be supplied explicitly (-k/--publicKeyPath), since each Open VSX registry holds its own signing key rather than trusting one baked-in Marketplace key.

Beyond the outer signature, it cross-checks the manifest's per-entry SHA256 digests against the package's actual contents and reports exactly which entry doesn't match, is missing from the manifest, or is missing from the package - a level of diagnostic detail the signature check alone can't give.

Also in this PR

  • Bumps the minimum supported Node.js version to 22 (engines field + @types/node), matching what was already done for webui.
  • Adds readAllZipEntries to zip.ts - a case-preserving companion to the existing readZip, needed because manifest entry keys must match original (non-lowercased) file names.

Testing

yarn build (tsc + lint) clean. Full yarn test: 45/45 passing, including a real Ed25519 keypair/signature and hand-built zip fixtures for both commands (valid/tampered/wrong-key/unsigned cases, allVersions resolution, and every manifest-mismatch case for verify-signature). Also manually smoke-tested both commands end-to-end against real generated fixtures.

Adds two new ovsx commands for checking a downloaded .vsix package's
signature, addressing #993:

- verify <extension.vsix>: resolves namespace/name/version from the
  package's own manifest, fetches the matching version's signature and
  public key from the registry (files.signature / files.publicKey,
  already exposed for any signed version), and verifies the Ed25519
  signature over the raw package bytes using Node's built-in crypto -
  no server-side changes needed, and no proprietary signing dependency.
  On success it reports that the package is identical to the version
  published to the registry; on failure, that it doesn't match.

- verify-signature -i <pkg> -m <manifest> -s <signature> -k <publicKey>:
  the offline counterpart, mirroring vsce verify-signature's exact
  command shape for a package/manifest/signature trio you already have
  on disk, with no registry involved. Unlike vsce, a public key must be
  supplied explicitly, since each Open VSX registry holds its own
  signing key rather than trusting one baked-in Marketplace key. Beyond
  the outer signature, it cross-checks the manifest's per-entry SHA256
  digests against the package's actual contents and reports exactly
  which entry doesn't match, if any.

Also bumps the minimum supported Node.js version to 22 (engines field
and @types/node), matching webui, and adds readAllZipEntries to zip.ts
- a case-preserving companion to the existing readZip, needed because
  manifest entry keys must match original (non-lowercased) file names.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@netomi
netomi requested review from gnugomez and a lite review from Copilot August 27, 2026 12:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds local verification capabilities to the ovsx CLI so users can confirm a downloaded VSIX is identical to what a registry published (online) or validate a package/manifest/signature trio entirely offline, aligning with VS Code/vsce signature verification behavior.

Changes:

  • Add ovsx verify and ovsx verify-signature commands (registry-backed vs fully offline verification).
  • Add zip helper for case-preserving entry reads to support manifest entry name matching.
  • Bump CLI minimum Node.js version to 22 and update dependencies/tests accordingly.

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cli/yarn.lock Updates lockfile for Node 22 typings and new zip-building test dependency (yazl).
cli/test/unit/verify.spec.ts Adds unit tests covering verify success and key/signature/unsigned failure modes plus allVersions resolution.
cli/test/unit/verify-signature.spec.ts Adds unit tests for offline signature verification and detailed manifest mismatch reporting.
cli/src/zip.ts Exports readZip and adds readAllZipEntries for case-preserving zip entry access.
cli/src/verify.ts Implements registry-backed VSIX signature verification using registry-provided signature/public key.
cli/src/verify-signature.ts Implements fully offline signature verification plus manifest digest cross-checks with detailed mismatch reporting.
cli/src/verify-signature-options.ts Defines options interface for offline verification inputs.
cli/src/verify-options.ts Defines options interface for registry-backed verification inputs.
cli/src/main.ts Wires new verify and verify-signature commands into the CLI.
cli/README.md Documents new verification commands and their intended usage.
cli/package.json Bumps minimum Node.js engine version to 22 and adds dev deps for tests.
cli/CHANGELOG.md Documents the new commands and Node.js version bump in the CLI changelog.
Suppressed comments (1)

cli/src/verify-signature.ts:106

  • When an entry exists in the manifest but is missing digests.sha256, the current logic reports it as a digest mismatch. This is inaccurate and makes it harder to debug malformed manifests; report a clear "missing digest" issue and only compare when a digest is present.
        if (entry.digests?.sha256 !== sha256Base64(content)) {
            issues.push(`'${name}' does not match its digest in the manifest`);
        }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cli/src/verify-signature.ts Outdated
Comment thread cli/src/zip.ts Outdated
gnugomez
gnugomez previously approved these changes Aug 27, 2026

@gnugomez gnugomez left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

- Distinguish a digest that's simply absent from the manifest from one
  that's present but wrong, for both the package-level and per-entry
  checks - a missing digest is a malformed/incomplete manifest, not
  necessarily a mismatch.
- Stream each zip entry straight into a SHA256 hash instead of
  buffering its full content into a Map alongside the already fully
  loaded package bytes, roughly halving peak memory for large
  extensions. readAllZipEntries becomes hashAllZipEntries, returning
  digests directly since that's all any caller ever needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@netomi
netomi merged commit 7acef62 into main Aug 27, 2026
5 checks passed
@netomi
netomi deleted the feat/cli-verify-commands branch August 27, 2026 12:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable verifying the signed package

3 participants