Skip to the content.

Hermetic Toolchain Locking & Cryptographic Provenance

🏠 Overview  •  📦 Installation  •  📖 Usage  •  🏗️ Architecture  •  🏢 Enterprise  •  🔒 Locking  •  🌐 Networking  •  🐚 Shells  •  🎯 Threat Matrix  •  ❓ FAQ  •  ⚖️ SDKMAN! Comparison  •  📜 Changelog  •  🛡️ Security  •  🤝 Contributing  •  💬 Support


In software development and CI/CD pipelines, “floating” toolchain dependencies are a major source of build instability, subtle compiler regressions, and supply chain vulnerabilities.

DiamTek JVM solves this with Hermetic Toolchain Locking (.jvm.lock) and HMAC-SHA256 Cryptographic Tamper-Proof Signing (.jvm.lock.sig).

🔍 Quick Jump


The Reproducible Build Problem

In software development and CI/CD pipelines, “floating” toolchain dependencies are a major source of build instability, subtle compiler regressions, and supply chain vulnerabilities.

A project configured simply as:

java=21

might resolve to:

Differences in minor patch levels, vendor-specific security backports, default JVM ergonomics, and compiler optimizations can cause test suites to fail intermittently or introduce subtle runtime discrepancies across developer laptops and production servers.

DiamTek JVM solves this with Hermetic Toolchain Locking (.jvm.lock) and HMAC-SHA256 Cryptographic Tamper-Proof Signing (.jvm.lock.sig).


The .jvm.lock v2 Specification

DiamTek JVM uses a deterministic Schema v2 JSON lockfile format (UTF-8 No BOM) designed to be committed directly into project source control (Git). It captures the complete immutable provenance of the active Java runtime and associated ecosystem build tools.

Sample .jvm.lock File:

{
  "$schema": "https://raw.githubusercontent.com/DiamTek/Java-Version-Manager-Windows/main/schemas/jvm.lock.json",
  "schema": 2,
  "lockfile_version": 1,
  "platform": "windows-x64",
  "generated_at": "2026-10-14T20:30:00Z",
  "tools": {
    "java": {
      "version": "21.0.6+7",
      "vendor": "adoptium",
      "arch": "x64",
      "url": "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.6%2B7/OpenJDK21U-jdk_x64_windows_hotspot_21.0.6_7.zip",
      "checksum_type": "sha256",
      "checksum": "d489b03126f5546ca337c75628b05e04cb2c48bf5ba2ea72d73347c61775f0a1"
    },
    "maven": {
      "version": "3.9.9",
      "arch": "all",
      "url": "https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip",
      "checksum_type": "sha512",
      "checksum": "8beac8d11ef208f1e2a8df0682b9448a9a363d2ad13ca74af43705549e72e74c9378823bf689287801cbbfc2f6ea9596201d19ccacfdfb682ee8a2ff4c4418ba"
    },
    "gradle": {
      "version": "8.12.1",
      "arch": "all",
      "url": "https://services.gradle.org/distributions/gradle-8.12.1-bin.zip",
      "checksum_type": "sha256",
      "checksum": "6639537e6b01e389a64765d78a87b3378be260ebcae1df676479f6e2467d130a"
    }
  }
}

Lockfile Operations & Lifecycle

1. Generating or Updating a Lock (jvm lock)

To inspect the current repository’s .jvm.toml, .java-version, and ecosystem state, and write a locked dependency set to .jvm.lock:

jvm lock

If specific candidates or versions are requested:

jvm lock --vendor adoptium 21

2. Validating Workspace Consistency (jvm lock --check)

To verify whether the currently installed toolchains on the local workstation or CI runner match the pinned .jvm.lock without downloading or modifying files:

jvm lock --check

3-State Cryptographic Signature Audit

When checking lockfiles, jvm lock --check evaluates cryptographic signature status into three distinct states:

  1. verified: .jvm.lock.sig is present and was evaluated against an authorized key ($env:JVM_LOCK_SECRET, --secret, or --key-file), passing constant-time HMAC-SHA256 verification. Output reports [ OK ] Cryptographic signature verified and JSON reports "signature_status":"verified","signature_verified":true.
  2. failed: .jvm.lock.sig exists and verification failed against the key (tampered lockfile or invalid signature). Execution fails closed with Exit Code 1, reporting [FAIL] Cryptographic signature verification failed and JSON "signature_status":"failed","signature_verified":false.
  3. not_verified: Either .jvm.lock.sig is absent, or no secret key was provided to perform cryptographic audit. Output reports [ WARN ] Cryptographic signature present but unverified (or skipped) and JSON reports "signature_status":"not_verified","signature_verified":false. The audit never reports signature_verified: true when verification was skipped or unverified.

3. Hermetic CI/CD Provisioning (jvm install --locked)

In CI/CD environments (GitHub Actions, Azure DevOps, Jenkins, GitLab CI), builds should never alter lockfiles or pull unpinned packages:

jvm install --locked

Hermetic Build Verification Pipeline

