7.2 VEX blast radius + ACS

On this page you prove two closing facts. Trusted Profile Analyzer shows the Track 2 library CVE as remediated by the Lightwell pin. The pipeline’s Advanced Cluster Security check is actually running.

Track 7 is continuous compliance. This is the second page. You download the GAV-bound CycloneDX and the scored OSV for the pin you set on 2.2 Remediated pin, ingest them, and write a blast-radius report whose remediation token is via-lightwell-pin. Hummingbird and Red Hat CSAF are the operating-system layer. They are a callout, not the Check. The live CSAF importer stays off.

Task acs-image-check has to come back passed or failed. A skipped result fails the Check. Admission was 6.1 GitOps + admission. ACS is not that gate.

Why this control exists

Continuous compliance means the system of record can say why the library CVE is closed, and the pipeline scan is on. The library statement is GAV-bound Lightwell Network metadata: OSV LW-DEMO-0002 plus the Maven CycloneDX classifier for commons-lang3 at 3.14.0.rhlw-00001. Quoting a RHEL or Hummingbird CSAF advisory for that library CVE over-claims. The operating-system advisory and the library advisory are different layers.

Scanners and Trusted Profile Analyzer recognize the pin only after you ingest that metadata. Provision does not pre-ingest it. fail-on-skipped: "true" on acs-image-check is what makes a soft-skip fail the task. passed and failed both prove the control ran.

A Clearinghouse Premier member advisory ingests the same way. The report still says the remediation is the Lightwell pin, including a member version. It does not say the upstream line was fixed, and it does not say a Hummingbird CSAF closed a library CVE. The public OSV on this Check is the post-disclosure Network state. During a Premier embargo, that advisory would stay inside the member set, off public scanner feeds, until disclosure. ACS can still scan the image.

Library Lightwell GAV VEX versus OS-layer Hummingbird CSAF

The figure is the two layers. This page scores the library layer: the .rhlw-* GAV from 2.2. The operating-system layer is Hummingbird CSAF. Leave it unscored.

End-state trust chain: Hummingbird digest

The chain is the workshop in one picture. The Hummingbird digest, the Lightwell GAV, the signed application image, and this VEX statement are the four names you can now point at.

A Python pin carries the same idea: VEX or SPDX travels with a +rhlw.* version on requirements.txt. Artifactory can store the same CDX and VEX classifiers beside the Maven GAV. Artifactory is not installed here. This Check downloads from Nexus Remediated.

In a customer engagement, VEX travels with the remediated GAV. After disclosure that VEX is public, which is this Check. During a Premier embargo it stays in the member set. You pull the public Network files from the enterprise proxy and put them in the system of record. Red Hat CSAF remains the other layer.

Learning objectives

By the end of this module, you will be able to:

  • Download the scored CycloneDX classifier and OSV LW-DEMO-0002 from Nexus and ingest them

  • Write the blast-radius report with id LW-DEMO-0002, the remediated GAV, and via-lightwell-pin

  • Contrast that library statement with OS-layer Hummingbird CSAF, including a Premier advisory that is not public yet

  • Show acs-image-check as passed or failed

The scored advisory

Success of the userinfo read is id LW-DEMO-0002, GAV org.apache.commons:commons-lang3, the Maven CDX and VEX URLs, the OSV URL, and live_csaf_gate still false. The upload hint and the OS-layer callout come from the analyzer ConfigMap.

Read the scored VEX coordinates
oc -n lightwell-repo get configmap demo-userinfo-lightwell-repo \
  -o jsonpath='id={.data.scored_vex_id}{"\n"}gav={.data.scored_vex_gav}{"\n"}cdx={.data.scored_vex_maven_cdx}{"\n"}vex={.data.scored_vex_maven_vex}{"\n"}osv={.data.scored_vex_osv}{"\n"}csaf={.data.live_csaf_gate}{"\n"}'
