Skip to content
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
2 changes: 1 addition & 1 deletion acceptance/kubernetes/kind/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ func (k *kindCluster) TaskInfo(ctx context.Context) (*types.TaskInfo, error) {

results := map[string]any{}
for _, r := range tr.Status.Results {
results[r.Name] = r.Value
results[r.Name] = paramValue(r.Value)
}

info := types.TaskInfo{
Expand Down
25 changes: 25 additions & 0 deletions acceptance/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,30 @@ func taskResultsShouldMatchTheSnapshot(ctx context.Context) error {
return snaps.MatchSnapshot(ctx, "results", string(j), nil)
}

func taskResultShouldEqual(ctx context.Context, resultName, expectedValue string) error {
c := testenv.FetchState[ClusterState](ctx)

if err := mustBeUp(ctx, *c); err != nil {
return err
}

info, err := c.cluster.TaskInfo(ctx)
if err != nil {
return err
}

actual, ok := info.Results[resultName]
if !ok {
return fmt.Errorf("result %q not found in task results", resultName)
}

if fmt.Sprintf("%v", actual) != expectedValue {
return fmt.Errorf("result %q: expected %q, got %q", resultName, expectedValue, actual)
}

return nil
}

func taskLogsShouldContain(ctx context.Context, stepName, needle string) error {
c := testenv.FetchState[ClusterState](ctx)

Expand Down Expand Up @@ -467,6 +491,7 @@ func AddStepsTo(sc *godog.ScenarioContext) {
sc.Step("^the task logs for step \"([^\"]*)\" should contain `([^`]+)`$", taskLogsShouldContain)
sc.Step(`^the task env var for step "([^"]*)" named "([^"]*)" should be set to "([^"]*)"$`, stepEnvVarShouldBe)
sc.Step(`^the task results should match the snapshot$`, taskResultsShouldMatchTheSnapshot)
sc.Step(`^the task result "([^"]*)" should equal "([^"]*)"$`, taskResultShouldEqual)
sc.Step(`^policy configuration named "([^"]*)" with (\d+) policy sources from "([^"]*)"(?:, patched with)$`, createNamedPolicyWithManySources)
// stop usage of the cluster once a test is done, godog will call this
// function on failure and on the last step, so more than once if the
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/verify-conforma-konflux-ta.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ paths can be provided by using the `:` separator.
*VSA_SIGNING_KEY* (`string`):: Signing key for format=dsse (k8s:// or file:// URL)
*VSA_UPLOAD* (`string`):: VSA upload destination
+
*Default*: `local@/var/workdir/vsa`
*Default*: `local@/var/workdir/conforma/vsa`
*ociStorage* (`string`):: OCI storage URL for trusted artifacts

== Results
Expand Down
2 changes: 1 addition & 1 deletion features/__snapshots__/ta_task_validate_image.snap
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
[Golden container image with trusted artifacts:results - 1]
{
"TEST_OUTPUT": "{\"timestamp\":\"${TIMESTAMP}\",\"namespace\":\"\",\"successes\":5,\"failures\":0,\"warnings\":0,\"result\":\"SUCCESS\"}\n",
"VSA_GENERATED": "false\n"
"VSA_GENERATED": "false"
}
---

Expand Down
25 changes: 25 additions & 0 deletions features/ta_task_validate_image.feature
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,31 @@ Feature: Verify Conforma Trusted Artifact Tekton Task
And the task results should match the snapshot
And the task logs for step "show-config" should match the snapshot

Scenario: VSA generation with predicate format
Given a working namespace
Given a snapshot artifact with content:
```
{
"components": [
{
"containerImage": "quay.io/hacbs-contract-demo/golden-container@sha256:e76a4ae9dd8a52a0d191fd34ca133af5b4f2609536d32200a4a40a09fdc93a0d"
}
]
}
```
When version 0.1 of the task named "verify-conforma-konflux-ta" is run with parameters:
| SNAPSHOT_FILENAME | snapshotartifact |
| SOURCE_DATA_ARTIFACT | oci:${REGISTRY}/acceptance/snapshotartifact@${BUILD_SNAPSHOT_DIGEST} |
| POLICY_CONFIGURATION | {"publicKey":"-----BEGIN PUBLIC KEY-----\\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERhr8Zj4dZW67zucg8fDr11M4lmRp\\nzN6SIcIjkvH39siYg1DkCoa2h2xMUZ10ecbM3/ECqvBV55YwQ2rcIEa7XQ==\\n-----END PUBLIC KEY-----","sources":[{"policy":["git::github.com/conforma/policy//policy/release?ref=d34eab36b23d43748e451004177ca144296bf323","git::github.com/conforma/policy//policy/lib?ref=d34eab36b23d43748e451004177ca144296bf323"],"config":{"include":["slsa_provenance_available"]}}]} |
| STRICT | true |
| IGNORE_REKOR | true |
| ENABLE_VSA | true |
| ATTESTATION_FORMAT | predicate |
| TRUSTED_ARTIFACTS_DEBUG | "true" |
| ORAS_OPTIONS | --plain-http |
Then the task should succeed
And the task result "VSA_GENERATED" should equal "true"

Scenario: Policy configuration passed as JSON string
Given a working namespace
Given a snapshot artifact with content:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ spec:
- name: VSA_UPLOAD
type: string
description: VSA upload destination
default: "local@/var/workdir/vsa"
default: "local@/var/workdir/conforma/vsa"

- name: ociStorage
type: string
Expand Down Expand Up @@ -322,22 +322,44 @@ spec:
if [[ "$(params.ENABLE_VSA)" == "true" ]]; then
EC_ARGS+=(--vsa --attestation-format=$(params.ATTESTATION_FORMAT))

# Extract local path from VSA_UPLOAD for output directory
# VSA_UPLOAD format is "local@/path/to/dir"
VSA_LOCAL_PATH=$(echo "$(params.VSA_UPLOAD)" | grep -oE '^local@[^ ]+' | sed 's/^local@//' | head -n1 || true)

if [[ "$(params.ATTESTATION_FORMAT)" == "dsse" ]]; then
if [[ -z "$(params.VSA_SIGNING_KEY)" ]]; then
echo "ERROR: VSA_SIGNING_KEY required for format=dsse" >&2
exit 1
fi
EC_ARGS+=(--vsa-signing-key "$(params.VSA_SIGNING_KEY)")
EC_ARGS+=(--vsa-upload "$(params.VSA_UPLOAD)")
fi

EC_ARGS+=(--vsa-upload "$(params.VSA_UPLOAD)")
echo "true" > $(results.VSA_GENERATED.path)
# ec requires --attestation-output-dir to be under /tmp or cwd.
# Write there first, then copy to the workdir so
# create-trusted-artifact includes them in the archive.
VSA_TMP_DIR="/tmp/vsa-output"
mkdir -p "$VSA_TMP_DIR"
EC_ARGS+=(--attestation-output-dir "$VSA_TMP_DIR")

echo -n "true" > $(results.VSA_GENERATED.path)
else
echo "false" > $(results.VSA_GENERATED.path)
echo -n "false" > $(results.VSA_GENERATED.path)
fi

# Execute EC with constructed arguments
ec "${EC_ARGS[@]}"

# Copy VSA output from /tmp to workdir for trusted artifact archival
if [[ "$(params.ENABLE_VSA)" == "true" ]]; then
VSA_LOCAL_PATH=$(echo "$(params.VSA_UPLOAD)" | grep -oE '^local@[^ ]+' | sed 's/^local@//' | head -n1 || true)
if [[ -n "$VSA_LOCAL_PATH" && -d "/tmp/vsa-output" ]]; then
mkdir -p "$VSA_LOCAL_PATH"
cp -r /tmp/vsa-output/* "$VSA_LOCAL_PATH"/ 2>/dev/null || true
# Include raw JSON report for downstream SLSA VSA generation
cp "$(params.HOMEDIR)/report-json.json" "$VSA_LOCAL_PATH"/ 2>/dev/null || true
fi
fi
env:
# POLICY_CONFIGURATION is passed via environment variable to safely handle JSON strings
# This avoids shell quoting issues when Tekton substitutes parameter values directly in scripts
Expand Down Expand Up @@ -449,7 +471,9 @@ spec:
- name: ociStorage
value: $(params.ociStorage)
- name: workDir
value: /var/workdir
value: $(params.TRUSTED_ARTIFACTS_EXTRACT_DIR)
- name: sourceDataArtifact
value: $(results.sourceDataArtifact.path)

volumes:
- name: trusted-ca
Expand Down
Loading