Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use .statement.predicate everywhere instead of just .predicate #772

Merged
merged 1 commit into from
Nov 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
14 changes: 10 additions & 4 deletions policy/release/attestation_type_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,16 @@ test_deny_when_pipelinerun_attestation_founds {
}

test_deny_deprecated_policy_attestation_format {
expected := {{
"code": "attestation_type.deprecated_policy_attestation_format",
"msg": "Deprecated policy attestation format found",
}}
expected := {
{
"code": "attestation_type.deprecated_policy_attestation_format",
"msg": "Deprecated policy attestation format found",
},
{
"code": "attestation_type.pipelinerun_attestation_found",
"msg": "Missing pipelinerun attestation",
lcarva marked this conversation as resolved.
Show resolved Hide resolved
},
}
attestations := [{
"_type": good_type,
"predicate": {"buildType": lib.tekton_pipeline_run},
Expand Down
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
simonbaird marked this conversation as resolved.
Show resolved Hide resolved
]

# 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