Skip to content

Capture remote stepAction source in SLSA resolvedDependencies#1737

Open
ngelman1 wants to merge 1 commit into
tektoncd:mainfrom
ngelman1:StepAction-origin-wiring
Open

Capture remote stepAction source in SLSA resolvedDependencies#1737
ngelman1 wants to merge 1 commit into
tektoncd:mainfrom
ngelman1:StepAction-origin-wiring

Conversation

@ngelman1

@ngelman1 ngelman1 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

This PR aims to close some gaps before advancing to reslove issue #1160

Changes

When a TaskRun step uses a remotely resolved stepAction, Pipelines records its origin in StepState.Provenance.RefSource. This change wires that data into the SLSA provenance resolvedDependencies as entries named "stepAction/{stepName}", enabling full traceability of step definitions.

Currently, Chains captures the origin of remote Tasks and Pipelines in provenance, but ignores the origin of remote StepActions. This means the SLSA provenance has a traceability gap -- a verifier cannot tell where a step's definition came from.

Submitter Checklist

As the author of this PR, please check off the items in this checklist:

  • Has Docs included if any changes are user facing
  • Has Tests included if any functionality added or changed
  • Follows the commit message standard
  • Meets the Tekton contributor standards (including
    functionality, content, code)
  • Release notes block below has been updated with any user facing changes (API changes, bug fixes, changes requiring upgrade notices or deprecation warnings)
  • Release notes contains the string "action required" if the change requires additional action from users switching to the new release

Release Notes

Capture the origin (URI + digest) of remotely resolved StepActions in SLSA resolvedDependencies as entries named "stepAction/{stepName}", enabling full traceability of step definitions in TaskRun and PipelineRun provenance.

@tekton-robot tekton-robot requested review from ab-ghosh and enarha June 30, 2026 10:28
@tekton-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign lcarva after the PR has been reviewed.
You can assign the PR to them by writing /assign @lcarva in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot tekton-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Jun 30, 2026
@ngelman1 ngelman1 force-pushed the StepAction-origin-wiring branch 2 times, most recently from 96e6234 to d4a946e Compare July 1, 2026 07:14
@anithapriyanatarajan

Copy link
Copy Markdown
Contributor

@ngelman1 - Thank you for the PR. Please consider incorporating the points:

  1. Add e2e test to handle this scenario, that covers the below:
  1. Submit a TaskRun whose taskSpec.steps[0] references a remote StepAction via the git resolver
  2. Wait for Chains to sign and annotate it
  3. Fetch and decode the SLSA attestation
  4. Assert predicate.resolvedDependencies contains {"name": "stepAction/", "uri": "", "digest": {...}}
  1. Update release notes to reflect something like below:
    Capture the origin (URI + digest) of remotely resolved StepActions in SLSA resolvedDependencies as entries named "stepAction/{stepName}", enabling full traceability of step definitions in TaskRun and PipelineRun provenance.

@ngelman1 ngelman1 force-pushed the StepAction-origin-wiring branch from d4a946e to 9d267f9 Compare July 6, 2026 12:17
@ngelman1

ngelman1 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor Author

@ngelman1 - Thank you for the PR. Please consider incorporating the points:

  1. Add e2e test to handle this scenario, that covers the below:
  1. Submit a TaskRun whose taskSpec.steps[0] references a remote StepAction via the git resolver
  2. Wait for Chains to sign and annotate it
  3. Fetch and decode the SLSA attestation
  4. Assert predicate.resolvedDependencies contains {"name": "stepAction/", "uri": "", "digest": {...}}
  1. Update release notes to reflect something like below:
    Capture the origin (URI + digest) of remotely resolved StepActions in SLSA resolvedDependencies as entries named "stepAction/{stepName}", enabling full traceability of step definitions in TaskRun and PipelineRun provenance.

Added! thanks for commenting
(btw, I used a stepAction task from pipelines. we do not have anyhthing in this repo. Should I add a simple one under example?)

…sk. saved in SLSA provenance resolvedDependency
@ngelman1 ngelman1 force-pushed the StepAction-origin-wiring branch from 9d267f9 to e627ee8 Compare July 6, 2026 13:26
@enarha

enarha commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Code Review

Thanks for the PR — the direction is right and the general approach is sound. Four issues worth addressing before merge:

1. fromRemoteStepActions bypasses the WithStepActionsResults gate (all format versions affected)

material.FromStepActionsResults at line 214 of resolved_dependencies.go is inside if opts.WithStepActionsResults {}. The new fromRemoteStepActions(tro) appended after the closing brace is not. v2alpha3 callers pass resolveddependencies.ResolveOptions{} (zero value) — see v2alpha3/internal/taskrun/taskrun.go:39 and v2alpha3/internal/pipelinerun/pipelinerun.go:43 — so v2alpha3 attestations now silently receive stepAction/ entries that were never part of that format's contract. Only v2alpha4 sets WithStepActionsResults: true.

Whether to gate this under WithStepActionsResults or a new dedicated flag is a design call, but the current unconditional behavior is inconsistent with how every other step-action data point is gated.

2. RemoveDuplicateResolvedDependencies silently drops entries when two steps share the same remote StepAction revision

The dedup function (line 98) keys on {Uri, Digest, Content} — the Name field is explicitly stripped before hashing. Its bypass guard is if !(name == TaskConfigName || name == PipelineConfigName). If two steps in the same TaskRun both reference the same StepAction at the same revision (identical URI+Digest), fromRemoteStepActions emits two descriptors — e.g. stepAction/build and stepAction/test — that are distinct only by name. The second entry is silently dropped because StepActionConfigName is not in the exception list, so the attestation records only one of the two steps as depending on the remote action.

The test suite only covers the case where each step has a distinct digest — the same-digest scenario is not tested and would currently produce an incomplete attestation.

3. E2E test pins to a mutable main branch in an external repo

test/e2e_test.go — the git resolver params use revision: "main" against https://github.com/tektoncd/pipeline. The file examples/v1/taskruns/stepaction.yaml exists today, but main is a moving ref. If that file is renamed, moved, or the resolver behavior changes, the test breaks for reasons unrelated to Chains. Existing Chains e2e tests that use the git resolver pin to a specific commit SHA or tag rather than a branch head — recommend doing the same here.

4. Empty URI passes through into the attestation without validation

GetRemoteStepActions in objects.go filters on step.Provenance != nil && step.Provenance.RefSource != nil but does not check RefSource.URI != "". A resolver that populates RefSource with only a digest (no URI) produces a ResourceDescriptor{Name: "stepAction/x", Uri: ""} — structurally invalid per SLSA. The analogous task-level helper AddSLSATaskDescriptor returns nil when URI is absent; aligning GetRemoteStepActions with that pattern (skip or log-and-skip entries with an empty URI) would be consistent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants