🏠 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).
- The Reproducible Build Problem
- The
.jvm.lockv2 Specification - Lockfile Operations & Lifecycle
- Freezing & Thawing (
jvm freeze&jvm thaw) - Cryptographic Anti-Tampering Signatures (
.jvm.lock.sig)
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:
- Adoptium
21.0.2on Monday - Amazon Corretto
21.0.5on Wednesday - Microsoft
21.0.6+7on Friday
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).
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.
{
"$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"
}
}
}To inspect the current repository's .jvm.toml, .java-version, and ecosystem state, and write a locked dependency set to .jvm.lock:
jvm lockIf specific candidates or versions are requested:
jvm lock --vendor adoptium 21To 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- Returns Exit Code 0 if all tools, versions, and SHA-256 checksums match.
- Returns Exit Code 1 (or
5: Checksum Mismatch) if discrepancies, unpinned tools, or signature tampering are found. - Supports
--jsonenvelope for CI/CD automation pipelines.
When checking lockfiles, jvm lock --check evaluates cryptographic signature status into three distinct states:
verified:.jvm.lock.sigis 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 verifiedand JSON reports"signature_status":"verified","signature_verified":true.failed:.jvm.lock.sigexists and verification failed against the key (tampered lockfile or invalid signature). Execution fails closed with Exit Code 1, reporting[FAIL] Cryptographic signature verification failedand JSON"signature_status":"failed","signature_verified":false.not_verified: Either.jvm.lock.sigis 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 reportssignature_verified: truewhen verification was skipped or unverified.
In CI/CD environments (GitHub Actions, Azure DevOps, Jenkins, GitLab CI), builds should never alter lockfiles or pull unpinned packages:
jvm install --locked- Reads
.jvm.lockstrictly. - Fails closed immediately if
.jvm.lockis missing. - Fails closed if the lockfile's declared SHA-256 digest does not match the downloaded archive.
- Installs and activates the exact vendor and binary version specified.
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"])
Teams often balance two competing needs:
- Flexibility during active development (floating major versions like
21to receive automatic minor security updates). - 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:
Converts floating or major-version specifications in .jvm.toml and .jvm.lock into fully resolved, immutable build locks across every active toolchain:
jvm freeze- Authentic Distribution Archive Checksums: Queries upstream vendor distribution APIs (e.g. Adoptium API v3) or candidate catalogs to resolve genuine distribution archive download URLs (
https://...) and official archive checksums (SHA-256/SHA-512). - Strict Elimination of File-Level Hashing Fallbacks: Strictly eliminates hashing of installed local files (such as
release,bin\java.exe, or<tool>.bat). Becausejvm install --lockedverifies the downloaded distribution archive before extraction, lockfile entries require valid distribution archive checksums. - Lockfile Metadata Preservation: Preserves all existing lockfile properties (
url,arch,checksum_type, etc.) when refreshing frozen coordinates. - Fail-Closed Guarantee: If genuine archive URLs or trusted distribution checksums cannot be resolved,
jvm freezefails closed immediately without modifying.jvm.lock. - Prevents any implicit upgrading or mirror substitution until thawed.
When beginning a new sprint or maintenance cycle, thaw the project dependencies to allow controlled upgrades:
jvm thaw- Relaxes exact patch and build coordinates back to major semantic versions (e.g.
21.0.6+7──>21). - Preserves vendor preferences (e.g.
adoptium). - Re-enables discovery of the latest upstream LTS security releases.
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)
}
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).
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.
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.
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"- Computes the HMAC-SHA256 digest of
.jvm.lockusing the active key. - Compares against
.jvm.lock.sigusing constant-time comparison. - If the signature is invalid or
.jvm.lockhas been altered, execution aborts with:[ ERROR ] Cryptographic signature verification failed for .jvm.lock. The lockfile has been altered or signed with an unauthorized key.
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
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.