7.2 VEX blast radius + ACS
- Overview
- Why it matters
- What does it solve
- Layer map (library VEX vs OS CSAF)
- Discover the scored VEX (not the spring-core sample)
- Worked example (not the Check)
- Your change: download, ingest, report, ACS on
- Check: report tokens + ACS not skipped
- Official documentation
- Callouts (not Checks)
- Key takeaways
Overview
You ingest Lightwell GAV-bound CycloneDX and OSV for the Track 2 pin into Trusted Profile Analyzer. Then you write a blast-radius report. That advisory is remediated via the Lightwell pin, not still-open upstream. The ACS task acs-image-check must not be skipped. Hummingbird and Red Hat CSAF are an OS-layer callout. They are not this Check. The live CSAF importer stays off.
ACS is not the admission gate. That was 6.1.
Why it matters
Scanners stay red unless the system of record knows the library CVE is remediated because you pinned Lightwell. ACS must actually run in the pipeline. Do not quote RHEL CSAF for a library CVE.
You download from Nexus, ingest into TPA (/api/v3/sbom and /api/v3/advisory), and record blast-radius tokens (via-lightwell-pin) so scanners and TPA recognize the pin. Setting fail-on-skipped to true proves the ACS control is not a stub.
Lightwell Clearinghouse Premier member advisories ingest the same way. The report would still say via-Lightwell-pin (member version), never via-upstream and never via-Hummingbird-CSAF. Public OSV and VEX on this lab are the post-disclosure Network state. During a Premier embargo, that advisory would stay member-private until disclosure. ACS can still scan the image.
What does it solve
-
Scanner noise with no GAV-bound VEX
-
ACS left out or skipped
-
Mixing OS-layer CSAF with library VEX
Layer map (library VEX vs OS CSAF)
Do not quote RHEL or Hummingbird CSAF for a library CVE. The library layer is the .rhlw-* GAV you pinned in 2.2.
Discover the scored VEX (not the spring-core sample)
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"}'
-
Scored:
LW-DEMO-0002/org.apache.commons:commons-lang3/3.14.0.rhlw-00001
Worked example (not the Check)
Spring-core / LW-DEMO-0001 and “fixed upstream.” If the blast-radius ConfigMap uses these tokens, the Check fails.
# 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, ingest, report, ACS on
-
Download Maven classifier
cdxfrom the userinfo URL (Nexus Remediated) and POST it to TPA/api/v3/sbom. The companion-vex.jsonclassifier is OpenVEX — TPA does not accept OpenVEX as an SBOM or as/api/v3/advisory(that path is CSAF, CVE, or OSV only). Ingest the scored OSV document instead (scored_vex_osv/LW-DEMO-0002.json). Do not scrape CSAF. Do not POST OpenVEX to/api/v3/sbom. -
Upload the CycloneDX file to
/api/v3/sbomand the OSV file to/api/v3/advisory(same SoR as 7.1). Provision does not pre-ingest them. Keeplive_csaf_gate=false.
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"
-
Write ConfigMap
stub-18-blast-radius(extract, fill, write back). Placeholders fail. Allowed tokens (the Check grades these):
vulnerability_id: REPLACE_ME_VEX_ID
gav: REPLACE_ME_GAV
status: REPLACE_ME_STATUS
remediation: REPLACE_ME_VIA
Fill with LW-DEMO-0002, the remediated GAV (include 3.14.0.rhlw-00001), status fixed (or not_affected if the VEX statement uses that), and remediation via-lightwell-pin. Do not claim the upstream 3.14.0 is fixed. Do not use LW-DEMO-0001.
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: confirm Job
rhacs-ci-token-mintinstackroxis Complete. That Job mints Secretrhacs-ci-secretsand copies it into your build namespace (student_build_namespace) soacs-image-checkcan mount it. Provision also registers the in-cluster registry with Central — do not add an image integration by hand. On the learner Pipeline, passfail-on-skipped: "true"onacs-image-check(seeded default is soft-skip). Re-run if the last TaskRun wasskipped. Expectpassedorfailed— both prove the control is on. Do not screenshot Central as this Check.
Check: report tokens + ACS not skipped
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
Pass when: Nexus GAV files were ingested; the report has the scored id + GAV + via-Lightwell token and no REPLACE_ME; acs-image-check is not skipped; CSAF importer is still off.
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.
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.
Official documentation
-
Trusted Profile Analyzer overview (SBOM and advisory ingest)
-
Patch delivery lifecycle (this Check is public Disclosure / OSV / VEX)
Callouts (not Checks)
-
Hummingbird / RHEL CSAF = OS layer. Do not score it.
-
PyPI VEX/SPDX is the same “metadata travels with the pin” idea (
+rhlw.*onrequirements.txt). This Check is the Maven GAV from Track 2. -
Artifactory can host the same GAV-bound CDX/VEX classifiers beside the Maven GAV (local/generic or the remote cache). It is not installed here. This Check downloads from Nexus Remediated.
Key takeaways
-
Advisory metadata travels with the
.rhlw-*GAV you pin. Lightwell Network is post-disclosure. Premier member versions use the same ingest and stay embargoed until disclosure. -
Quoting OS-layer CSAF for a library CVE is the wrong layer.
-
ACS on is a pipeline control. It is not the 6.1 admission gate.
cd ~/ocp5-rhacs-showroom
bash setup/lab-cleanup.sh --module tssc-18


