Skip to content

fix(trustedresources): preserve the input document - #3245

Open
somaz94 wants to merge 3 commits into
tektoncd:mainfrom
somaz94:fix/task-sign-preserve-yaml
Open

somaz94 wants to merge 3 commits into
tektoncd:mainfrom
somaz94:fix/task-sign-preserve-yaml

Conversation

@somaz94

@somaz94 somaz94 commented Sep 14, 2026

Copy link
Copy Markdown

Changes

tkn task sign and tkn pipeline sign marshalled the parsed resource back to
YAML, so the whole document was rewritten rather than annotated. Keys were
reordered, sequences reflowed, and zero valued fields of the embedded Kubernetes
types were emitted, including the resources: {} that Tekton rejects on apply
with strict decoding error: unknown field "spec.steps[0].resources".

Sign now takes the document the resource was read from and inserts the
signature annotation into it directly, so the signed file differs from the input
by that annotation alone. Both reported symptoms come from the same cause, so
this covers them together.

The document is parsed only to locate the insertion point. Re-serializing the
parsed tree was the simpler option but does not round trip: a folded scalar
(description: >-) comes back with its line breaks collapsed, which is exactly
the kind of unrelated diff the catalog verify-generated check trips over.

Two things worth flagging for review:

  • Sign takes an extra argument. All three call sites already had the file
    contents to hand, so the change is one argument at each.
  • Signing now fails, rather than silently reformatting, on a document whose
    metadata or annotations is written in flow style, since there is no line
    to insert. Everything else is handled: existing annotations, no annotations,
    annotations: {}, an empty annotations: key, a leading ---, and leading
    comments. Happy to fall back to the old behaviour there instead if you prefer.

go.yaml.in/yaml/v3 was already vendored as an indirect dependency, so
go mod tidy moves one line and go mod vendor produces no change.

Verified by reverting the fix: the new tests then report resources: {} present
and the step sequence reformatted from - name: echo into - image: ubuntu /
name: echo, reproducing both issues exactly.

Submitter Checklist

  • Includes tests (if functionality changed/added)
  • Run the code checkers with make check
  • Regenerate the manpages, docs and go formatting with make generated
  • Commit messages follow commit message best practices

Release Notes

`tkn task sign` and `tkn pipeline sign` now only add the signature annotation instead of rewriting the whole YAML document, which also stops them emitting an invalid `resources: {}` into steps.

tkn task sign and tkn pipeline sign marshalled the parsed resource back
to YAML, which rewrote the whole document: it reordered keys, reflowed
sequences, and emitted zero valued fields of the embedded Kubernetes
types, including the resources: {} that Tekton rejects on apply.

Sign now takes the document the resource was read from and inserts the
signature annotation into it, so the signed file differs from the input
by that annotation alone. The document is parsed only to locate the
insertion point: re-serializing the parsed tree collapses the line
breaks of a folded scalar such as description: >-.

Fixes tektoncd#2895
Fixes tektoncd#2894

Signed-off-by: somaz <genius5711@gmail.com>
Assisted-by: Claude Opus 5 (via Claude Code)
@tekton-robot tekton-robot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Sep 14, 2026
@tekton-robot

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign chmouel after the PR has been reviewed.
You can assign the PR to them by writing /assign @chmouel 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/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Sep 14, 2026
somaz94 added a commit to somaz94/somaz94 that referenced this pull request Sep 14, 2026
@somaz94

somaz94 commented Sep 16, 2026

Copy link
Copy Markdown
Author

/kind bug

@tekton-robot tekton-robot added the kind/bug Categorizes issue or PR as related to a bug. label Sep 16, 2026
@divyansh42
divyansh42 requested a balanced review from Copilot September 22, 2026 18:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Re-signing creates duplicate signature keys, and inserted annotations do not consistently preserve CRLF endings.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Preserves Task and Pipeline YAML formatting when adding trusted-resource signatures.

Changes:

  • Inserts signature annotations directly into source YAML.
  • Passes original document bytes through signing call sites.
  • Adds preservation and verification tests.
  • Promotes YAML v3 to a direct dependency.
File Description
pkg/​trustedresources/​sign.go Signs while preserving the source document.
pkg/​trustedresources/​sign_test.go Tests preservation and verification.
pkg/​trustedresources/​annotation.go Implements insertion; must replace existing signatures and preserve CRLF endings.
pkg/​trustedresources/​annotation_test.go Tests insertion; preservation checks should be order-sensitive.
pkg/​cmd/​task/​sign.go Passes Task source bytes.
pkg/​cmd/​pipeline/​sign.go Passes Pipeline source bytes.
go.mod Declares YAML v3 as a direct dependency.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pkg/trustedresources/annotation.go
Signing a document that already carried a signature inserted a second
tekton.dev/signature key, which strict YAML decoders reject. Replace
the existing entry instead, and refuse one that spans several lines
rather than rewrite part of it.

The new signature was also computed with the old annotation still on
the object, while Verify removes it before checking, so a re-signed
file did not verify. Drop the old signature before signing.

Inserted lines now use the document's own line ending, so a CRLF file
is not left with mixed endings, and the preservation tests compare
whole documents, so a reordered line fails them too.

Signed-off-by: somaz <genius5711@gmail.com>
Assisted-by: Claude Opus 5.5 (via Claude Code)
@divyansh42
divyansh42 requested a balanced review from Copilot September 23, 2026 18:58
@divyansh42

Copy link
Copy Markdown
Member

/retest

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Critical issues with YAML aliases and unsigned unknown fields must be resolved.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 High severity

Open (2)
Resolved since last review (1)

Comment on lines +69 to +70
case annotations != nil && annotations.Kind == yaml.MappingNode &&
annotations.Style != yaml.FlowStyle && len(annotations.Content) > 0:

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 12e7210. Signing now stops with an error when metadata, annotations or an existing tekton.dev/signature value carries an anchor, instead of editing through it, so an alias elsewhere in the file can no longer pick up the signature. The error cases in annotation_test.go cover all three.

o.SetAnnotations(a)
signedBuf, err := yaml.Marshal(o)

signedBuf, err := insertAnnotation(doc, SignatureAnnotation, encoded)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 12e7210. Sign now decodes the document strictly before signing and returns an error if it has a field the type does not define, so nothing can reach the signed file without being covered by the signature. One behavior change worth flagging: a v1 Task that sets computeResources on a step is now refused, because the v1beta1 type the CLI decodes into has no such field, whereas main signs it by silently dropping the field from the output. If you would rather keep accepting those files, I can fall back to the old marshalling path for them instead. Verify still decodes permissively, as it does on main, so tightening that side could be a follow-up.

Sign writes the input document with the signature added, but the
signature covers only the object decoded from it, and that decode
drops any field the Tekton type does not define. Such a field reached
the signed file unsigned, and verify decodes the same way, so changing
it did not invalidate the signature. Decode the document strictly
before signing and return an error for it instead.

Adding the annotation to an anchored metadata or annotations mapping
also changed every alias of that mapping, so a `labels: *common` alias
gained a signature entry the signed object never had, and the file
failed verification. Return an error rather than edit an anchored node.

Signed-off-by: somaz <genius5711@gmail.com>
Assisted-by: Claude Opus 5.5 (via Claude Code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Categorizes issue or PR as related to a bug. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants