feat(EC-1683): Run existing task policies against task bundle images#1713
feat(EC-1683): Run existing task policies against task bundle images#1713dheerajodha wants to merge 1 commit into
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughPolicy modules were refactored to consume Task objects from a new shared rule Changes
Sequence Diagram(s)sequenceDiagram
participant Input
participant Lib as lib.tkn_bundle.tasks
participant OCI as ec.oci
participant Policy as Task_Policies
Note over Input,Lib: Input can be direct Tekton YAML (apiVersion+kind) or an image.ref pointing to a task-bundle
Input->>Lib: provide input (apiVersion+kind OR image.ref)
alt image.ref present
Lib->>OCI: ec.oci.image_manifest(image.ref)
OCI-->>Lib: manifest (layers, annotations)
loop for each task-layer annotated dev.tekton.image.kind == "task"
Lib->>OCI: ec.oci.blob_files(repo@digest, filter by name)
OCI-->>Lib: blob file contents (task YAML)
end
end
Lib-->>Policy: yield extracted Task objects (data.lib.tkn_bundle.tasks)
Policy->>Policy: iterate tasks and run kind / annotations / results / step-image checks
Policy-->>Input: emit per-task policy results
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
policy/task/kind/kind.rego (1)
24-42:⚠️ Potential issue | 🟠 Major
apiVersionpresence is a loose guard — may silently skip denies on malformed tasks.Both deny rules are now gated purely on truthy presence of
input.apiVersion. For the intended bundle-delegation use case (where extracted tasks always carryapiVersion) this works, but it has two side effects worth confirming:
- Any task definition that happens to omit
apiVersion(malformed, stripped, or produced by a non-Tekton pipeline stage) will now silently pass bothexpected_kindandkind_presentchecks. Previouslykind_presentwould have fired. This is effectively a bypass for malformed/adversarial inputs.- Any non-task resource that happens to have
apiVersionbut a differentkind(e.g., aPipelineorConfigMapdelegated by mistake) will still tripexpected_kind, which is presumably fine for the bundle use case but may be surprising if these rules are reused elsewhere.Consider gating on something stronger tied to the task shape (e.g.,
startswith(input.apiVersion, "tekton.dev/"), or the presence ofinput.spec.steps) so malformed task inputs still failkind_presentwhile non-task inputs are skipped. If the current looser guard is intentional, a short comment documenting the rationale would help future readers.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@policy/task/kind/kind.rego` around lines 24 - 42, The current deny rules (the two deny blocks using input.apiVersion, expected_kind and input.kind) use a loose guard that lets malformed inputs without apiVersion bypass checks; update both deny rule guards to a stronger task-shape predicate (e.g., replace the predicate input.apiVersion with a conjunction like startswith(input.apiVersion, "tekton.dev/") or input.spec.steps to ensure the object is actually a Tekton task) so malformed or non-task objects are handled correctly; alternatively, if the looser guard is intentional, add a short comment above the deny rules documenting that decision and why input.apiVersion is considered sufficient.
🧹 Nitpick comments (4)
policy/task/task_bundle/task_bundle.rego (2)
63-69: Redundant guard in_task_name.Regal flags line 64.
_task_name(task) := task.metadata.name if { task.metadata.name }can be simplified — whentask.metadata.nameis undefined the head already fails, so the body check is redundant:Proposed simplification
-_task_name(task) := task.metadata.name if { - task.metadata.name -} - -_task_name(task) := "<unnamed>" if { - not task.metadata.name -} +_task_name(task) := task.metadata.name + +_task_name(task) := "<unnamed>" if not task.metadata.name🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@policy/task/task_bundle/task_bundle.rego` around lines 63 - 69, The rule _task_name has a redundant body check; replace the first clause ` _task_name(task) := task.metadata.name if { task.metadata.name }` with a head-only rule `_task_name(task) := task.metadata.name` (no body) and keep the fallback `_task_name(task) := "<unnamed>" if { not task.metadata.name }` unchanged so the head will naturally fail when metadata.name is missing.
105-138: Add an explicit metadata scope to the seconddenyMETADATA block.Regal reports
Ambiguous metadata scopeat lines 123-130. Because multipledeny contains result ifrules share thedenyname in this file, withoutscope: rulethe annotations may attach in a surprising way. Addscope: ruleto both METADATA blocks that document individual rules (thewarn contains …one at line 114 is already unambiguous since it is the onlywarnrule, but being explicit here is also safer):# METADATA # title: No tasks extracted # description: >- # A task bundle was detected but no tasks could be extracted from it. # custom: # short_name: no_tasks # failure_msg: "Task bundle detected but no tasks could be extracted from %s" +# scope: rule # deny contains result if {Apply the same
scope: ruleto thedetectedwarn block for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@policy/task/task_bundle/task_bundle.rego` around lines 105 - 138, The METADATA blocks for the per-rule annotations are ambiguous; update the two rule-level METADATA blocks that document the "task_bundle.detected" warn rule and the "task_bundle.no_tasks" deny rule to include "scope: rule" (i.e., add scope: rule to the METADATA above the warn contains result if { ... } that emits code "task_bundle.detected" and to the METADATA above the deny contains result if { ... } that emits code "task_bundle.no_tasks") so Regal will attach the annotations to the correct rules; add the same "scope: rule" to both blocks (you may also add it to the detected warn block for consistency).policy/task/task_bundle/task_bundle_test.rego (1)
54-91: Delegation tests only coverkind— add at least one case per delegated policy.The policy delegates to five packages (
kind,annotations,step_images,step_image_registries,results) and prefixes their codes withtask_bundle.. Onlykindis exercised, and the critical_delegatemessage formatting/code-prefix behavior is only verified via one path._missing_image_taskis defined but never asserted against.Add at least one test per delegated package (e.g. assert a
task_bundle.step_images.*denial using_missing_image_task) so regressions in the delegation wiring — including thewith input as tasksubstitution and prefix shape — are caught. Also consider a test where multiple extracted tasks each surface a distinct denial, to verify the cross-product in the comprehension rules (lines 73-96) does not under- or over-generate.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@policy/task/task_bundle/task_bundle_test.rego` around lines 54 - 91, Add tests that exercise each delegated package so delegation wiring and code-prefixing are verified: create cases calling task_bundle.deny (and task_bundle.warn where relevant) with ec.oci.blob_files containing task blobs that trigger the delegated packages (kind, annotations, step_images, step_image_registries, results) and assert returned result.code starts with "task_bundle.<package>." and result.msg contains the task key (e.g., "[my-task]"). Specifically add a test that triggers the _missing_image_task denial to exercise step_images/step_image_registries delegation, a test for annotations delegation, and at least one test feeding multiple task blobs to task_bundle.deny to assert each task yields its own prefixed denial (verifying the comprehension that uses _delegate produces the cross-product correctly); target functions/values: task_bundle.deny, _delegate, _missing_image_task and the delegated package names to locate where to add the blob inputs and assertions.policy/task/kind/kind_test.rego (1)
9-29: Tests align with the new guard; consider one more negative case.Coverage for the apiVersion-present path and the "skipped without apiVersion" path looks good. As a follow-up to the concern raised on
kind.rego, consider also asserting behavior whenapiVersionis a non-Tekton value (e.g."v1"for aConfigMap) so the intent of the guard is pinned down by tests.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@policy/task/kind/kind_test.rego` around lines 9 - 29, Add a negative test asserting the rule skips non-Tekton apiVersions: create a new test (e.g., test_non_tekton_api_version) that calls kind.deny with input where "apiVersion" is a non-Tekton value like "v1" and "kind" is something like "ConfigMap", and assert the result is empty (use assertions.assert_empty(kind.deny) with input as {"apiVersion":"v1","kind":"ConfigMap"}). This pins down the guard behavior in kind.rego by ensuring only tekton.dev apiVersions trigger the kind checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@policy/task/task_bundle/task_bundle.rego`:
- Around line 53-56: _repo currently equals the whole input.image.ref when no
digest is present, leading to malformed blob_ref (sprintf("%s@%s", [_repo,
layer.digest])) and silent failures in ec.oci.blob_files; update the logic in
the rule that defines _repo (and any callers using blob_ref, layer.digest,
_task_definitions) to either (A) validate and fail fast when input.image.ref
lacks a digest by adding an explicit deny (or error) if "@" not in
input.image.ref, or (B) normalize refs by stripping a tag portion after ":" when
no "@" is present (e.g., split on "@" first, and if single-part, split on ":" to
remove tag) so _repo is always the plain repository before constructing
blob_ref; implement one of these fixes and ensure the deny message clearly
references input.image.ref and that downstream blob_ref construction uses the
normalized _repo.
- Around line 1-16: The package name in task_bundle.rego ("package task_bundle")
conflicts with the pipeline module; change the package declaration in
policy/task/task_bundle/task_bundle.rego to a unique name (for example "package
task.task_bundle" or "package task_task_bundle") and update the corresponding
test module declaration in policy/task/task_bundle/task_bundle_test.rego to
match the new package name so imports/metadata and rule namespaces no longer
collide; ensure you only rename the package identifier (leave rule names like
any references to data.annotations/data.kind intact) so tests and rules resolve
correctly.
---
Outside diff comments:
In `@policy/task/kind/kind.rego`:
- Around line 24-42: The current deny rules (the two deny blocks using
input.apiVersion, expected_kind and input.kind) use a loose guard that lets
malformed inputs without apiVersion bypass checks; update both deny rule guards
to a stronger task-shape predicate (e.g., replace the predicate input.apiVersion
with a conjunction like startswith(input.apiVersion, "tekton.dev/") or
input.spec.steps to ensure the object is actually a Tekton task) so malformed or
non-task objects are handled correctly; alternatively, if the looser guard is
intentional, add a short comment above the deny rules documenting that decision
and why input.apiVersion is considered sufficient.
---
Nitpick comments:
In `@policy/task/kind/kind_test.rego`:
- Around line 9-29: Add a negative test asserting the rule skips non-Tekton
apiVersions: create a new test (e.g., test_non_tekton_api_version) that calls
kind.deny with input where "apiVersion" is a non-Tekton value like "v1" and
"kind" is something like "ConfigMap", and assert the result is empty (use
assertions.assert_empty(kind.deny) with input as
{"apiVersion":"v1","kind":"ConfigMap"}). This pins down the guard behavior in
kind.rego by ensuring only tekton.dev apiVersions trigger the kind checks.
In `@policy/task/task_bundle/task_bundle_test.rego`:
- Around line 54-91: Add tests that exercise each delegated package so
delegation wiring and code-prefixing are verified: create cases calling
task_bundle.deny (and task_bundle.warn where relevant) with ec.oci.blob_files
containing task blobs that trigger the delegated packages (kind, annotations,
step_images, step_image_registries, results) and assert returned result.code
starts with "task_bundle.<package>." and result.msg contains the task key (e.g.,
"[my-task]"). Specifically add a test that triggers the _missing_image_task
denial to exercise step_images/step_image_registries delegation, a test for
annotations delegation, and at least one test feeding multiple task blobs to
task_bundle.deny to assert each task yields its own prefixed denial (verifying
the comprehension that uses _delegate produces the cross-product correctly);
target functions/values: task_bundle.deny, _delegate, _missing_image_task and
the delegated package names to locate where to add the blob inputs and
assertions.
In `@policy/task/task_bundle/task_bundle.rego`:
- Around line 63-69: The rule _task_name has a redundant body check; replace the
first clause ` _task_name(task) := task.metadata.name if { task.metadata.name }`
with a head-only rule `_task_name(task) := task.metadata.name` (no body) and
keep the fallback `_task_name(task) := "<unnamed>" if { not task.metadata.name
}` unchanged so the head will naturally fail when metadata.name is missing.
- Around line 105-138: The METADATA blocks for the per-rule annotations are
ambiguous; update the two rule-level METADATA blocks that document the
"task_bundle.detected" warn rule and the "task_bundle.no_tasks" deny rule to
include "scope: rule" (i.e., add scope: rule to the METADATA above the warn
contains result if { ... } that emits code "task_bundle.detected" and to the
METADATA above the deny contains result if { ... } that emits code
"task_bundle.no_tasks") so Regal will attach the annotations to the correct
rules; add the same "scope: rule" to both blocks (you may also add it to the
detected warn block for consistency).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: bd0e0448-d93c-40c3-b787-2be350b084aa
📒 Files selected for processing (4)
policy/task/kind/kind.regopolicy/task/kind/kind_test.regopolicy/task/task_bundle/task_bundle.regopolicy/task/task_bundle/task_bundle_test.rego
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@policy/task/results/results.rego`:
- Around line 26-27: The deny rule currently rebinding input using "with input
as task" should be refactored: create a helper rule errors_for_task(task) that
encapsulates the logic from the existing errors rules (the rules that reference
input.* around the current lines 46 and 64), replacing all input.* references
with task.*; update the deny rule that iterates "some task in tkn_bundle.tasks"
to call errors_for_task(task) instead of using "with", and remove the original
errors rules so all task-scoped checks run via errors_for_task(task).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1573ea08-ab41-469a-ab08-939ab9c62448
📒 Files selected for processing (7)
policy/lib/tkn_bundle/tkn_bundle.regopolicy/task/annotations/annotations.regopolicy/task/kind/kind.regopolicy/task/kind/kind_test.regopolicy/task/results/results.regopolicy/task/step_image_registries/step_image_registries.regopolicy/task/step_images/step_images.rego
🚧 Files skipped from review as they are similar to previous changes (1)
- policy/task/kind/kind_test.rego
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@policy/task/results/results.rego`:
- Around line 30-45: The version filter is currently global and can let
unrelated task versions suppress checks; update the comprehensions inside the
_errors rule that build version_constraints and required so they are scoped to
the current task: when constructing version_constraints (from
rule_data.get(_rule_data_key)) only collect r.version entries where r.task ==
task.metadata.name, and likewise ensure the required set and the found/result
lookup compare against entries filtered to r.task == task.metadata.name
(referencing task, rule_data.get(_rule_data_key), version_constraints, required,
and found to locate the code to change).
🪄 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: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: ff2b155f-e6d6-4306-8c25-37cd82e17dd9
📒 Files selected for processing (5)
policy/lib/tkn_bundle/tkn_bundle.regopolicy/task/annotations/annotations_test.regopolicy/task/results/results.regopolicy/task/step_image_registries/step_image_registries_test.regopolicy/task/step_images/step_images_test.rego
✅ Files skipped from review due to trivial changes (2)
- policy/task/step_images/step_images_test.rego
- policy/task/step_image_registries/step_image_registries_test.rego
There was a problem hiding this comment.
♻️ Duplicate comments (1)
policy/task/results/results.rego (1)
31-34:⚠️ Potential issue | 🟠 MajorScope
version_constraintsto the current task to avoid hidden misses.At Line 33,
version_constraintsis built from allrequired_task_resultsentries, not just the currenttask. A version from an unrelated task can disable the(all versions)branch and mask missing required results for this task.Proposed fix
- version_constraints := {r.version | some r in rule_data.get(_rule_data_key)} + version_constraints := {r.version | + some r in rule_data.get(_rule_data_key) + task.metadata.name == r.task + r.version + }As per coding guidelines,
**: -Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.Also applies to: 36-39
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@policy/task/results/results.rego` around lines 31 - 34, The comprehension building version_constraints in _errors(task) currently aggregates versions from all entries in rule_data (via rule_data.get(_rule_data_key)) and can pick up constraints for unrelated tasks; restrict that comprehension to only entries that belong to the current task (use a task identifier from task.metadata such as metadata.name or a label like app.kubernetes.io/name) so version_constraints contains only versions where the rule_data entry matches the current task, and apply the same scoping change to the analogous comprehension used in the block covering lines 36-39; update the comprehension expressions referencing rule_data.get(_rule_data_key) to include a filter (e.g., some r in ..., r.task == <current-task-id>) so only matching entries are collected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@policy/task/results/results.rego`:
- Around line 31-34: The comprehension building version_constraints in
_errors(task) currently aggregates versions from all entries in rule_data (via
rule_data.get(_rule_data_key)) and can pick up constraints for unrelated tasks;
restrict that comprehension to only entries that belong to the current task (use
a task identifier from task.metadata such as metadata.name or a label like
app.kubernetes.io/name) so version_constraints contains only versions where the
rule_data entry matches the current task, and apply the same scoping change to
the analogous comprehension used in the block covering lines 36-39; update the
comprehension expressions referencing rule_data.get(_rule_data_key) to include a
filter (e.g., some r in ..., r.task == <current-task-id>) so only matching
entries are collected.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: 6d8714b8-d228-402a-bb00-b120a74aee73
📒 Files selected for processing (1)
policy/task/results/results.rego
There was a problem hiding this comment.
♻️ Duplicate comments (1)
policy/task/results/results.rego (1)
48-49:⚠️ Potential issue | 🟠 MajorScope
version_constraintsto the current task to avoid false negatives.Line 48 currently aggregates versions from all
required_task_resultsentries. That can suppress the Line 49 branch for the current task when another task happens to define the same version string, skipping required-result checks incorrectly.Proposed fix
- version_constraints := {r.version | some r in rule_data.get(_rule_data_key)} + version_constraints := {r.version | + some r in rule_data.get(_rule_data_key) + task.metadata.name == r.task + r.version + }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@policy/task/results/results.rego` around lines 48 - 49, The comprehension building version_constraints currently collects versions from all rule_data entries; change it to only gather versions for the current task so other tasks' versions don't mask missing results. Update the comprehension that defines version_constraints to filter by the current task (e.g., include a clause like r.task == task or match the rule_data key to required_task_results[_].task) when iterating rule_data.get(_rule_data_key), so version_constraints only contains versions relevant to the current task before evaluating not version in version_constraints.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@policy/task/results/results.rego`:
- Around line 48-49: The comprehension building version_constraints currently
collects versions from all rule_data entries; change it to only gather versions
for the current task so other tasks' versions don't mask missing results. Update
the comprehension that defines version_constraints to filter by the current task
(e.g., include a clause like r.task == task or match the rule_data key to
required_task_results[_].task) when iterating rule_data.get(_rule_data_key), so
version_constraints only contains versions relevant to the current task before
evaluating not version in version_constraints.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Enterprise
Run ID: cfe26aca-7774-478e-8706-f9593ee5bb1d
📒 Files selected for processing (1)
policy/task/results/results.rego
|
I'll squash commits, once I get the approval(s) |
|
Were you able to find any tekton bundles built as a Konflux component so we can test this in a real-life situation? Lgtm, but maybe we need to delay merging if there's no real task bundles that can benefit from it. |
Not yet :( Raised a thread on the build channel asking for the same. Adam is OOO, will be back on May 6
That's fair. |
|
I found a task bundle that's built on Konflux! The Integration team builds the images they own on Konflux. I used the correct public key from the rh01 cluster and the latest build of the clair-scan task: Here's how the output looks (this is a dropdown, click on me)$ ec validate image --image quay.io/redhat-user-workloads/rhtap-integration-tenant/clair-scan-v03:b6f703c5abab7ff15a576321cde80cec8290e756 --policy ../ec-cli/policies/task-bundle/policy.yaml --ignore-rekor --output text --show-successesSuccess: false Results: ✕ [Violation] base_image_registries.base_image_info_found ✕ [Violation] cve.cve_results_found ✕ [Violation] external_parameters.pipeline_run_params_provided ✕ [Violation] git_branch.git_branch ✕ [Violation] rhtap_multi_ci.attestation_found ✕ [Violation] rpm_repos.rule_data_provided ✕ [Violation] rpm_signature.rule_data_provided ✕ [Violation] slsa_build_scripted_build.image_built_by_trusted_task ✕ [Violation] slsa_source_correlated.source_code_reference_provided ✕ [Violation] source_image.exists ✕ [Violation] trusted_task.data › [Warning] github_certificate.gh_workflow_extensions › [Warning] github_certificate.gh_workflow_extensions › [Warning] github_certificate.gh_workflow_extensions › [Warning] github_certificate.gh_workflow_extensions › [Warning] github_certificate.gh_workflow_extensions › [Warning] tasks.pipeline_required_tasks_list_provided ✓ [Success] annotations.expires_on_format ✓ [Success] attestation_type.deprecated_policy_attestation_format ✓ [Success] attestation_type.known_attestation_type ✓ [Success] attestation_type.known_attestation_types_provided ✓ [Success] attestation_type.pipelinerun_attestation_found ✓ [Success] buildah_build_task.add_capabilities_param ✓ [Success] buildah_build_task.buildah_uses_local_dockerfile ✓ [Success] buildah_build_task.disallowed_platform_patterns_pattern ✓ [Success] buildah_build_task.platform_param ✓ [Success] buildah_build_task.privileged_nested_param ✓ [Success] builtin.attestation.signature_check ✓ [Success] builtin.attestation.syntax_check ✓ [Success] builtin.image.signature_check ✓ [Success] cve.rule_data_provided ✓ [Success] kind.expected_kind ✓ [Success] kind.kind_present ✓ [Success] labels.deprecated_labels ✓ [Success] labels.disallowed_inherited_labels ✓ [Success] labels.inaccessible_config ✓ [Success] labels.inaccessible_manifest ✓ [Success] labels.inaccessible_parent_config ✓ [Success] labels.inaccessible_parent_manifest ✓ [Success] labels.optional_labels ✓ [Success] labels.required_labels ✓ [Success] labels.rule_data_provided ✓ [Success] olm.allowed_registries ✓ [Success] olm.allowed_registries_related ✓ [Success] olm.allowed_resource_kinds ✓ [Success] olm.csv_semver_format ✓ [Success] olm.feature_annotations_format ✓ [Success] olm.inaccessible_related_images ✓ [Success] olm.olm_bundle_multi_arch ✓ [Success] olm.required_olm_features_annotations_provided ✓ [Success] olm.subscriptions_annotation_format ✓ [Success] olm.unmapped_references ✓ [Success] olm.unpinned_references ✓ [Success] olm.unpinned_related_images ✓ [Success] olm.unpinned_snapshot_references ✓ [Success] pre_build_script_task.pre_build_script_task_runner_image_allowed ✓ [Success] pre_build_script_task.pre_build_script_task_runner_image_in_results ✓ [Success] pre_build_script_task.pre_build_script_task_runner_image_in_sbom ✓ [Success] pre_build_script_task.valid_pre_build_script_task_runner_image_ref ✓ [Success] prefetch_dependencies.mode_not_permissive ✓ [Success] provenance_materials.git_clone_source_matches_provenance ✓ [Success] provenance_materials.git_clone_task_found ✓ [Success] quay_expiration.expires_label ✓ [Success] results.required ✓ [Success] results.rule_data_provided ✓ [Success] rpm_build_deps.download_location_valid ✓ [Success] rpm_ostree_task.builder_image_param ✓ [Success] rpm_ostree_task.rule_data ✓ [Success] rpm_packages.unique_version ✓ [Success] rpm_pipeline.invalid_pipeline ✓ [Success] rpm_repos.ids_known ✓ [Success] rpm_signature.allowed ✓ [Success] rpm_signature.result_format ✓ [Success] sbom.disallowed_packages_provided ✓ [Success] sbom.found ✓ [Success] sbom_cyclonedx.allowed ✓ [Success] sbom_cyclonedx.allowed_package_external_references ✓ [Success] sbom_cyclonedx.allowed_package_sources ✓ [Success] sbom_cyclonedx.cdx_supported_version ✓ [Success] sbom_cyclonedx.disallowed_package_attributes ✓ [Success] sbom_cyclonedx.disallowed_package_external_references ✓ [Success] sbom_cyclonedx.valid_cdx_1_4 ✓ [Success] sbom_cyclonedx.valid_cdx_1_5 ✓ [Success] sbom_cyclonedx.valid_cdx_1_6 ✓ [Success] sbom_spdx.allowed ✓ [Success] sbom_spdx.allowed_package_external_references ✓ [Success] sbom_spdx.allowed_package_sources ✓ [Success] sbom_spdx.contains_files ✓ [Success] sbom_spdx.contains_packages ✓ [Success] sbom_spdx.disallowed_package_attributes ✓ [Success] sbom_spdx.disallowed_package_external_references ✓ [Success] sbom_spdx.matches_image ✓ [Success] sbom_spdx.valid ✓ [Success] schedule.date_restriction ✓ [Success] schedule.rule_data_provided ✓ [Success] schedule.weekday_restriction ✓ [Success] slsa_build_build_service.allowed_builder_ids_provided ✓ [Success] slsa_build_build_service.slsa_builder_id_accepted ✓ [Success] slsa_build_build_service.slsa_builder_id_found ✓ [Success] slsa_build_scripted_build.build_script_used ✓ [Success] slsa_build_scripted_build.build_task_image_results_found ✓ [Success] slsa_build_scripted_build.subject_build_task_matches ✓ [Success] slsa_provenance_available.allowed_predicate_types_provided ✓ [Success] slsa_provenance_available.attestation_predicate_type_accepted ✓ [Success] slsa_source_correlated.attested_source_code_reference ✓ [Success] slsa_source_correlated.expected_source_code_reference ✓ [Success] slsa_source_correlated.rule_data_provided ✓ [Success] slsa_source_version_controlled.materials_format_okay ✓ [Success] slsa_source_version_controlled.materials_include_git_sha ✓ [Success] slsa_source_version_controlled.materials_uri_is_git_repo ✓ [Success] step_image_registries.step_image_registry_prefix_list_provided ✓ [Success] step_image_registries.step_images_permitted ✓ [Success] step_images.step_images_accessible ✓ [Success] tasks.data_provided ✓ [Success] tasks.future_required_tasks_found ✓ [Success] tasks.pinned_task_refs ✓ [Success] tasks.pipeline_has_tasks ✓ [Success] tasks.required_tasks_found ✓ [Success] tasks.required_tasks_list_provided ✓ [Success] tasks.required_untrusted_task_found ✓ [Success] tasks.successful_pipeline_tasks ✓ [Success] tasks.unsupported ✓ [Success] test.no_erred_tests ✓ [Success] test.no_failed_informative_tests ✓ [Success] test.no_failed_tests ✓ [Success] test.no_skipped_tests ✓ [Success] test.no_test_warnings ✓ [Success] test.rule_data_provided ✓ [Success] test.test_all_images ✓ [Success] test.test_data_found ✓ [Success] test.test_results_found ✓ [Success] test.test_results_known ✓ [Success] trusted_artifacts.parameter ✓ [Success] trusted_artifacts.result ✓ [Success] trusted_artifacts.workspace ✓ [Success] trusted_task.current ✓ [Success] trusted_task.data_format ✓ [Success] trusted_task.future_deny_rule ✓ [Success] trusted_task.pinned ✓ [Success] trusted_task.tagged ✓ [Success] trusted_task.trusted ✓ [Success] trusted_task.trusted_parameters ✓ [Success] trusted_task.valid_trusted_artifact_inputs ✓ [Success] volatile_config.expired_rule ✓ [Success] volatile_config.expiring_rule ✓ [Success] volatile_config.invalid_config ✓ [Success] volatile_config.no_expiration ✓ [Success] volatile_config.pending_rule Error: success criteria not met The task-specific policies from this PR are all passing: The 12 violations are all unrelated supply chain policies (missing rule data, untrusted build tasks, missing CVE scans, etc.) — not from my changes. |
Introduce lib/tkn_bundle, a shared helper that returns task definitions from either direct YAML input (ec validate input) or OCI task bundle image layers (ec validate image). All task policies (kind, annotations, results, step_images, step_image_registries) now iterate over tkn_bundle.tasks instead of accessing input directly. - Use a positive apiVersion check to identify raw task YAML input - Extract results validation into a parameterized _errors(task) function - Update tests to include apiVersion in task inputs - Regenerate task policy docs resolves: EC-1683 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest commit is nothing but a squashed-up commit from the previous 7 commits that were in this PR. Nothing has changed code-wise. |
|
Did some testing, see details here in slack. Lgtm. |
How it works:
tkn_bundle.tasks returns task definitions from two sources:
ec validate inputbehavior)Each task policy then does
some task in tkn_bundle.tasksand validatestask.*instead ofinput.*.Demo output