Series MapLesson 27 / 35
Deepen PracticeOrdered learning track

Learn Java Security Cryptography Integrity Part 027 Build Release Signing Provenance And Slsa

19 min read3701 words
PrevNext
Lesson 2735 lesson track2029 Deepen Practice

title: Learn Java Security, Cryptography and Integrity - Part 027 description: Build and release integrity for Java systems using artifact signing, immutable releases, provenance, CI trust boundaries, SLSA, Sigstore, in-toto, and policy-driven promotion. series: learn-java-security-cryptography-integrity seriesTitle: Learn Java Security, Cryptography and Integrity order: 27 partTitle: Build/Release Signing, Provenance & SLSA tags:

  • java
  • security
  • supply-chain-security
  • slsa
  • provenance
  • sigstore
  • ci-cd
  • release-engineering
  • secure-engineering date: 2026-06-30

Part 027 — Build/Release Signing, Provenance & SLSA

Di Part 026 kita mengamankan dependency yang masuk ke build. Part ini mengamankan artifact yang keluar dari build: JAR/WAR, container image, deployment manifest, SBOM, attestation, dan release evidence. Tujuannya bukan sekadar “build sukses”, tetapi build yang verifiable: siapa yang membangun, dari source mana, dengan builder apa, menghasilkan digest apa, lalu bagaimana artifact tersebut dipromosikan ke production.

Supply-chain security sering gagal bukan karena tidak ada scanner, tetapi karena organisasi tidak bisa menjawab pertanyaan sederhana saat incident:

“Binary yang berjalan di production ini berasal dari commit mana, dibangun oleh pipeline mana, memakai dependency apa, ditandatangani oleh identitas mana, dan apakah ada bukti bahwa artifact ini tidak diubah setelah build?”

Target part ini: kamu mampu mendesain release pipeline Java yang punya artifact integrity, provenance, signing, promotion gates, and audit-grade evidence. Kita tidak mengulang Maven/Gradle basic. Kita fokus ke trust boundary dan release correctness.

Referensi baseline:


1. Kaufman Deconstruction: Skill yang Harus Dikuasai

Build/release integrity bisa dipecah menjadi sub-skill berikut:

  1. Artifact identity — memahami identity artifact sebagai digest, bukan nama/tag semata.
  2. Build trust boundary — mengetahui siapa/apa yang dipercaya: developer, repository, CI runner, secrets, plugin, cache, registry, deployer.
  3. Immutable release discipline — memastikan release tidak berubah setelah dipromosikan.
  4. Signing semantics — membedakan checksum, signature, certificate, transparency log, dan keyless signing.
  5. Provenance literacy — membaca attestation: subject digest, builder identity, source material, invocation, parameters, environment.
  6. SLSA mapping — menerjemahkan SLSA ke control praktis, bukan sekadar badge.
  7. Promotion governance — dev → staging → production memakai artifact sama, bukan rebuild ulang tanpa bukti.
  8. Policy enforcement — menolak deploy jika signature/provenance/SBOM tidak valid.
  9. Incident traceability — menjawab “apa yang terdampak” dari digest, commit, dependency, dan deployment.
  10. Evidence packaging — menghasilkan bukti untuk audit/security review/regulatory defensibility.

Minimal effective practice:

  • Build satu Java service menjadi JAR dan container image.
  • Pin base image by digest.
  • Generate SBOM.
  • Sign image by digest.
  • Generate provenance attestation.
  • Enforce deploy hanya untuk image digest yang punya valid signature + provenance.
  • Simpan release evidence packet.

2. Mental Model: Release Bukan File, Release Adalah Chain of Custody

Artifact production chain:

Security invariant:

Production must run only immutable artifacts whose digest, source, builder, dependencies, and authorization path can be verified.

Jika production deploy memakai my-service:latest, rebuild manual, mutable artifact, shared CI runner tanpa isolation, atau bypass emergency tanpa evidence, chain of custody putus.


3. Artifact Identity: Nama Bukan Identitas

Nama artifact adalah label. Identitas artifact adalah digest.

ObjectWeak identityStronger identity
Maven artifactcom.acme:case-service:1.4.0repository + GAV + checksum/signature + timestamp + provenance
JAR filecase-service.jarSHA-256 digest + signature + source commit attestation
Container imagecase-service:1.4.0OCI digest sha256:... + signature + SBOM + provenance
Helm chartcase-service-1.4.0.tgzchart digest + signed package + referenced image digests
Deployment manifestdeployment.yamlGit commit + manifest digest + reviewed promotion record

Anti-pattern:

image: registry.example.com/case-service:latest

Better:

image: registry.example.com/case-service@sha256:3d4f...

Tag bisa berubah. Digest merepresentasikan content-addressed identity. Release policy harus berbicara dalam digest.


4. Threat Model Build/Release Java

ThreatExampleImpactPrimary Control
Build script tamperingPR mengubah Gradle task untuk exfiltrate tokenCI credential theftprotected branch, review, workflow permissions
CI runner compromiseShared runner menyisakan state/cache berbahayapoisoned artifactephemeral runner, isolation, cache policy
Mutable artifactJAR/image diganti setelah approvalproduction driftimmutable registry, digest pinning
Unsigned releaseTidak ada verifiable producer identityartifact spoofingsigning + verification gate
Provenance forgeryAttestation dibuat oleh actor tidak dipercayafalse assurancetrusted builder identity, transparency, policy
Dependency confusion during buildResolver mengambil artifact publikmalicious code executionrepository allowlist, dependency verification
Build cache poisoningCache memuat output dari input berbedainjected binarycache isolation, content-addressed cache
Secret leakageCI logs/env mengandung tokenlateral movementleast-privilege OIDC, masking, short-lived tokens
Deployment bypassManual kubectl deploy image unknownuncontrolled productionadmission control, RBAC, release gate
Rebuild-on-promoteStaging dan prod menjalankan binary berbedauntraceable behaviorbuild once, promote same digest
Unpinned base imageeclipse-temurin:25-jre berubahsilent driftpin by digest, update deliberately
Artifact repository compromiseRegistry serves modified imagemalicious runtimesignature verification at deploy

5. Release Integrity Invariants

Gunakan invariant berikut sebagai review rubric:

  1. Source invariant — setiap release menunjuk ke immutable source revision.
  2. Builder invariant — release dibangun oleh builder/pipeline yang diizinkan.
  3. Input invariant — dependency, plugin, base image, dan build parameters bisa diketahui.
  4. Output invariant — artifact diidentifikasi dengan cryptographic digest.
  5. Signature invariant — artifact/attestation ditandatangani oleh trusted identity/key.
  6. Provenance invariant — ada bukti machine-readable tentang bagaimana artifact dibuat.
  7. Promotion invariant — environment naik level memakai artifact digest yang sama.
  8. Policy invariant — production deploy menolak artifact yang tidak memenuhi signature/provenance/SBOM policy.
  9. Evidence invariant — release evidence bisa diambil ulang untuk incident dan audit.
  10. Revocation invariant — artifact yang compromised bisa diblokir melalui policy, bukan hanya diumumkan di chat.

6. Build Trust Boundary

CI/CD sering menjadi trust boundary paling kritis karena menyentuh source, credentials, signing identity, registry token, deploy token, SBOM, dan artifact.

Rules:

  • PR dari fork tidak boleh punya akses ke production secrets.
  • Workflow file changes harus direview ekstra ketat.
  • Build runner harus ephemeral untuk release-grade artifact.
  • Token registry/deploy/signing harus short-lived dan scoped.
  • Build output harus immutable begitu keluar dari trusted builder.
  • Release job harus bergantung pada artifact digest, bukan rebuild lokal.

7. Checksums, Signatures, Attestations, and Provenance

Banyak tim mencampur istilah ini. Perbedaannya penting.

MechanismMenjawabTidak menjawab
Checksum“Content ini berubah atau tidak?”“Siapa yang membuat?”
Signature“Identity/key ini menyetujui content ini?”“Bagaimana content dibuat?”
Certificate“Key/identity ini terikat ke subject apa?”“Artifact-nya aman?”
Transparency log“Signature pernah dipublikasikan dan bisa diaudit?”“Code bebas vulnerability?”
SBOM“Komponen apa saja di dalam artifact?”“Artifact dibangun oleh pipeline yang sah?”
Provenance attestation“Artifact dibuat dari source/input/builder apa?”“Semua dependency bebas exploit?”
VEX“Apakah vulnerability tertentu exploitable untuk artifact ini?”“Artifact tidak diubah?”

Signature tanpa provenance hanya mengatakan “seseorang menandatangani artifact”. Provenance tanpa policy hanya menjadi dokumentasi. Policy tanpa enforcement menjadi checklist.


8. Java Artifact Surfaces

Java release bisa menghasilkan banyak artifact:

ArtifactSecurity concern
Thin JARruntime classpath harus dikontrol
Fat/Uber JARshaded dependency bisa menyembunyikan vulnerable code
WAR/EARapp server dependency interaction
Native imagebuild-time dependency/code initialization risk
Container imagebase image, OS packages, user, capabilities
Helm/Kustomize manifestsimage digest, env, secrets, securityContext
SBOMcompleteness dan mapping ke release digest
Provenance attestationbuilder/source identity
Migration scriptsprivileged DB changes
Config bundlefeature flags, endpoint, policy

Invariant:

Release identity must cover every artifact that changes production behavior.

Jangan hanya sign container image sementara migration script atau config bundle bisa mengubah privilege, schema, atau authorization behavior.


9. Build Once, Promote by Digest

Bad release flow:

Problem:

  • Dependency resolution bisa berbeda.
  • Base image bisa berubah.
  • Build plugin bisa menghasilkan output berbeda.
  • Secret/build arg bisa berbeda.
  • Tidak ada jaminan staging artifact sama dengan production artifact.

Better:

Rule:

Build once. Promote the same digest. Environment differences masuk sebagai runtime configuration yang terkontrol, bukan rebuild.


10. SLSA sebagai Maturity Model, Bukan Badge

SLSA membantu mengatur expectation supply-chain integrity. Pakai SLSA untuk memetakan control, bukan sekadar menempel badge di README.

Praktik mapping sederhana:

CapabilityBaselineStronger
Source controlprotected branchbranch protection + signed commits/tags + review policy
Buildscripted CIephemeral isolated trusted builder
Provenancegenerated manuallygenerated by builder, signed, non-forgeable by developer
Artifactnamed by tag/versioncontent-addressed digest
Dependenciesscanner onlyverification + SBOM + provenance input
Deploymanual deploy allowedadmission verifies signature/provenance
Evidencescattered logsrelease evidence packet

SLSA bukan pengganti threat model. SLSA tidak otomatis membuktikan aplikasi bebas vulnerability. Ia membantu membuktikan bahwa artifact yang kamu jalankan berasal dari proses build yang dikontrol.


11. Provenance: Apa yang Harus Dibaca

Sebuah provenance attestation minimal harus membuat kamu bisa menjawab:

  • Artifact digest apa yang menjadi subject?
  • Source repository apa?
  • Commit/ref apa?
  • Builder identity apa?
  • Workflow/pipeline apa?
  • Build trigger apa?
  • Build parameters apa?
  • Dependency/material apa yang dipakai?
  • Waktu build kapan?
  • Siapa/apa yang menandatangani attestation?

Pseudo-shape:

{
  "subject": [
    {
      "name": "registry.example.com/case-service",
      "digest": { "sha256": "..." }
    }
  ],
  "predicateType": "https://slsa.dev/provenance/v1",
  "predicate": {
    "buildDefinition": {
      "buildType": "https://github.com/actions/workflow",
      "externalParameters": {
        "source": "git+https://github.com/acme/case-service@refs/tags/v1.4.0"
      }
    },
    "runDetails": {
      "builder": { "id": "https://github.com/actions/runner/..." }
    }
  }
}

Review question:

Apakah provenance dibuat oleh trusted builder atau oleh script yang bisa diubah developer di PR?

Jika developer bisa mengubah script untuk menghasilkan provenance palsu, provenance tidak punya kekuatan assurance tinggi.


12. Signing Strategy untuk Java Release

Ada beberapa level signing.

12.1 Maven/JAR Publishing Signing

Untuk library publik, ecosystem Maven sering memakai PGP signing karena repository/publishing workflow mengharuskannya. Ini berguna untuk distribusi library, tetapi untuk internal service production biasanya belum cukup karena:

  • signature sering melekat ke artifact library, bukan container runtime;
  • tidak selalu mengikat artifact ke CI builder;
  • tidak otomatis diverifikasi saat deploy;
  • key management PGP sering rapuh di organisasi besar.