oc -n trusted-profile-analyzer get configmap rhtpa-ingestion-info \
  -o jsonpath='{.data.upload_hint}{"\n"}{.data.os_layer_callout}{"\n"}'

The block below is a different advisory, on spring-core, claiming the upstream line was fixed. A blast-radius ConfigMap that uses these tokens fails the Check.

# Worked example ONLY — different advisory, different GAV, wrong remediation.
vulnerability_id: LW-DEMO-0001
gav: org.springframework:spring-core:5.3.18.rhlw-00003
status: fixed
remediation: via-upstream

Your change

Download the Maven classifier cdx from the userinfo URL on Nexus Remediated, and POST it to /api/v3/sbom. The companion -vex.json classifier is OpenVEX. Trusted Profile Analyzer does not accept OpenVEX as an SBOM, and it does not accept OpenVEX on /api/v3/advisory. That path takes CSAF, a CVE record, or OSV. Ingest the scored OSV document, scored_vex_osv, file LW-DEMO-0002.json. Leave CSAF unscraped. Leave OpenVEX off /api/v3/sbom.

The token request is the same client you used on 7.1. Success is an HTTP success code for the CycloneDX POST and an HTTP success code for the OSV POST. live_csaf_gate stays false.

Download and ingest the GAV documents
CDX_URL="$(oc -n lightwell-repo get configmap demo-userinfo-lightwell-repo -o jsonpath='{.data.scored_vex_maven_cdx}')"
OSV_URL="$(oc -n lightwell-repo get configmap demo-userinfo-lightwell-repo -o jsonpath='{.data.scored_vex_osv}')"
curl -fsSL -o ~/commons-lang3-cdx.json "${CDX_URL}"
curl -fsSL -o ~/LW-DEMO-0002.json "${OSV_URL}"
export OIDC_ISSUER="$(oc -n sso get configmap demo-userinfo-keycloak -o jsonpath='{.data.oidc_issuer}')"
export RHTPA_URL="$(oc -n trusted-profile-analyzer get configmap rhtpa-ingestion-info -o jsonpath='{.data.server_url}')"
export TPA_USER="$(oc -n sso get configmap demo-userinfo-keycloak -o jsonpath='{.data.workshop_username}')"
: "${TPA_PASS:=$(oc -n sso get configmap demo-userinfo-keycloak -o jsonpath='{.data.workshop_password}')}"
export CLI_SECRET="$(oc -n trusted-profile-analyzer get secret tpa-realm-cli-clients -o jsonpath='{.data.cli}' | base64 -d)"
TOKEN="$(curl -sk -X POST "${OIDC_ISSUER}/protocol/openid-connect/token" \
  -d grant_type=password -d client_id=cli -d client_secret="${CLI_SECRET}" \
  -d username="${TPA_USER}" -d password="${TPA_PASS}" -d scope=openid \
  | jq -r .access_token)"
curl -sk -X POST -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @"${HOME}/commons-lang3-cdx.json" \
  -w '\nCDX HTTP %{http_code}\n' \
  "${RHTPA_URL%/}/api/v3/sbom"
curl -sk -X POST -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @"${HOME}/LW-DEMO-0002.json" \
  -w '\nOSV HTTP %{http_code}\n' \
  "${RHTPA_URL%/}/api/v3/advisory"
TPA UI after ingesting GAV-bound VEX for LW-DEMO-0002

The capture is the analyzer after the OSV ingest. The advisory you find is LW-DEMO-0002 on org.apache.commons:commons-lang3 at 3.14.0.rhlw-00001.

The scored report is ConfigMap stub-18-blast-radius in namespace lightwell-repo, key blast-radius.txt. Extract it, fill the four keys, and write it back. A remaining REPLACE_ME fails the Check. The values are LW-DEMO-0002, the remediated GAV including 3.14.0.rhlw-00001, status fixed (or not_affected when the VEX statement uses that word), and remediation via-lightwell-pin. Upstream 3.14.0 stays affected. LW-DEMO-0001 is the worked example.

vulnerability_id: REPLACE_ME_VEX_ID
gav: REPLACE_ME_GAV
status: REPLACE_ME_STATUS
remediation: REPLACE_ME_VIA

Success of the write-back is a ConfigMap whose text contains the scored id, the remediated GAV, and via-lightwell-pin.

Write the blast-radius report
oc -n lightwell-repo get configmap stub-18-blast-radius \
  -o jsonpath='{.data.blast-radius\.txt}' > ~/track-7-2-blast-radius.txt
# edit ~/track-7-2-blast-radius.txt, then:
oc -n lightwell-repo create configmap stub-18-blast-radius \
  --from-file=blast-radius.txt=$HOME/track-7-2-blast-radius.txt \
  --dry-run=client -o yaml | oc apply -f -

ACS needs a token the pipeline can mount. Job rhacs-ci-token-mint in namespace stackrox mints Secret rhacs-ci-secrets and copies it into the build namespace, student_build_namespace. Provision also registers the in-cluster registry with Central. Adding an image integration by hand is unnecessary. On the learner Pipeline, pass fail-on-skipped: "true" on acs-image-check. The seeded default is a soft-skip. Re-run the pipeline if the last TaskRun was skipped. Expect passed or failed. Both prove the control is on. A screenshot of Central is not this Check.

Check

Success is the Nexus GAV files ingested, a report with the scored id, the remediated GAV, and via-lightwell-pin, no REPLACE_ME, an acs-image-check TaskRun that is not skipped, and the CSAF importer still off.

BUILD_NS="$(oc -n gitea get configmap demo-userinfo-gitea -o jsonpath='{.data.student_build_namespace}')"
grep -E 'REPLACE_ME' ~/track-7-2-blast-radius.txt && echo 'STILL HAS PLACEHOLDERS' || echo 'placeholders gone'
grep -E 'LW-DEMO-0002|3.14.0.rhlw-00001|via-lightwell-pin' ~/track-7-2-blast-radius.txt
oc -n lightwell-repo get configmap stub-18-blast-radius \
  -o jsonpath='{.data.blast-radius\.txt}' | grep -E 'LW-DEMO-0002|3.14.0.rhlw-00001|via-lightwell-pin'
oc -n stackrox get job rhacs-ci-token-mint
oc -n "${BUILD_NS}" get secret rhacs-ci-secrets
oc -n "${BUILD_NS}" get tr -l tekton.dev/pipelineTask=acs-image-check
Fill the report

The Job also grades ConfigMap report-18-vex-acs key vex_layer. Set it to gav-bound. Empty or REPLACE_ME fails even if cluster state is correct. Do not copy validate-docs.

oc -n lw-poc-validate edit configmap report-18-vex-acs

The scored Check is Job validate-18-vex-acs in lw-poc-validate. Direct nav URLs still work (honor system). Unlimited retries. There is no Solve.

Run the Validate Job
oc -n lw-poc-validate delete job validate-18-vex-acs --ignore-not-found
TPL='job-18.yaml'
oc -n lw-poc-validate get configmap validate-job-templates \
  -o go-template="{{ index .data \"${TPL}\" }}" | oc create -f -
oc -n lw-poc-validate logs -f job/validate-18-vex-acs

Expect CHECK PASSED: before you continue. CHECK FAILED: names the object to fix. Delete the Job and create it again as often as you need.

The Validate Job grades the report tokens and the ACS TaskRun. That is the last gated page.

Key takeaways

  • The library CVE is remediated because the application pins 3.14.0.rhlw-00001, and the system of record has the OSV that says so.

  • A Hummingbird or RHEL CSAF advisory is the operating-system layer. It does not close this library CVE.

  • A Premier member advisory uses the same ingest. During an embargo that metadata stays off public feeds.

  • ACS on the pipeline is a scan of the image. Unsigned deny remains the 6.1 admission gate.