feat: integrate Red Hat Trusted Software Supply Chain (TSSF)#206
Conversation
Enable supply-chain compliance for ImageBuild pipelines by adding SBOM generation (Syft), Tekton Chains result contract (IMAGE_URL/IMAGE_DIGEST), and traceability metadata in build status. Closes centos-automotive-suite#204 Made-with: Cursor
|
Architecture context: ADR-001: Integrate Red Hat Trusted Software Supply Chain |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Made-with: Cursor
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (1)
docs/adr/001-tssf-integration.md (1)
124-134: Minor: ADR ComplianceConfig differs slightly from implementation.The ADR shows
TrustedArtifactSignerURLin theComplianceConfigstruct, but the actual implementation inapi/v1alpha1/operatorconfig_types.gohas separateRekorURLandFulcioURLfields instead. Additionally, the implementation includes aSyftImagefield not shown here.This is acceptable since ADRs capture intent at decision time and implementations may evolve, but consider updating the ADR to match the final implementation for documentation accuracy.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/adr/001-tssf-integration.md` around lines 124 - 134, The ADR's ComplianceConfig struct is out of sync with the implementation: replace the single TrustedArtifactSignerURL field with the separate RekorURL and FulcioURL fields and add the missing SyftImage field so the ADR reflects the actual implementation; update the struct declaration for ComplianceConfig and its JSON tags to match the identifiers used in the code (ComplianceConfig, RekorURL, FulcioURL, SyftImage, SBOMFormat, SBOMTaskBundle, ECPolicyRef) so the ADR and operatorconfig_types.go stay consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@api/v1alpha1/imagebuild_types.go`:
- Around line 181-205: The doc comments for ArtifactRef incorrectly state that
registry/digest are populated only when "compliance is enabled"; update the
comments for ArtifactRef and the other occurrence referencing the same behavior
so they match controller behavior: state that status.artifact.registry and
status.artifact.digest are set for any successful registry push, while SBOMRef,
SignatureRef, and ProvenanceRef are populated when their respective features
(SBOM, signing/Sigstore, provenance/Tekton Chains) are produced; reference
ArtifactRef and the fields Registry, Digest, SBOMRef, SignatureRef,
ProvenanceRef and status.artifact to locate the comments and change the wording
accordingly.
In `@api/v1alpha1/zz_generated.deepcopy.go`:
- Around line 55-68: This PR accidentally includes generated deepcopy code
(e.g., the ArtifactRef DeepCopyInto and DeepCopy functions) and generated CRD
manifests; drop those hunks from the change set by reverting the generated
zz_generated.deepcopy.go edits (restore the file to the upstream/generated state
or remove it from the commit) and remove any config/crd/bases/*.yaml CRD
manifests from the PR; ensure the generated outputs remain ignored (keep them
out of source control) and only commit changes to the source API types (then run
the generator separately if you need updated generated output).
In `@internal/common/tasks/scripts/push_artifact.sh`:
- Around line 338-341: The script extracts the image digest into pushed_digest
from oras output and writes it to results.IMAGE_DIGEST.path but doesn’t validate
it; if empty the task incorrectly reports success. After computing pushed_digest
(the grep/awk pipeline that sets pushed_digest) add a validation check that it
is non-empty and matches the expected sha256:hex pattern, and fail/exit with a
non-zero status and an error log if validation fails; apply the same validation
logic to the other push branch that writes to "$(results.IMAGE_DIGEST.path)"
(the second push path around the other extract/write block) so both push flows
enforce the digest presence before writing IMAGE_DIGEST and IMAGE_URL.
In `@internal/common/tasks/scripts/sbom_generate.sh`:
- Around line 54-56: The SBOM result currently writes only image_url to
result_path; change sbom_generate.sh to capture the actual SBOM artifact
reference produced by the attach operation and write that full OCI ref to
SBOM_URI: run the oras attach command (or reuse the existing variable that
captures its stdout), parse its output to extract the SBOM digest (as done in
push_artifact.sh), then set sbom_ref to the combined reference (e.g.,
image_url@<digest>) and write sbom_ref to result_path instead of just image_url;
look for symbols sbom_ref, image_url, result_path and the oras attach invocation
in sbom_generate.sh to implement this parsing and assignment.
In `@internal/common/tasks/tasks.go`:
- Around line 1475-1484: The docker-config volume uses an OCI image ref as
SecretName ("$(params.IMAGE_URL)"), which is invalid; add a parameter named
secret-ref (like in GeneratePushArtifactRegistryTask) and change the Volume's
SecretName to "$(params.secret-ref)"; also update the corresponding PipelineTask
binding that creates this task to pass the secret-ref parameter (replacing the
IMAGE_URL usage) so the task receives a valid Kubernetes secret name for the
docker-config volume.
In `@internal/controller/operatorconfig/controller.go`:
- Around line 668-670: The code only appends tasks.GenerateSBOMTask when
buildConfig.ComplianceEnabled is true, but provides no removal when it flips to
false; update the reconcile/cleanup path to prune the sbom-generate Tekton Task
so cluster state doesn't drift. Add logic either in the same branch (an else
that schedules a deletion/prune for the sbom-generate Task) or modify
cleanupOSBuilds() to include sbom-generate removal, referencing the existing
symbols tasks.GenerateSBOMTask, buildConfig.ComplianceEnabled, tektonTasks and
cleanupOSBuilds() so the controller explicitly deletes the sbom-generate Task
when compliance is disabled.
- Around line 653-658: Add the missing compliance fields to the build pipeline
by (1) adding rekorURL, fulcioURL, and ecPolicyRef to the BuildConfig struct;
(2) wiring config.Spec.Compliance.GetRekorURL(), GetFulcioURL(), and
GetECPolicyRef() into buildConfig in both operatorconfig/controller.go and
imagebuild/controller.go (alongside ComplianceEnabled, SyftImage, SBOMFormat);
and (3) update the task generation code that produces SBOM/compliance tasks (the
routines that create SBOM tasks and the Enterprise Contract gate—e.g., the
generateTasks/createSBOMTask/createECGate call sites) to read
BuildConfig.rekorURL, BuildConfig.fulcioURL and BuildConfig.ecPolicyRef and pass
them into Tekton Chains / EC gate task params so those operator API fields
actually affect execution.
---
Nitpick comments:
In `@docs/adr/001-tssf-integration.md`:
- Around line 124-134: The ADR's ComplianceConfig struct is out of sync with the
implementation: replace the single TrustedArtifactSignerURL field with the
separate RekorURL and FulcioURL fields and add the missing SyftImage field so
the ADR reflects the actual implementation; update the struct declaration for
ComplianceConfig and its JSON tags to match the identifiers used in the code
(ComplianceConfig, RekorURL, FulcioURL, SyftImage, SBOMFormat, SBOMTaskBundle,
ECPolicyRef) so the ADR and operatorconfig_types.go stay consistent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a9f7dbea-de5f-41b1-ba90-244b6619d6c9
⛔ Files ignored due to path filters (2)
config/crd/bases/automotive.sdv.cloud.redhat.com_imagebuilds.yamlis excluded by!config/crd/bases/**config/crd/bases/automotive.sdv.cloud.redhat.com_operatorconfigs.yamlis excluded by!config/crd/bases/**
📒 Files selected for processing (11)
api/v1alpha1/imagebuild_types.goapi/v1alpha1/operatorconfig_types.goapi/v1alpha1/zz_generated.deepcopy.goconfig/samples/automotive_v1_operatorconfig.yamldocs/adr/001-tssf-integration.mdinternal/common/tasks/scripts.gointernal/common/tasks/scripts/push_artifact.shinternal/common/tasks/scripts/sbom_generate.shinternal/common/tasks/tasks.gointernal/controller/imagebuild/controller.gointernal/controller/operatorconfig/controller.go
| // ArtifactRef captures the supply-chain traceability metadata for a build artifact. | ||
| // Populated from PipelineRun results when compliance is enabled. | ||
| type ArtifactRef struct { | ||
| // Registry is the OCI registry URL where the artifact was pushed (IMAGE_URL) | ||
| // +optional | ||
| Registry string `json:"registry,omitempty"` | ||
|
|
||
| // Digest is the content-addressable digest of the pushed artifact (sha256:...) | ||
| // +optional | ||
| Digest string `json:"digest,omitempty"` | ||
|
|
||
| // SBOMRef is the OCI reference to the attached SBOM artifact | ||
| // +optional | ||
| SBOMRef string `json:"sbomRef,omitempty"` | ||
|
|
||
| // SignatureRef is the OCI reference to the cosign/Sigstore signature | ||
| // Populated by Tekton Chains when signing is configured | ||
| // +optional | ||
| SignatureRef string `json:"signatureRef,omitempty"` | ||
|
|
||
| // ProvenanceRef is the OCI reference to the SLSA provenance attestation | ||
| // Populated by Tekton Chains when provenance is configured | ||
| // +optional | ||
| ProvenanceRef string `json:"provenanceRef,omitempty"` | ||
| } |
There was a problem hiding this comment.
Update the API docs to match the controller behavior.
These comments say artifact metadata is populated only when compliance is enabled, but the controller fills status.artifact.registry and status.artifact.digest for any successful registry push. That will mislead users of the new status field.
Also applies to: 257-260
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@api/v1alpha1/imagebuild_types.go` around lines 181 - 205, The doc comments
for ArtifactRef incorrectly state that registry/digest are populated only when
"compliance is enabled"; update the comments for ArtifactRef and the other
occurrence referencing the same behavior so they match controller behavior:
state that status.artifact.registry and status.artifact.digest are set for any
successful registry push, while SBOMRef, SignatureRef, and ProvenanceRef are
populated when their respective features (SBOM, signing/Sigstore,
provenance/Tekton Chains) are produced; reference ArtifactRef and the fields
Registry, Digest, SBOMRef, SignatureRef, ProvenanceRef and status.artifact to
locate the comments and change the wording accordingly.
| // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. | ||
| func (in *ArtifactRef) DeepCopyInto(out *ArtifactRef) { | ||
| *out = *in | ||
| } | ||
|
|
||
| // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArtifactRef. | ||
| func (in *ArtifactRef) DeepCopy() *ArtifactRef { | ||
| if in == nil { | ||
| return nil | ||
| } | ||
| out := new(ArtifactRef) | ||
| in.DeepCopyInto(out) | ||
| return out | ||
| } |
There was a problem hiding this comment.
Drop generated deepcopy hunks from the PR.
This file is generated output, not stable source. Keeping these hunks in the PR adds churn and diverges from the repository’s normal workflow for API generation.
Based on learnings: In centos-automotive-suite/automotive-dev-operator, the files api/v1alpha1/zz_generated.deepcopy.go and all config/crd/bases/*.yaml CRD manifests are explicitly listed in .gitignore and are NOT committed to the repository. PRs should NOT include these generated files.
Also applies to: 366-379, 706-710, 1204-1208
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@api/v1alpha1/zz_generated.deepcopy.go` around lines 55 - 68, This PR
accidentally includes generated deepcopy code (e.g., the ArtifactRef
DeepCopyInto and DeepCopy functions) and generated CRD manifests; drop those
hunks from the change set by reverting the generated zz_generated.deepcopy.go
edits (restore the file to the upstream/generated state or remove it from the
commit) and remove any config/crd/bases/*.yaml CRD manifests from the PR; ensure
the generated outputs remain ignored (keep them out of source control) and only
commit changes to the source API types (then run the generator separately if you
need updated generated output).
| # Extract digest from oras output (format: "Digest: sha256:abc123...") | ||
| pushed_digest=$(echo "$push_output" | grep -i '^Digest:' | awk '{print $2}' | head -1) | ||
| printf '%s' "${repo_url}" > "$(results.IMAGE_URL.path)" | ||
| printf '%s' "${pushed_digest}" > "$(results.IMAGE_DIGEST.path)" |
There was a problem hiding this comment.
Validate the parsed digest before publishing Tekton results.
If oras push succeeds but its output format changes or no Digest: line is emitted, both branches write an empty IMAGE_DIGEST and still continue as if the push succeeded. That breaks the new result contract for the SBOM task and status.artifact.digest.
Suggested fix
pushed_digest=$(echo "$push_output" | grep -i '^Digest:' | awk '{print $2}' | head -1)
+ if [ -z "$pushed_digest" ]; then
+ echo "ERROR: Failed to parse pushed digest from oras output" >&2
+ exit 1
+ fi
printf '%s' "${repo_url}" > "$(results.IMAGE_URL.path)"
printf '%s' "${pushed_digest}" > "$(results.IMAGE_DIGEST.path)"Apply the same check in both push paths.
Also applies to: 407-409
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/common/tasks/scripts/push_artifact.sh` around lines 338 - 341, The
script extracts the image digest into pushed_digest from oras output and writes
it to results.IMAGE_DIGEST.path but doesn’t validate it; if empty the task
incorrectly reports success. After computing pushed_digest (the grep/awk
pipeline that sets pushed_digest) add a validation check that it is non-empty
and matches the expected sha256:hex pattern, and fail/exit with a non-zero
status and an error log if validation fails; apply the same validation logic to
the other push branch that writes to "$(results.IMAGE_DIGEST.path)" (the second
push path around the other extract/write block) so both push flows enforce the
digest presence before writing IMAGE_DIGEST and IMAGE_URL.
| # Write the SBOM reference as a result (image_url with SBOM digest) | ||
| sbom_ref="${image_url}" | ||
| printf '%s' "${sbom_ref}" > "${result_path}" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check oras attach output format to confirm how to parse the SBOM digest
oras version 2>/dev/null || echo "oras not available in sandbox"
# Check if there's documentation or examples of oras attach output parsing in the repo
rg -n "oras attach" --type shRepository: centos-automotive-suite/automotive-dev-operator
Length of output: 219
🏁 Script executed:
cat -n internal/common/tasks/scripts/sbom_generate.sh | sed -n '40,65p'Repository: centos-automotive-suite/automotive-dev-operator
Length of output: 940
🏁 Script executed:
# Check if there are any ADR references or documentation about SBOM artifact references
rg -i "adr.*001|SBOM.*ref|artifact.*digest" --type sh --type md -B 2 -A 2Repository: centos-automotive-suite/automotive-dev-operator
Length of output: 3348
🏁 Script executed:
# Search for documentation about how the result_path or sbom_ref is used
rg -n "result_path|sbom_ref" internal/common/tasks/scripts/sbom_generate.sh -B 2 -A 2Repository: centos-automotive-suite/automotive-dev-operator
Length of output: 561
🏁 Script executed:
# Search for any documentation or examples of oras output parsing
rg -i "oras.*output|oras.*digest|oras.*sha256" --type sh --type mdRepository: centos-automotive-suite/automotive-dev-operator
Length of output: 406
🏁 Script executed:
# Check if there are other places in codebase that use oras and how they handle output
rg -n "oras" --type sh -A 3 -B 1Repository: centos-automotive-suite/automotive-dev-operator
Length of output: 10869
🌐 Web query:
oras attach output format digest sha256
💡 Result:
To output the digest (sha256) of the attached referrer manifest from the oras attach command, use the --format flag with Go template syntax. Example command: oras attach --artifact-type doc/example localhost:5000/hello:v1 hi.txt --format go-template --template "{{.digest}}" This prints only the digest string, e.g., sha256:0afd0f0c35f98dcb607de0051be7ebefd942eef1e3a6d26eefd1b2d80f2affbe. For JSON output including the digest: oras attach --artifact-type doc/example localhost:5000/hello:v1 hi.txt --format json Example JSON: { "reference": "localhost:5000/hello@sha256:0afd0f0c35f98dcb607de0051be7ebefd942eef1e3a6d26eefd1b2d80f2affbe", "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:0afd0f0c35f98dcb607de0051be7ebefd942eef1e3a6d26eefd1b2d80f2affbe", "size": 923, "annotations": { ... }, "artifactType": "doc/example" } The --format option supports text (default), json, and go-template. The digest field is the sha256 digest of the newly created referrer manifest. This is an experimental feature documented in official ORAS CLI docs (version 1.3).
Citations:
- 1: https://oras.land/docs/commands/oras_attach/
- 2: feat: support formatted output in oras attach and push oras-project/oras#1237
- 3: https://oras.land/docs/how_to_guides/format_output/
- 4: https://oras.land/docs/1.2/how_to_guides/format_output
🏁 Script executed:
# Check the exact format of oras attach output by examining push_artifact.sh more closely
sed -n '329,345p' internal/common/tasks/scripts/push_artifact.shRepository: centos-automotive-suite/automotive-dev-operator
Length of output: 730
SBOM_URI result does not contain the actual SBOM artifact reference—violates ADR-001 requirement.
The sbom_ref is set to only image_url, but ADR-001 specifies SBOM_URI must be an "OCI reference to attached SBOM" (see ArtifactRef.SBOMRef). When oras attach creates the referrer artifact, it outputs the SBOM artifact's digest, which must be captured and included in the result for full traceability.
The codebase already has a pattern for this in push_artifact.sh (line 339). Follow the same approach:
♻️ Proposed fix to capture actual SBOM digest
# Use ORAS to attach the SBOM as a referrer (OCI 1.1 referrers API)
-DOCKER_CONFIG="${DOCKER_CONFIG:-}" oras attach \
+attach_output=$(DOCKER_CONFIG="${DOCKER_CONFIG:-}" oras attach \
--artifact-type "${sbom_media_type}" \
"${image_ref}" \
- "${sbom_file}:${sbom_media_type}" 2>&1 || {
+ "${sbom_file}:${sbom_media_type}" 2>&1) || {
echo "ERROR: Failed to attach SBOM to artifact" >&2
exit 1
}
+# Extract SBOM digest from oras output (format: "Digest: sha256:abc123...")
+sbom_digest=$(echo "$attach_output" | grep -i '^Digest:' | awk '{print $2}' | head -1)
+
# Write the SBOM reference as a result (image_url with SBOM digest)
-sbom_ref="${image_url}"
+sbom_ref="${image_url}@${sbom_digest:-unknown}"
printf '%s' "${sbom_ref}" > "${result_path}"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/common/tasks/scripts/sbom_generate.sh` around lines 54 - 56, The
SBOM result currently writes only image_url to result_path; change
sbom_generate.sh to capture the actual SBOM artifact reference produced by the
attach operation and write that full OCI ref to SBOM_URI: run the oras attach
command (or reuse the existing variable that captures its stdout), parse its
output to extract the SBOM digest (as done in push_artifact.sh), then set
sbom_ref to the combined reference (e.g., image_url@<digest>) and write sbom_ref
to result_path instead of just image_url; look for symbols sbom_ref, image_url,
result_path and the oras attach invocation in sbom_generate.sh to implement this
parsing and assignment.
| Volumes: []corev1.Volume{ | ||
| { | ||
| Name: "docker-config", | ||
| VolumeSource: corev1.VolumeSource{ | ||
| Secret: &corev1.SecretVolumeSource{ | ||
| SecretName: "$(params.IMAGE_URL)", | ||
| Optional: ptr.To(true), | ||
| }, | ||
| }, | ||
| }, |
There was a problem hiding this comment.
Critical: Incorrect secret name for docker-config volume.
The SecretName is set to $(params.IMAGE_URL), which will be an OCI image reference (e.g., quay.io/org/repo:tag), not a valid Kubernetes secret name. This will cause the task to fail at runtime when trying to mount the volume.
Compare with GeneratePushArtifactRegistryTask (lines 269-273) which correctly uses $(params.secret-ref) as the secret name.
🐛 Proposed fix: Add secret-ref parameter and use it for docker-config
Params: []tektonv1.ParamSpec{
{
Name: "IMAGE_URL",
Type: tektonv1.ParamTypeString,
Description: "OCI reference to the artifact to scan",
},
{
Name: "IMAGE_DIGEST",
Type: tektonv1.ParamTypeString,
Description: "Digest of the artifact to scan (sha256:...)",
},
{
Name: "sbom-format",
Type: tektonv1.ParamTypeString,
Description: "SBOM output format (spdx-json or cyclonedx-json)",
Default: &tektonv1.ParamValue{
Type: tektonv1.ParamTypeString,
StringVal: automotivev1alpha1.DefaultSBOMFormat,
},
},
+ {
+ Name: "secret-ref",
+ Type: tektonv1.ParamTypeString,
+ Description: "Name of the secret containing registry credentials",
+ Default: &tektonv1.ParamValue{
+ Type: tektonv1.ParamTypeString,
+ StringVal: "",
+ },
+ },
},And update the volume:
Volumes: []corev1.Volume{
{
Name: "docker-config",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
- SecretName: "$(params.IMAGE_URL)",
+ SecretName: "$(params.secret-ref)",
Optional: ptr.To(true),
},
},
},
},Also update the pipeline task binding (lines 1348-1352) to pass the secret-ref:
Params: []tektonv1.Param{
{Name: "IMAGE_URL", Value: tektonv1.ParamValue{Type: tektonv1.ParamTypeString, StringVal: "$(tasks.push-disk-artifact.results.IMAGE_URL)"}},
{Name: "IMAGE_DIGEST", Value: tektonv1.ParamValue{Type: tektonv1.ParamTypeString, StringVal: "$(tasks.push-disk-artifact.results.IMAGE_DIGEST)"}},
{Name: "sbom-format", Value: tektonv1.ParamValue{Type: tektonv1.ParamTypeString, StringVal: "$(params.sbom-format)"}},
+ {Name: "secret-ref", Value: tektonv1.ParamValue{Type: tektonv1.ParamTypeString, StringVal: "$(params.secret-ref)"}},
},🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/common/tasks/tasks.go` around lines 1475 - 1484, The docker-config
volume uses an OCI image ref as SecretName ("$(params.IMAGE_URL)"), which is
invalid; add a parameter named secret-ref (like in
GeneratePushArtifactRegistryTask) and change the Volume's SecretName to
"$(params.secret-ref)"; also update the corresponding PipelineTask binding that
creates this task to pass the secret-ref parameter (replacing the IMAGE_URL
usage) so the task receives a valid Kubernetes secret name for the docker-config
volume.
| // Wire compliance configuration into build config | ||
| if config.Spec.Compliance != nil && config.Spec.Compliance.Enabled { | ||
| buildConfig.ComplianceEnabled = true | ||
| buildConfig.SyftImage = config.Spec.Compliance.GetSyftImage() | ||
| buildConfig.SBOMFormat = config.Spec.Compliance.GetSBOMFormat() | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Usages of compliance URL/policy fields:"
rg -n --type=go '\b(RekorURL|FulcioURL|ECPolicyRef)\b'
echo
echo "Usages of compliance settings propagated into build/task generation:"
rg -n --type=go '\b(ComplianceEnabled|SBOMFormat|SyftImage|RekorURL|FulcioURL|ECPolicyRef)\b'Repository: centos-automotive-suite/automotive-dev-operator
Length of output: 3397
rekorURL, fulcioURL, and ecPolicyRef are defined but unused configuration fields.
These fields are exposed in the OperatorConfig API (api/v1alpha1/operatorconfig_types.go:457-467) but never read or passed to task generation. Only Enabled, SyftImage, and SBOMFormat are wired into BuildConfig and consumed by SBOM task generation. The URL fields (intended for Tekton Chains configuration per their comments) and ECPolicyRef (for Enterprise Contract gate enforcement) have no effect when set by users.
Add these fields to BuildConfig, propagate them in both compliance wiring locations (operatorconfig/controller.go and imagebuild/controller.go), and ensure task generation code consumes them appropriately.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/controller/operatorconfig/controller.go` around lines 653 - 658, Add
the missing compliance fields to the build pipeline by (1) adding rekorURL,
fulcioURL, and ecPolicyRef to the BuildConfig struct; (2) wiring
config.Spec.Compliance.GetRekorURL(), GetFulcioURL(), and GetECPolicyRef() into
buildConfig in both operatorconfig/controller.go and imagebuild/controller.go
(alongside ComplianceEnabled, SyftImage, SBOMFormat); and (3) update the task
generation code that produces SBOM/compliance tasks (the routines that create
SBOM tasks and the Enterprise Contract gate—e.g., the
generateTasks/createSBOMTask/createECGate call sites) to read
BuildConfig.rekorURL, BuildConfig.fulcioURL and BuildConfig.ecPolicyRef and pass
them into Tekton Chains / EC gate task params so those operator API fields
actually affect execution.
| if buildConfig.ComplianceEnabled { | ||
| tektonTasks = append(tektonTasks, tasks.GenerateSBOMTask(config.Namespace, buildConfig)) | ||
| } |
There was a problem hiding this comment.
Prune sbom-generate when compliance is disabled.
Once this task has been created, turning spec.compliance.enabled back to false stops reconciling it but never deletes it. cleanupOSBuilds() also omits sbom-generate, so managed cluster state drifts after disable/cleanup.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@internal/controller/operatorconfig/controller.go` around lines 668 - 670, The
code only appends tasks.GenerateSBOMTask when buildConfig.ComplianceEnabled is
true, but provides no removal when it flips to false; update the
reconcile/cleanup path to prune the sbom-generate Tekton Task so cluster state
doesn't drift. Add logic either in the same branch (an else that schedules a
deletion/prune for the sbom-generate Task) or modify cleanupOSBuilds() to
include sbom-generate removal, referencing the existing symbols
tasks.GenerateSBOMTask, buildConfig.ComplianceEnabled, tektonTasks and
cleanupOSBuilds() so the controller explicitly deletes the sbom-generate Task
when compliance is disabled.
|
This is being worked on in #197 |
- Fix critical: SBOM task volume now uses a dedicated secret-ref param instead of IMAGE_URL as the Secret name - Fix major: sbom_generate.sh captures actual referrer digest from oras attach output for accurate SBOM_URI result - Fix major: push_artifact.sh validates parsed digest before writing Tekton results (both multi-layer and single-file paths) - Fix minor: ArtifactRef doc comments no longer wrongly scope fields to "when compliance is enabled" - Fix minor: OperatorConfig reconciler cleans up sbom-generate task when compliance is toggled off - Fix minor: ADR ComplianceConfig struct updated to match implementation (SyftImage instead of SBOMTaskBundle, drop TrustedArtifactSignerURL) Made-with: Cursor
|
Thanks @bennyz -- yes, I saw #197 overlaps on the This PR builds on top of that by adding the compliance layer (SBOM generation, |
Summary
ArtifactReftoImageBuildstatus andComplianceConfigtoOperatorConfigspec for supply-chain traceabilityIMAGE_URL/IMAGE_DIGESTpipeline results frompush-artifact-registrytask (Tekton Chains contract)sbom-generateTekton Task (Syft) that attaches SBOMs as OCI referrers when compliance is enabledBuildConfigso bothOperatorConfigandImageBuildreconcilers honour itTest plan
make manifests generate buildsucceedsgo test ./api/... ./internal/common/tasks/... ./internal/controller/imagebuild/...)compliance.enabled: false(default) -- existing pipelines unchangedcompliance.enabled: true-- pipeline gainssbom-generatetask,SBOM_URIresultstatus.artifact.registryandstatus.artifact.digestCloses #204
Made with Cursor
Summary by CodeRabbit
Release Notes
New Features
Documentation