Skip to content

TEP-0164: Tekton Artifacts Phase 2 — External Storage for Artifacts and Results#1248

Draft
vdemeester wants to merge 4 commits intotektoncd:mainfrom
vdemeester:vdemeester/tep-0164-external-results
Draft

TEP-0164: Tekton Artifacts Phase 2 — External Storage for Artifacts and Results#1248
vdemeester wants to merge 4 commits intotektoncd:mainfrom
vdemeester:vdemeester/tep-0164-external-results

Conversation

@vdemeester
Copy link
Member

@vdemeester vdemeester commented Feb 9, 2026

Summary

This TEP extends TEP-0147 (Tekton Artifacts Phase 1) with external storage backends, unifying two related problems:

  1. Larger Results — Overcoming the 4KB/12KB termination message limits and ~1.5MB CRD size constraints
  2. Trusted Artifacts — Establishing a chain of trust for data shared between Tasks (TEP-0139)

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:

  • Extends TEP-0147 — adds StorageRef, Size, Inline fields to existing ArtifactValue type
  • Adopts TEP-0139's declarative APIspec.artifacts.inputs/outputs on Tasks with $(inputs.name.path) / $(outputs.name.path) variables
  • OCI-first backend — OCI registry is the only Phase 1 backend, leveraging existing imagePullSecrets for auth and OCI referrers for PipelineRun grouping
  • Entrypoint + init container — transparent upload/download/verify without injected Steps or sidecars
  • Reference-based — only URI + digest stored in TaskRun status; content lives in external storage
  • Pipeline-level artifact bindingartifacts.inputs[].from: tasks.producer.outputs.foo with implicit DAG edges
  • Konflux CI compatible — OCI artifact format aligned with build-trusted-artifacts (ADR-0036)

OCI-First Implementation

Phase 1 focuses exclusively on OCI registry as the storage backend because:

  • Every Kubernetes cluster already has access to an OCI registry
  • Konflux CI uses OCI for trusted artifacts in production
  • Tekton Chains already stores attestations in OCI registries
  • Content-addressable storage provides native deduplication and caching
  • Auth reuses existing ServiceAccount imagePullSecrets — zero additional credential config in many setups

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 Provider interface.

Repository Configuration

OCI repository path is configurable at 4 levels (highest priority first):

Priority Source Use Case
1 PipelineRun annotations Caller-controlled, per-invocation
2 Pipeline annotations Pipeline author default
3 Namespace ConfigMap (TEP-0085) Team/project isolation
4 Cluster ConfigMap Cluster default

Use Cases

  • Multi-image build pipelines (Konflux) — pass 20+ image references between build and signing Tasks
  • SBOM generation — store large SBOMs externally, reference by digest in attestations (solves Rekor size limits)
  • ML model passing (Kubeflow Pipelines on Tekton) — pass datasets, models, metrics between pipeline steps
  • Test results processing — large JUnit XML output consumed by reporting Tasks

Convergence Vision

The TEP includes a future work section describing the path toward unified spec.inputs/spec.outputs in a future API v2, where params, results, and artifacts converge into a single model.

Related

/kind tep

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>
@tekton-robot tekton-robot added the kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). label Feb 9, 2026
@tekton-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please ask for approval from vdemeester after the PR has been reviewed.

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/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Feb 9, 2026
Copy link

@arewm arewm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't done a comprehensive review, but some initial comments.

Comment on lines +100 to +101
- **SBOM Generation**: Software Bill of Materials documents are typically
10KB-10MB in size
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +146 to +156
**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
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you envision that this is most likely to be used for overriding the configuration if an OCI registry is leveraged?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but also maybe switch backend from one namespace to the others.

Comment on lines +148 to +149
A Task generates an SBOM in SPDX or CycloneDX format that needs to be
passed to an attestation Task.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)?

Comment on lines +270 to +271
enabled or no backend is configured, the controller should reject the
resource with a clear error message:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this update the status of the CR?

Comment on lines +540 to +541
- Attempting to declare a Pipeline result as `type: string` when referencing
a very large external Task result will fail with a clear error message.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to have a per-pipelinerun configuration as well (i.e. based on credentials linked to the Service Accounts)?

Comment on lines +366 to +369
backend: "oci"
oci.registry: "team-a-registry.example.com"
oci.repository: "tekton/results"
oci.credentialsSecret: "team-a-registry-creds"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
@vdemeester
Copy link
Member Author

/wip

@vdemeester vdemeester marked this pull request as draft February 18, 2026 09:25
@tekton-robot tekton-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Feb 18, 2026
@tekton-robot tekton-robot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Feb 26, 2026
…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
@tekton-robot
Copy link
Contributor

The following Tekton test failed:

Test name Commit Details Required Rerun command
pull-community-teps-lint 3d33001 link true /test pull-community-teps-lint

@vdemeester vdemeester changed the title TEP-0164: Larger Results via External Storage with Pluggable Backends TEP-0164: Tekton Artifacts Phase 2 — External Storage for Artifacts and Results Feb 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. kind/tep Categorizes issue or PR as related to a TEP (or needs a TEP). size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants