TEP-0164: Tekton Artifacts Phase 2 — External Storage for Artifacts and Results#1248
TEP-0164: Tekton Artifacts Phase 2 — External Storage for Artifacts and Results#1248vdemeester wants to merge 4 commits intotektoncd:mainfrom
Conversation
This TEP proposes a new approach to handling large Task results by introducing external storage backends with pluggable providers. Key features: - New result type: `type: external` for large results - Pluggable backends: S3, GCS, OCI registry, Azure, PVC - No per-pod overhead (unlike TEP-0127 sidecar approach) - Per-result opt-in with transparent resolution - Integration with Tekton Chains and Results This addresses the 4KB/12KB termination message limits and the 1.5MB CRD size limit that affect use cases like Tekton Chains signing, SBOM generation, and multi-image build pipelines. Related issues: - tektoncd/pipeline#4012 - tektoncd/pipeline#4808 - tektoncd/pipeline#8448 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
arewm
left a comment
There was a problem hiding this comment.
I haven't done a comprehensive review, but some initial comments.
| - **SBOM Generation**: Software Bill of Materials documents are typically | ||
| 10KB-10MB in size |
There was a problem hiding this comment.
Do you envision that this is a real use case? I wouldn't expect that a SBOM is exposed in a result as text. Instead, I would expect that SBOMs are stored elsewhere and just referenced. This way, SBOM producers have the ability to do additional things like sign the SBOM as a protection against its integrity.
| - **SBOM Generation**: Software Bill of Materials documents are typically | ||
| 10KB-10MB in size | ||
| - **Build Manifests**: Multi-architecture build manifests listing all produced | ||
| artifacts |
There was a problem hiding this comment.
Is this about exposing all arch-specific manifests that are produced in a multi-arch image? If so, I think we can clarify that. Tasks may want to expose results for each related digest produced which can include an OCI Image Index as well as multiple OCI Image Manifests.
| **Use Case 2: SBOM Generation** | ||
|
|
||
| A Task generates an SBOM in SPDX or CycloneDX format that needs to be | ||
| passed to an attestation Task. | ||
|
|
||
| ```yaml | ||
| results: | ||
| - name: sbom | ||
| type: external | ||
| description: SPDX SBOM document | ||
| ``` |
There was a problem hiding this comment.
Do you envision that this is a real use case? I wouldn't expect that a SBOM is exposed in a result as text. Instead, I would expect that SBOMs are stored elsewhere and just referenced. This way, SBOM producers have the ability to do additional things like sign the SBOM as a protection against its integrity.
This would be one task producing an SBOM and another one signing/attesting it? Would we expect this to happen as separate tasks or would it make more sense to happen as separate steps?
|
|
||
| 7. **Garbage Collection**: External results should be cleanable when TaskRuns | ||
| are deleted. For MVP, operators can rely on storage lifecycle policies. | ||
| 8. **Namespace-level configuration**: Per-namespace storage backend overrides |
There was a problem hiding this comment.
Would you envision that this is most likely to be used for overriding the configuration if an OCI registry is leveraged?
There was a problem hiding this comment.
Yes, but also maybe switch backend from one namespace to the others.
| A Task generates an SBOM in SPDX or CycloneDX format that needs to be | ||
| passed to an attestation Task. |
There was a problem hiding this comment.
Reading into this use case a little more, do perceive that this is used strictly for string-like parameters? Or would this be able to be used for passing arbitrary data between tasks (i.e. an implementation of TEP 0139-trusted-artifacts)?
| enabled or no backend is configured, the controller should reject the | ||
| resource with a clear error message: |
| - Attempting to declare a Pipeline result as `type: string` when referencing | ||
| a very large external Task result will fail with a clear error message. |
There was a problem hiding this comment.
What do you mean by this? How does this differ from the prior behavior of PipelineRun results?
| - Storage backend availability affects Pipeline reliability | ||
|
|
||
| **Mitigations:** | ||
| - Content-addressable references enable caching |
There was a problem hiding this comment.
How would this interact with clusters that have caching configured? If an OCI backend is used, for example, would it be possible for a cluster to cache the result that it pushes so that we would be able to get cache-hits when fetching the large result?
| azure.credentialsSecret: "tekton-results-azure-creds" | ||
| ``` | ||
|
|
||
| ### Namespace-Level Configuration |
There was a problem hiding this comment.
Would it be possible to have a per-pipelinerun configuration as well (i.e. based on credentials linked to the Service Accounts)?
| backend: "oci" | ||
| oci.registry: "team-a-registry.example.com" | ||
| oci.repository: "tekton/results" | ||
| oci.credentialsSecret: "team-a-registry-creds" |
There was a problem hiding this comment.
Storing a lot of results can be hard to process in an OCI registry if a user might want to go look at it. Do you think it would be reasonable to keep all results "together" for a PipelineRun? This might look like producing a single "reference" OCI artifact for the PipelineRun and then attaching individual results to that? One could even generate recursive referring objects where you have TaskRun "reference" artifacts attached to the PipelineRun upon TaskRun initialization.
Rewrote TEP-0164 to unify TEP-0147 (provenance), TEP-0139 (trusted artifacts API), and external storage backends into a single coherent proposal. - Adopted TEP-0139's declarative Artifact API with spec.artifacts.inputs/outputs and path variables - Extended ArtifactValue with StorageRef, Size, Inline fields - Replaced injected Steps with entrypoint + init container - Added pluggable backends (OCI, S3, GCS, PVC) over PVC-only - Addressed all 12 @arewm review comments from PR tektoncd#1248 - Added Pipeline-level artifact binding syntax - Positioned as TEP-0147 Phase 2 implementing TEP-0139 goals
Added Future Work section describing the convergence path from separate params/results/artifacts fields toward a unified inputs/outputs model, with mid-term results-as-sugar and long-term API v2 unification.
|
/wip |
…levels - Restructure implementation plan to OCI-only Phase 1 (S3/GCS/PVC deferred) - Add OCI Artifact Format Specification section: manifest structure, media types, config blob, multi-file tar+gzip, PipelineRun grouping via OCI referrers, tagging convention, authentication model - Add 4-level repository configuration: cluster, namespace, Pipeline annotation, PipelineRun annotation with clear resolution order - Promote OCI PipelineRun grouping from optional to default - Add Konflux CI links throughout (org, ADR-0036, build-trusted-artifacts, individual StepAction YAMLs) - Update last-updated date
Summary
This TEP extends TEP-0147 (Tekton Artifacts Phase 1) with external storage backends, unifying two related problems:
Approach
Rather than three separate TEPs solving overlapping problems, this TEP unifies TEP-0147's provenance structure + TEP-0139's Artifact API + external storage backends into a single design.
Key design decisions:
StorageRef,Size,Inlinefields to existingArtifactValuetypespec.artifacts.inputs/outputson Tasks with$(inputs.name.path)/$(outputs.name.path)variablesartifacts.inputs[].from: tasks.producer.outputs.foowith implicit DAG edgesbuild-trusted-artifacts(ADR-0036)OCI-First Implementation
Phase 1 focuses exclusively on OCI registry as the storage backend because:
The TEP specifies the OCI artifact format: manifest structure, media types, multi-file archiving, PipelineRun grouping via OCI referrers, and tagging conventions.
Additional backends (S3, GCS, PVC) are deferred to Phase 2 behind a
Providerinterface.Repository Configuration
OCI repository path is configurable at 4 levels (highest priority first):
Use Cases
Convergence Vision
The TEP includes a future work section describing the path toward unified
spec.inputs/spec.outputsin a future API v2, where params, results, and artifacts converge into a single model.Related
/kind tep