Skip to content

feat: lock/digest integrity verification (aesh + resolver SPI)#2522

Draft
maxandersen wants to merge 3 commits into
mainfrom
lockfeature2-aesh
Draft

feat: lock/digest integrity verification (aesh + resolver SPI)#2522
maxandersen wants to merge 3 commits into
mainfrom
lockfeature2-aesh

Conversation

@maxandersen

@maxandersen maxandersen commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

This PR adds lock-based integrity + reproducibility checks for JBang refs, ported to the aesh CLI framework and wired into the Maven Resolver trusted-checksums SPI.

Supersedes #2410 (which was picocli-based and predates the aesh migration).

p.s. The IKEA table from last time is holding up great.

What's included

  • New command: jbang lock <ref>
  • Default lock file behavior:
    • local file refs (app.java) → app.java.lock
    • alias/GAV/URL refs → .jbang.lock
    • override via --lock-file=...
  • Run policy flag: --locked=<none|lenient|strict>
    • none: ignore lock checks
    • lenient (default): if lock data exists, enforce it; if lock missing, run normally
    • strict: require lock entry when lock file exists and enforce strict matching
  • Lock structure per ref:
    • ref=sha256:... (main resource digest)
    • ref.sources=... (resolved source manifest)
    • ref.deps=... (resolved transitive dependency coordinates)
    • ref.dep.<gav>=sha256:... (per-artifact dependency digests)

Verification behavior

When lock data exists, JBang validates:

  1. Main resource digest
  2. Source manifest (.sources) consistency
  3. Dependency graph (.deps) consistency
  4. Per-artifact dependency digests (.dep.<gav>)

Mismatch → fail with explicit error including resolved file path and fix guidance.

Maven Resolver integration

Per discussion with @cstamas, this implements the resolver's TrustedChecksumsSource SPI:

  • JBangTrustedChecksumsSource implements TrustedChecksumsSource + Writer backed by .jbang.lock
  • Lock command uses the Writer interface to record per-artifact checksums
  • DigestUtil delegates to ChecksumAlgorithmHelper.calculate() from maven-resolver-spi instead of custom MessageDigest code
  • Algorithm name mapping between lock-file format (sha256) and resolver format (SHA-256)

Today the TC source is used standalone by Lock and Run. When MIMA gains an extension point for custom trusted-checksums sources (no such API exists through 2.4.45 or 3.0.0-alpha-3), the same implementation can be injected directly into the resolver pipeline — at which point the manual dep-digest verification loop in Run can be deleted.

Why this design

  • Keeps "just run it" workflow intact when no lock is present.
  • Provides stronger guarantees as soon as lock data exists.
  • Separates mutation (jbang lock) from execution (jbang run ...).
  • Reuses resolver's own checksum infrastructure instead of rolling custom crypto.
  • Shared DigestUtil eliminates code duplication between Lock and Run.

Feedback requested

  1. Are --locked mode semantics (none|lenient|strict) right?
  2. Is <script>.lock the right default for local file refs?
  3. Is properties-based lock format acceptable for v1 with these keys?
  4. Should strict mode require complete per-artifact digests for every locked dep (current behavior)?
  5. Is the TrustedChecksumsSource SPI the right abstraction to build on for the MIMA integration path?

Related issues

Relates to:

Supersedes / consolidates discussion from:

Port the lock file integrity verification feature from PR #2410
(picocli-based) to the current aesh-based CLI framework.

New commands/options:
- jbang lock <ref> -- generate lock entries with checksums
- jbang run --locked=<none|lenient|strict> -- enforce lock checks
- jbang run --lock-file=<path> -- custom lock file path

New files:
- Lock.java: aesh-based lock command
- DigestUtil.java: shared digest/verification utilities
  (eliminates duplication between Lock and Run)
- LockFileUtil.java: lock file read/write (properties format)

Modified:
- Run.java: lock verification during run
- ProjectBuilder.java: locked sources override support
- JBang.java, Main.java: register lock subcommand
- reachability-metadata.json: native image support
…ksums

Implement JBangTrustedChecksumsSource backed by .jbang.lock file,
using the Maven Resolver's TrustedChecksumsSource SPI interface.

This allows the same implementation to be injected into the resolver
pipeline once MIMA adds an extension point for custom TC sources.

Changes:
- JBangTrustedChecksumsSource: implements TrustedChecksumsSource +
  Writer backed by lock file dep digest entries
- Lock.java: uses Writer to record per-artifact checksums via the SPI
- DigestUtil: uses ChecksumAlgorithmHelper.calculate() from
  maven-resolver-spi instead of custom MessageDigest code
- build.gradle: add maven-resolver-spi and maven-resolver-impl as
  compile dependencies (were only transitive via MIMA runtime)
@maxandersen maxandersen mentioned this pull request Jun 9, 2026
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • ai-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a6f2d2c0-a5c2-4da7-8f44-5ab4afc24e93

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread build.gradle Outdated

implementation "eu.maveniverse.maven.mima:context:2.4.36"
implementation "org.apache.maven.resolver:maven-resolver-spi:1.9.24"
implementation "org.apache.maven.resolver:maven-resolver-impl:1.9.24"

@cstamas cstamas Jun 9, 2026

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.

compileOnly: as both are included into standalone-static fat jar below, plus, SPI is already transitive dep of context (it pull api, spi and util, the public APIs).

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.

2 participants