Skip to content

Commit

Permalink
Use .statement.predicate everywhere instead of just .predicate
Browse files Browse the repository at this point in the history
Signed-off-by: Mark Bestavros <mbestavr@redhat.com>
  • Loading branch information
mbestavros committed Nov 1, 2023
1 parent 7200fd2 commit dae3b97
Show file tree
Hide file tree
Showing 18 changed files with 60 additions and 105 deletions.
11 changes: 0 additions & 11 deletions policy/lib/statement.rego

This file was deleted.

11 changes: 0 additions & 11 deletions policy/lib/statement_test.rego

This file was deleted.

5 changes: 2 additions & 3 deletions policy/lib/tekton/pipeline.rego
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import future.keywords.contains
import future.keywords.if
import future.keywords.in

import data.lib
import data.lib.time as ectime

pipeline_label := "pipelines.openshift.io/runtime"
Expand Down Expand Up @@ -38,10 +37,10 @@ pipeline_label_selector(pipeline) := value if {
value := build_task(pipeline).invocation.environment.labels[task_label]
} else := value if {
# PipelineRun labels found in the SLSA Provenance v1.0
value := lib.statement(pipeline).predicate.buildDefinition.internalParameters.labels[pipeline_label]
value := pipeline.statement.predicate.buildDefinition.internalParameters.labels[pipeline_label]
} else := value if {
# PipelineRun labels found in the SLSA Provenance v0.2
value := lib.statement(pipeline).predicate.invocation.environment.labels[pipeline_label]
value := pipeline.statement.predicate.invocation.environment.labels[pipeline_label]
} else := value if {
# Labels from a Tekton Pipeline definition
value := pipeline.metadata.labels[pipeline_label]
Expand Down
5 changes: 2 additions & 3 deletions policy/lib/tekton/task.rego
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import future.keywords.contains
import future.keywords.if
import future.keywords.in

import data.lib
import data.lib.refs
import data.lib.time as ectime

Expand Down Expand Up @@ -39,7 +38,7 @@ _slsa_task(task) if {

# _maybe_tasks returns a set of potential tasks.
# Handle tasks from a PipelineRun attestation.
_maybe_tasks(attestation) := lib.statement(attestation).predicate.buildConfig.tasks
_maybe_tasks(attestation) := attestation.statement.predicate.buildConfig.tasks

# Handle tasks from a Pipeline definition.
_maybe_tasks(pipeline) := _tasks if {
Expand All @@ -53,7 +52,7 @@ _maybe_tasks(pipeline) := _tasks if {

# handle tasks from a slsav1 attestation
_maybe_tasks(slsav1) := _tasks if {
deps := lib.statement(slsav1).predicate.buildDefinition.resolvedDependencies
deps := slsav1.statement.predicate.buildDefinition.resolvedDependencies
_tasks := {json.unmarshal(base64.decode(dep.content)) |
some dep in deps
_slsav1_tekton(dep)
Expand Down
32 changes: 16 additions & 16 deletions policy/lib/tekton/task_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test_tasks_from_attestation if {
git_clone := {"name": "ignored", "ref": {"name": "git-clone"}}
buildah := {"name": "ignored", "ref": {"name": "buildah"}}

attestation := {"predicate": {"buildConfig": {"tasks": [git_clone, buildah]}}}
attestation := {"statement": {"predicate": {"buildConfig": {"tasks": [git_clone, buildah]}}}}
expected := {git_clone, buildah}
lib.assert_equal(expected, tkn.tasks(attestation))
}
Expand All @@ -42,14 +42,14 @@ test_tasks_from_slsav1_tekton_attestation if {
"content": content,
}

attestation := {
attestation := {"statement": {
"predicateType": "https://slsa.dev/provenance/v1",
"predicate": {"buildDefinition": {
"buildType": "https://tekton.dev/chains/v2/slsa-tekton",
"externalParameters": {"runSpec": {"pipelineSpec": {}}},
"resolvedDependencies": [task],
}},
}
}}
expected := {{
"params": [
{
Expand Down Expand Up @@ -120,14 +120,14 @@ test_tasks_from_slsav1_tekton_mixture_attestation if {
"content": task3,
}

attestation := {"predicate": {"buildDefinition": {
attestation := {"statement": {"predicate": {"buildDefinition": {
"buildType": "https://tekton.dev/chains/v2/slsa-tekton",
"resolvedDependencies": [
git_init,
git_init_pipeline,
git_init_bad,
],
}}}
}}}}
expected := {
{
"params": [
Expand Down Expand Up @@ -181,10 +181,10 @@ test_tasks_from_slsav1_attestation if {
"uri": "oci://gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init",
"digest": {"sha256": "28ff94e63e4058afc3f15b4c11c08cf3b54fa91faa646a4bbac90380cd7158df"},
}
attestation := {"predicate": {"buildDefinition": {
attestation := {"statement": {"predicate": {"buildDefinition": {
"buildType": "https://tekton.dev/chains/v2/slsa-tekton",
"resolvedDependencies": [git_init],
}}}
}}}}
lib.assert_equal(set(), tkn.tasks(attestation))
}

Expand Down Expand Up @@ -253,7 +253,7 @@ test_tasks_from_attestation_with_spam if {
{"ref": {"name": "summary", "kind": "Task", "bundle": _bundle}},
}

attestation := {"predicate": {"buildConfig": {"tasks": expected_tasks}}}
attestation := {"statement": {"predicate": {"buildConfig": {"tasks": expected_tasks}}}}

lib.assert_equal(expected_tasks, tkn.tasks(attestation))

Expand Down Expand Up @@ -309,19 +309,19 @@ test_build_task if {
test_build_task_not_found if {
missing_image_url := json.patch(_good_attestation, [{
"op": "add",
"path": "/predicate/buildConfig/tasks/0/results/0/name",
"path": "/statement/predicate/buildConfig/tasks/0/results/0/name",
"value": "IMAGE_URL_SKIP",
}])
not tkn.build_task(missing_image_url)

missing_image_digest := json.patch(_good_attestation, [{
"op": "add",
"path": "/predicate/buildConfig/tasks/0/results/1/name",
"path": "/statement/predicate/buildConfig/tasks/0/results/1/name",
"value": "IMAGE_DIGEST_SKIP",
}])
not tkn.build_task(missing_image_digest)

missing_results := json.remove(_good_attestation, ["/predicate/buildConfig/tasks/0/results"])
missing_results := json.remove(_good_attestation, ["/statement/predicate/buildConfig/tasks/0/results"])
not tkn.build_task(missing_results)
}

Expand All @@ -333,19 +333,19 @@ test_git_clone_task if {
test_git_clone_task_not_found if {
missing_url := json.patch(_good_attestation, [{
"op": "add",
"path": "/predicate/buildConfig/tasks/1/results/0/name",
"path": "/statement/predicate/buildConfig/tasks/1/results/0/name",
"value": "you-argh-el",
}])
not tkn.git_clone_task(missing_url)

missing_commit := json.patch(_good_attestation, [{
"op": "add",
"path": "/predicate/buildConfig/tasks/1/results/1/name",
"path": "/statement/predicate/buildConfig/tasks/1/results/1/name",
"value": "bachelor",
}])
not tkn.git_clone_task(missing_commit)

missing_results := json.remove(_good_attestation, ["/predicate/buildConfig/tasks/1/results"])
missing_results := json.remove(_good_attestation, ["/statement/predicate/buildConfig/tasks/1/results"])
not tkn.git_clone_task(missing_results)
}

Expand Down Expand Up @@ -449,10 +449,10 @@ _good_git_clone_task := {
"ref": {"kind": "Task", "name": "git-clone", "bundle": _bundle},
}

_good_attestation := {"predicate": {
_good_attestation := {"statement": {"predicate": {
"buildType": lib.tekton_pipeline_run,
"buildConfig": {"tasks": [_good_build_task, _good_git_clone_task]},
}}
}}}

slsav1_attestation_local_spec := {
"params": [
Expand Down
2 changes: 1 addition & 1 deletion policy/release/attestation_type.rego
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import data.lib
#
deny contains result if {
some att in lib.pipelinerun_attestations
att_type := att._type
att_type := att.statement._type
not att_type in lib.rule_data("known_attestation_types")
result := lib.result_helper(rego.metadata.chain(), [att_type])
}
Expand Down
4 changes: 2 additions & 2 deletions policy/release/attestation_type_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ test_deny_deprecated_policy_attestation_format {
"code": "attestation_type.deprecated_policy_attestation_format",
"msg": "Deprecated policy attestation format found",
}}
attestations := [{
attestations := [{"statement": {
"_type": good_type,
"predicate": {"buildType": lib.tekton_pipeline_run},
}]
}}]
lib.assert_equal_results(attestation_type.deny, expected) with input.attestations as attestations
}
6 changes: 4 additions & 2 deletions policy/release/external_parameters.rego
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ import data.lib
#
deny contains result if {
some provenance in lib.pipelinerun_attestations

param_names := {name |
some p in provenance.predicate.buildDefinition.externalParameters.runSpec.params
some p in provenance.statement.predicate.buildDefinition.externalParameters.runSpec.params
p.value != ""
name := p.name
}
expected_names := {n | some n in lib.rule_data("pipeline_run_params")}

expected_names != param_names
result := lib.result_helper(rego.metadata.chain(), [param_names, expected_names])
}
Expand All @@ -48,7 +50,7 @@ deny contains result if {
deny contains result if {
some provenance in lib.pipelinerun_attestations
shared_workspaces := {w |
some w in provenance.predicate.buildDefinition.externalParameters.runSpec.workspaces
some w in provenance.statement.predicate.buildDefinition.externalParameters.runSpec.workspaces
w.persistentVolumeClaim
}
count(shared_workspaces) > 0
Expand Down
22 changes: 10 additions & 12 deletions policy/release/lib/attestations.rego
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package lib
import future.keywords.if
import future.keywords.in

import data.lib
import data.lib.tkn

tekton_pipeline_run := "tekton.dev/v1beta1/PipelineRun"
Expand Down Expand Up @@ -49,33 +48,32 @@ pipelinerun_attestations := att if {
att := array.concat(v1_0, v0_2)
}

pipelinerun_slsa_provenance02 := [statement |
pipelinerun_slsa_provenance02 := [att |
some att in input.attestations
statement := lib.statement(att)
statement.predicate.buildType in pipelinerun_att_build_types
att.statement.predicate.buildType in pipelinerun_att_build_types
]

# TODO: Make this work with pipelinerun_attestations above so policy rules can be
# written for either.
pipelinerun_slsa_provenance_v1 := [statement |
pipelinerun_slsa_provenance_v1 := [att |
some att in input.attestations
statement := lib.statement(att)
statement.predicateType == "https://slsa.dev/provenance/v1"
att.statement.predicateType == "https://slsa.dev/provenance/v1"

statement.predicate.buildDefinition.buildType in slsav1_pipelinerun_att_build_types
att.statement.predicate.buildDefinition.buildType in slsav1_pipelinerun_att_build_types

# TODO: Workaround to distinguish between taskrun and pipelinerun attestations
spec_keys := object.keys(statement.predicate.buildDefinition.externalParameters.runSpec)
spec_keys := object.keys(att.statement.predicate.buildDefinition.externalParameters.runSpec)

pipeline_keys := {"pipelineRef", "pipelineSpec"}

count(pipeline_keys - spec_keys) != count(pipeline_keys)
]

# These ones we don't care about any more
taskrun_attestations := [statement |
taskrun_attestations := [att |
some att in input.attestations
statement := lib.statement(att)

statement.predicate.buildType in taskrun_att_build_types
att.statement.predicate.buildType in taskrun_att_build_types
]

tasks_from_pipelinerun := [task |
Expand Down
29 changes: 3 additions & 26 deletions policy/release/lib/attestations_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ test_tasks_from_pipelinerun {

test_pr_attestations {
lib.assert_equal(
[mock_pr_att.statement, mock_pr_att_legacy.statement],
[mock_pr_att, mock_pr_att_legacy],
lib.pipelinerun_attestations,
) with input.attestations as [
mock_tr_att,
Expand All @@ -175,18 +175,6 @@ test_pr_attestations {
garbage_att,
]

# Deprecate format should still work for now
lib.assert_equal(
[mock_pr_att.statement, mock_pr_att_legacy.statement],
lib.pipelinerun_attestations,
) with input.attestations as [
mock_tr_att.statement,
mock_tr_att_legacy.statement,
mock_pr_att.statement,
mock_pr_att_legacy.statement,
garbage_att.statement,
]

lib.assert_equal([], lib.pipelinerun_attestations) with input.attestations as [
mock_tr_att,
mock_tr_att_legacy,
Expand Down Expand Up @@ -243,28 +231,17 @@ test_pipelinerun_slsa_provenance_v1 {
"value": {"taskRef": {}},
}]),
]
expected := [provenance_with_pr_spec.statement, provenance_with_pr_ref.statement]
expected := [provenance_with_pr_spec, provenance_with_pr_ref]
lib.assert_equal(expected, lib.pipelinerun_slsa_provenance_v1) with input.attestations as attestations

# Deprecated format should still work for now
old_attestations := [att.statement | some att in attestations]
lib.assert_equal(expected, lib.pipelinerun_slsa_provenance_v1) with input.attestations as old_attestations
}

test_tr_attestations {
lib.assert_equal([mock_tr_att.statement], lib.taskrun_attestations) with input.attestations as [
lib.assert_equal([mock_tr_att], lib.taskrun_attestations) with input.attestations as [
mock_tr_att,
mock_pr_att,
garbage_att,
]

# Deprecated format should still work for now
lib.assert_equal([mock_tr_att.statement], lib.taskrun_attestations) with input.attestations as [
mock_tr_att.statement,
mock_pr_att.statement,
garbage_att.statement,
]

lib.assert_equal([], lib.taskrun_attestations) with input.attestations as [mock_pr_att, garbage_att]
}

Expand Down
2 changes: 1 addition & 1 deletion policy/release/provenance_materials.rego
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ deny contains result if {
commit := tkn.task_result(t, "commit")

materials := [m |
some m in attestation.predicate.materials
some m in attestation.statement.predicate.materials
m.uri == url
m.digest.sha1 == commit
]
Expand Down
15 changes: 7 additions & 8 deletions policy/release/sbom_spdx.rego
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,8 @@ deny contains result if {

_sboms := [sbom |
some att in input.attestations
statement := att.statement
statement.predicateType == "https://spdx.dev/Document"
sbom := _predicate(statement)
att.statement.predicateType == "https://spdx.dev/Document"
sbom := _predicate(att)
]

# _is_valid is true if the given SPDX SBOM has certain fields. This is
Expand All @@ -108,9 +107,9 @@ _is_valid(sbom) if {
is_array(sbom.packages)
}

# _predicate returns the predicate from the given statement. If the
# _predicate returns the predicate from the given attestation. If the
# predicate is JSON marshaled, it is unmarshaled.
_predicate(statement) := predicate if {
json.is_valid(statement.predicate)
predicate := json.unmarshal(statement.predicate)
} else := statement.predicate
_predicate(att) := predicate if {
json.is_valid(att.statement.predicate)
predicate := json.unmarshal(att.statement.predicate)
} else := att.statement.predicate
Loading

0 comments on commit dae3b97

Please sign in to comment.