Gunakan bila kamu publish library. Jangan anggap ini menggantikan release provenance.

12.2 JAR Signing

jarsigner bisa menandatangani JAR. Ini berguna untuk use case tertentu seperti plugin, applet era lama, atau distribusi komponen yang perlu verifikasi class/resource. Namun untuk microservice containerized, signature JAR jarang menjadi enforcement boundary utama.

Risk:

  • JAR bisa ditandatangani tapi container image berisi entrypoint/config/agent berbahaya.
  • Runtime bisa memuat Java agent atau classpath tambahan di luar signed JAR.
  • Verification harus benar-benar dilakukan sebelum execution.

12.3 Container Image Signing

Untuk service modern, signing container image by digest sering lebih praktis karena deployment unit adalah image.

Example conceptual commands:

# Build and push image
IMAGE="registry.example.com/case-service"
TAG="1.4.0"
docker build -t "$IMAGE:$TAG" .
docker push "$IMAGE:$TAG"

# Resolve immutable digest
DIGEST="$(crane digest "$IMAGE:$TAG")"
REF="$IMAGE@$DIGEST"

# Sign immutable reference
cosign sign "$REF"

# Attach SBOM/provenance as attestations
cosign attest --predicate sbom.cdx.json --type cyclonedx "$REF"
cosign attest --predicate provenance.json --type slsaprovenance "$REF"

Principle:

Sign immutable digest references, not mutable tags.

12.4 Keyless Signing

Keyless signing memakai OIDC identity dari CI dan short-lived certificate. Benefit:

  • tidak menyimpan long-lived private key di CI;
  • identity bisa dikaitkan ke repo/workflow;
  • transparency log bisa membantu audit;
  • rotation burden lebih rendah.

Risk yang tetap harus dikontrol:

  • workflow permissions;
  • branch protection;
  • trusted builder identity;
  • policy verification subject;
  • replay/bypass deploy path.

13. CI Credentials: Prefer Short-Lived, Scoped, and Auditable

Bad:

CI_SECRET_PROD_DEPLOY_TOKEN = long-lived token with cluster-admin
CI_SECRET_SIGNING_KEY = long-lived private key stored in repo/org secret

Better:

  • CI obtains short-lived credentials through OIDC federation.
  • Token scope limited to one repository/workflow/environment.
  • Production deployment requires environment protection/approval.
  • Signing identity is derived from trusted workflow identity.
  • Secrets are not exposed to fork PRs.
  • Logs redact values and disable debug echoing.

CI should be treated like a production system. It can create production code.


14. Build Isolation and Hermeticity

Ideal build properties:

PropertyMeaningWhy it matters
Ephemeralclean machine/container per buildavoids state poisoning
Isolatedbuild cannot see unnecessary networks/secretsreduces exfiltration
Scriptedbuild steps are versionedrepeatable review
Pinnedtool/dependency/base image versions pinnedavoids silent drift
Verifiableoutputs have digest/signature/provenancedeploy can enforce
Reproducible-ishsame inputs tend to same outputeasier audit/diff

Hermetic build penuh sulit untuk banyak Java projects karena Maven/Gradle dependency resolution, plugin downloads, timestamped archives, generated metadata, dan remote repositories. Tetapi kamu tetap bisa bergerak ke arah yang lebih deterministic:

  • gunakan lockfile/dependency verification;
  • pin JDK distribution/version;
  • pin container base image by digest;
  • disable dynamic versions (1.+, latest.release);
  • avoid build-time network selain artifact repositories allowlisted;
  • normalize archive timestamps bila tooling mendukung;
  • jangan embed build machine path/random value ke artifact;
  • simpan build metadata di provenance, bukan tersembunyi di binary.

15. Build Cache Poisoning

Cache mempercepat build, tapi cache juga trust boundary.

Threat:

  • PR berbahaya menulis cache key yang dipakai release build.
  • Cache dari branch tidak dipercaya dipakai protected branch.
  • Build output cache tidak mengikat input digest.
  • Dependency cache berisi artifact tampered.