flowchart TD
    Start(["CI Job: jvm install --locked"]) --> CheckLock{".jvm.lock exists?"}
    CheckLock -- No --> FailNoLock["FAIL: Hermetic build requires .jvm.lock (Exit 1)"]
    CheckLock -- Yes --> CheckSigPolicy{"Enterprise requires signature?"}
    CheckSigPolicy -- Yes --> VerifySig{"Valid .jvm.lock.sig?"}
    VerifySig -- No --> FailSig["FAIL: Cryptographic signature mismatch (Exit 9)"]
    VerifySig -- Yes --> FetchCache{"Found in local CAS Cache?"}
    CheckSigPolicy -- No --> FetchCache
    FetchCache -- Yes --> VerifyCAS["Verify CAS SHA-256 Digest"]
    FetchCache -- No --> Download["Download from archive_url (.part file)"]
    Download --> VerifyDownload["Compute Streaming SHA-256"]
    VerifyDownload --> CompareHash{"Hash matches .jvm.lock sha256?"}
    VerifyCAS --> CompareHash
    CompareHash -- No --> FailHash["FAIL: Checksum mismatch (CWE-494) (Exit 5)"]
    CompareHash -- Yes --> AtomicExtract["Atomically Stage & Point Directory Junction"]
    AtomicExtract --> Success(["PASS: Hermetic Toolchain Provisioned"])

Freezing & Thawing (jvm freeze & jvm thaw)

Teams often balance two competing needs:

  1. Flexibility during active development (floating major versions like 21 to receive automatic minor security updates).
  2. Absolute immutability for releases and compliance audits (pinning exact patch versions like 21.0.6+7).

DiamTek JVM provides dedicated commands to transition smoothly between these states:

Freezing Toolchains (jvm freeze)

Converts floating or major-version specifications in .jvm.toml and .jvm.lock into fully resolved, immutable build locks across every active toolchain:

jvm freeze

Controlled Thawing (jvm thaw)

When beginning a new sprint or maintenance cycle, thaw the project dependencies to allow controlled upgrades:

jvm thaw

Toolchain Freeze Lifecycle State Machine

stateDiagram-v2
    [*] --> FloatingState: Initial Setup (.jvm.toml)
    FloatingState --> FrozenState: jvm freeze / jvm lock
    FrozenState --> ThawedState: jvm thaw
    ThawedState --> FrozenState: jvm freeze
    FrozenState --> CIBuild: jvm install --locked
    CIBuild --> [*]

    state FloatingState {
        [*] --> MajorVersion: java = "21"
        MajorVersion --> AutoPatches: Discovers latest minor updates
    }
    state FrozenState {
        [*] --> PinnedHash: version = "21.0.6+7"
        PinnedHash --> ImmutableSha: sha256 = "d489b031..."
        ImmutableSha --> SigCheck: .jvm.lock.sig (HMAC Validated)
    }

Cryptographic Anti-Tampering Signatures (.jvm.lock.sig)

The Threat Model

If a malicious actor or compromised dependency achieves commit access to a repository, they could alter both the archive_url and the sha256 in .jvm.lock simultaneously. Standard checksum validation would succeed, allowing malicious binaries into corporate build pipelines (CWE-494).

HMAC-SHA256 Signatures

DiamTek JVM mitigates this by providing cryptographic signatures stored alongside the lockfile in .jvm.lock.sig.

flowchart LR
    Lock[".jvm.lock<br>(Build Dependency Payload)"] --> HMAC["HMAC-SHA256 Engine<br>[ Managed Secret Key ]"]
    HMAC --> Sig[".jvm.lock.sig<br>(Hex Authentication Digest)"]

[!IMPORTANT] Hardcoded Secret Immunity (CWE-798 Elimination): DiamTek JVM strictly forbids hardcoded fallback secrets. Signing and verification require an explicitly managed secret key. If no secret is provided via environment variable or CLI parameter, jvm lock --sign and jvm lock --verify immediately fail closed with exit code 1 citing CWE-798.

1. Signing a Lockfile (jvm lock --sign)

Enterprise release engineers or authorized CI bots sign the verified lockfile using a managed secret:

:: Via environment variable:
set JVM_LOCK_SECRET=secret-enterprise-hmac-key-string
jvm lock --sign

:: Or via direct CLI secret flag:
jvm lock --sign --secret "secret-enterprise-hmac-key-string"

:: Or via secret key file:
jvm lock --sign --key-file "C:\Keys\lockfile.secret"

This generates .jvm.lock.sig containing the HMAC-SHA256 digest of .jvm.lock.

2. Verifying a Lockfile Signature (jvm lock --verify)

To verify the integrity and provenance of .jvm.lock:

:: Using active environment secret:
jvm lock --verify

:: Or using specific secret key:
jvm lock --verify --secret "secret-enterprise-hmac-key-string"

Cryptographic Signature Verification Sequence

sequenceDiagram
    autonumber
    participant Dev as Developer / CI Agent
    participant JVM as DiamTek JVM Engine
    participant Lock as .jvm.lock File
    participant Sig as .jvm.lock.sig File
    participant Sec as Key Provider ($env:JVM_LOCK_SECRET / --secret / --key-file)

    Dev->>JVM: jvm lock --verify (or jvm install --locked)
    JVM->>Lock: Read Raw Content Bytes
    JVM->>Sig: Read Expected HMAC-SHA256 Hex
    JVM->>Sec: Fetch Active Signing Key
    alt Secret Missing
        JVM-->>Dev: FAIL: CWE-798 Secret Required (Exit 1 / Fail-Closed)
    else Secret Provided
        JVM->>JVM: Compute HMAC-SHA256(LockBytes, Key)
        JVM->>JVM: Constant-Time Comparison(Computed, Expected)
        alt Signature Matches
            JVM-->>Dev: PASS: Cryptographic Integrity Confirmed (Exit 0)
        else Signature Mismatches or Key Unauthorized
            JVM-->>Dev: FAIL: Tampering Detected (Exit 1 / Fail-Closed)
        end
    end

3. Enterprise Policy Enforcement

When require_signed_lockfile = true is set in %ProgramData%\DiamTek\JVM\policy.toml, any invocation of jvm install --locked or jvm use strictly mandates valid cryptographic signatures before activating any JDK.


← Back to Documentation Overview