Repository navigation
Conversation
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)
|
[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 |
|
/kind bug |
There was a problem hiding this comment.
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
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.
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)
|
/retest |
There was a problem hiding this comment.
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
Open (2)
Resolved since last review (1)
| case annotations != nil && annotations.Kind == yaml.MappingNode && | ||
| annotations.Style != yaml.FlowStyle && len(annotations.Content) > 0: |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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)

Changes
tkn task signandtkn pipeline signmarshalled the parsed resource back toYAML, 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 applywith
strict decoding error: unknown field "spec.steps[0].resources".Signnow takes the document the resource was read from and inserts thesignature 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 exactlythe kind of unrelated diff the catalog
verify-generatedcheck trips over.Two things worth flagging for review:
Signtakes an extra argument. All three call sites already had the filecontents to hand, so the change is one argument at each.
metadataorannotationsis written in flow style, since there is no lineto insert. Everything else is handled: existing annotations, no annotations,
annotations: {}, an emptyannotations:key, a leading---, and leadingcomments. Happy to fall back to the old behaviour there instead if you prefer.
go.yaml.in/yaml/v3was already vendored as an indirect dependency, sogo mod tidymoves one line andgo mod vendorproduces no change.Verified by reverting the fix: the new tests then report
resources: {}presentand the step sequence reformatted from
- name: echointo- image: ubuntu/name: echo, reproducing both issues exactly.Submitter Checklist
make checkmake generatedRelease Notes