Controls:

  • pisahkan cache trusted dan untrusted branch;
  • jangan restore release cache dari fork PR;
  • gunakan dependency verification setelah restore cache;
  • cache keyed by lockfile + toolchain + OS + branch trust level;
  • invalidate cache saat build plugin berubah;
  • jangan cache secrets atau generated credentials;
  • release build boleh lebih lambat jika integrity lebih kuat.

16. Base Image Discipline

Bad Dockerfile:

FROM eclipse-temurin:25-jre
COPY target/app.jar /app/app.jar
CMD ["java", "-jar", "/app/app.jar"]

Masalah:

  • tag mutable;
  • user default bisa root;
  • tidak ada digest pinning;
  • tidak ada SBOM/provenance tie-in;
  • tidak ada minimal runtime control.

Better concept:

FROM eclipse-temurin:25-jre@sha256:<pinned-digest>

RUN addgroup --system app && adduser --system --ingroup app app
WORKDIR /app
COPY --chown=app:app target/case-service.jar /app/case-service.jar
USER app:app

ENTRYPOINT ["java", "-jar", "/app/case-service.jar"]

Part 028 akan membahas runtime hardening lebih detail. Di part ini, poin pentingnya: base image adalah build input dan release material. Ia harus masuk SBOM/provenance dan diupdate dengan process yang disengaja.


17. Release Evidence Packet

Setiap production release harus punya evidence packet. Ini bisa berupa folder/object storage record/ticket attachment.

Isi minimum:

release-id: CASE-SERVICE-2026.06.30-001
service: case-service
version: 1.4.0
source-repo: https://github.com/acme/case-service
source-commit: <git-sha>
release-branch/tag: refs/tags/v1.4.0
builder: github-actions://acme/case-service/.github/workflows/release.yml
jdk: 25.0.x
build-tool: Gradle 9.x or Maven 4.x
artifact-digest:
  jar: sha256:...
  image: sha256:...
sbom:
  cyclonedx: sbom.cdx.json sha256:...
provenance:
  slsa: provenance.intoto.jsonl sha256:...
signatures:
  image: cosign signature reference
policy-results:
  dependency-scan: pass/waived
  container-scan: pass/waived
  license-policy: pass/waived
  sast: pass/waived
approvals:
  engineering-owner: ...
  security-exception: ...
deployment:
  staging-digest: sha256:...
  prod-digest: sha256:...
rollback:
  previous-prod-digest: sha256:...

Evidence packet bukan birokrasi. Ia mengurangi MTTR saat incident.


18. Promotion Gates

A release gate harus memutuskan berdasarkan artifact evidence, bukan trust pada manusia yang menjalankan deploy.

Gate example:

Policy examples:

  • image must be referenced by digest;
  • image digest must have valid signature;
  • signing identity must match trusted CI workflow;
  • provenance source repo must match expected repository;
  • source ref must be protected branch or signed release tag;
  • builder id must be from allowed builder set;
  • SBOM must exist and match digest;
  • critical vulnerabilities must be fixed or have approved VEX/waiver;
  • production namespace denies unsigned images.

19. Example: GitHub Actions Release Shape

Conceptual workflow:

name: release

on:
  push:
    tags:
      - "v*"

permissions:
  contents: read
  id-token: write
  packages: write

jobs:
  build:
    runs-on: ubuntu-latest
    environment: release
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: "25"

      - name: Build and test
        run: ./gradlew clean test bootJar --no-daemon

      - name: Generate SBOM
        run: ./gradlew cyclonedxBom --no-daemon

      - name: Build image
        run: |
          docker build -t ghcr.io/acme/case-service:${GITHUB_REF_NAME} .
          docker push ghcr.io/acme/case-service:${GITHUB_REF_NAME}

      - name: Resolve digest
        id: digest
        run: |
          DIGEST=$(crane digest ghcr.io/acme/case-service:${GITHUB_REF_NAME})
          echo "image=ghcr.io/acme/case-service@${DIGEST}" >> "$GITHUB_OUTPUT"

      - name: Sign image
        run: cosign sign --yes "${{ steps.digest.outputs.image }}"

      - name: Attest SBOM
        run: |
          cosign attest --yes \
            --predicate build/reports/bom.json \
            --type cyclonedx \
            "${{ steps.digest.outputs.image }}"

Hardening notes:

  • Pin third-party actions by commit SHA for stricter assurance.
  • Restrict workflow permissions; default token should not be broad.
  • Use environment protection for release/prod.
  • Do not expose secrets to fork PRs.
  • Prefer OIDC federation over static cloud credentials.
  • Ensure provenance is generated by trusted builder, not hand-written script when higher assurance is required.

20. Policy-as-Code Examples

Policy language can be OPA/Rego, Kyverno, admission controller config, or platform-specific rules. The important part is semantic.

Pseudo-policy:

package release.policy

default allow = false

allow {
  input.image.digest != ""
  input.signature.verified == true
  input.signature.identity in data.trusted_signers
  input.provenance.verified == true
  input.provenance.source_repo == "https://github.com/acme/case-service"
  input.provenance.builder_id in data.trusted_builders
  input.sbom.exists == true
  input.vulnerability_policy.status == "pass"
}

Policy should produce a decision with reason:

{
  "allow": false,
  "reason": "image signature identity does not match trusted release workflow",
  "artifact": "registry.example.com/case-service@sha256:..."
}

Audit-grade systems need explainable denial, not just “403”.


21. Release Signing Failure Modes

FailureWhy it is dangerousFix
Signing mutable tagLater tag update invalidates assumptionsign digest
Signature verified but identity ignoredAny signer acceptedverify expected identity/key
Provenance exists but not verifiedAttestation spoof possibleverify signature + subject digest
Signing key in CI secretkey theft compromises all future releasesuse KMS/HSM/keyless or scoped key
Manual emergency deploy bypasses gateattacker waits for exception pathcontrolled break-glass with evidence
SBOM generated from source, not artifactSBOM mismatchgenerate/attach to final artifact
Rebuild per environmentprod artifact differs from tested artifactbuild once, promote digest
Allow latest tagsilent updatedigest pinning
Untrusted cachebuild output influenced by PRcache isolation
No revocation/blocklistcompromised artifact remains deployabledenylist digest/signature policy

22. VEX and Vulnerability Exceptions

A vulnerability finding is not always exploitable in a specific artifact. VEX helps encode statements like:

  • not affected;
  • affected;
  • fixed;
  • under investigation.

But VEX can become dangerous if used as “paper shield”. Require:

  • exact product/artifact digest;
  • vulnerability ID;
  • justification;
  • reviewer;
  • expiration date;
  • compensating controls;
  • re-evaluation trigger when code path/config changes.

Good exception:

vulnerability: CVE-20xx-yyyy
artifact: registry.example.com/case-service@sha256:...
status: not_affected
justification: vulnerable module is not packaged in final image
validated_by: security-review-1234
expires: 2026-08-31

Bad exception:

CVE ignored because scanner noisy.

23. Reproducible Builds: Useful, But Not a Silver Bullet

Reproducible builds mean independent builds can produce identical output from same source/input. Benefit:

  • detects hidden build influence;
  • improves auditability;
  • strengthens confidence in release process;
  • helps compare source vs binary.

Java challenges:

  • timestamps in JAR metadata;
  • generated build-info properties;
  • file ordering;
  • OS path differences;
  • annotation processors;
  • plugin versions;
  • embedded Git/build time;
  • native dependencies.

Practical target:

  • deterministic archive configuration;
  • fixed build timezone/locale;
  • pinned toolchain;
  • no dynamic dependency versions;
  • stable generated metadata;
  • provenance records unavoidable non-determinism.

Even if builds are not fully reproducible, provenance + signing + policy still provide strong operational assurance.


24. Secure Release ADR Template

# ADR: Release Integrity for case-service

## Context
case-service handles enforcement case evidence and regulatory workflow decisions. Production releases must be traceable to approved source and immutable artifact digest.

## Decision
- Build once in trusted CI from protected release tag.
- Produce JAR, container image, SBOM, and SLSA provenance.
- Sign final image by digest using CI OIDC identity.
- Production deployment references image digest only.
- Admission policy verifies signature, source repo, builder id, and SBOM existence.
- Emergency deploy requires break-glass approval and post-release evidence packet within 24 hours.

## Security Invariants
- No mutable tag in production.
- No unsigned image in production.
- No artifact without source commit mapping.
- No rebuild during promotion.

## Consequences
- Release pipeline is slightly slower.
- Manual hotfix path is constrained.
- Incident traceability improves.

25. Java-Specific Release Review Checklist

Source and Build

  • Release source is protected branch or signed tag.
  • Workflow changes require code owner review.
  • Build uses pinned JDK distribution/version.
  • Maven/Gradle wrapper is checked in and verified.
  • Dynamic dependency versions are disallowed.
  • Dependency verification or lock metadata is enabled.
  • Build plugins are reviewed as trusted code.
  • Annotation processors are explicitly allowed.

Artifact

  • JAR/WAR digest recorded.
  • Container image digest recorded.
  • Image references base image by digest.
  • SBOM generated from final artifact/image.
  • Shaded dependencies are represented in SBOM or documented.
  • Build metadata does not leak secrets.

Signing and Provenance

  • Image/JAR/significant artifacts are signed.
  • Signature is over digest, not mutable tag.
  • Provenance subject digest matches final artifact.
  • Provenance builder is trusted.
  • Signing identity is scoped to release workflow.
  • Keyless/KMS/HSM strategy has rotation/revocation model.

Promotion

  • Staging and production use same digest.
  • Production manifest pins digest.
  • Admission policy verifies signature/provenance.
  • Emergency bypass is logged and reviewed.
  • Release evidence packet is stored.

26. Lab: Build a Verifiable Java Release

Goal: produce a minimal release evidence packet.

Steps:

  1. Pick a Java service.
  2. Generate JAR.
  3. Generate SBOM.
  4. Build container image.
  5. Push image to registry.
  6. Resolve image digest.
  7. Sign image digest.
  8. Attach SBOM attestation.
  9. Generate provenance attestation.
  10. Create release-evidence.md with source commit, artifact digest, SBOM path, signature reference, provenance path, and deployment environment.

Expected output:

release-evidence/
  release.md
  sbom.cdx.json
  provenance.intoto.jsonl
  image-digest.txt
  policy-result.json

Stretch:

  • reject deployment if image uses tag without digest;
  • reject if signature identity mismatch;
  • reject if provenance source repo mismatch.

27. Interview-Level Questions

  1. Why is signing :latest weaker than signing @sha256?
  2. What does provenance prove that a signature alone does not?
  3. Why is CI runner isolation part of artifact integrity?
  4. How can build cache poisoning affect release integrity?
  5. Why is “build again in production” an anti-pattern?
  6. What is the difference between SBOM and VEX?
  7. Why can a signed artifact still be vulnerable?
  8. What controls prevent manual deploy bypass?
  9. How would you respond if a signing identity is compromised?
  10. How do you prove which customers were affected by a vulnerable image digest?

28. Common Anti-Patterns

Anti-patternCorrection
“CI passed, so artifact is trusted”CI must produce verifiable signed output
“We use tags for release identity”use digest for production identity
“We have SBOM, therefore secure”SBOM is inventory, not assurance by itself
“Only security team can approve release security”platform should enforce policy automatically
“Emergency deploy can bypass everything”break-glass must be controlled and auditable
“Provenance generated by arbitrary script is enough”provenance must be tied to trusted builder identity
“Signing key is just another CI secret”use KMS/HSM/keyless with scoped identity
“Staging rebuild is close enough”promote same digest
“Scanner found nothing, ship it”scanner is one control, not complete proof
“Release evidence lives in Slack”store structured evidence packet

29. Summary

Build/release integrity is about preserving trust from source to production. For Java systems, that means treating JARs, images, manifests, SBOMs, provenance, and release approvals as one coherent chain of custody.

Core takeaways:

  • Artifact identity is digest, not name or tag.
  • Build once; promote the same digest.
  • Sign immutable artifact references.
  • Generate provenance that binds artifact to source and builder.
  • CI is a high-trust production system.
  • SBOM is inventory; signature is integrity/identity; provenance is origin/process evidence.
  • SLSA is a control map, not a magic badge.
  • Production deploy should enforce signature/provenance/SBOM policy automatically.
  • Release evidence must survive incident response and audit.

Next part: Container, Cloud Runtime & JVM Hardening — how to run trusted artifacts with minimum runtime blast radius.

Lesson Recap

You just completed lesson 27 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.