Skip to content

fix: strip OCI image tag when pushing attestation to registry - #464

Merged
bdehamer merged 5 commits into
mainfrom
bdehamer/strip-oci-subject-tag
Jul 29, 2026
Merged

fix: strip OCI image tag when pushing attestation to registry#464
bdehamer merged 5 commits into
mainfrom
bdehamer/strip-oci-subject-tag

Conversation

@bdehamer

@bdehamer bdehamer commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

When a subject is discovered via $GITHUB_ARTIFACTS_LIST for an OCI image, the
name may include a :tag (e.g. ghcr.io/owner/app:v1). Pushing the
attestation to the registry via @sigstore/oci fails on such names because
parseImageName only accepts a bare registry/repository reference:

Invalid image name: ghcr.io/github/attest-demo:30468266162

Approach

The image tag is preserved in the attestation subject (it's meaningful
provenance) and stripped only at the registry-push boundary in attest.ts.
The subject digest already pins the exact image, so a bare reference is
sufficient for attaching/pushing the attestation.

  • parseArtifactsList now records OCI subjects faithfully (tag preserved;
    downcaseOCI still applied for the push flow).
  • stripOCITag is applied in createAttestation for getRegistryCredentials,
    attachArtifactToImage, getRegistryURL, and the storage record — so the
    signed attestation keeps …/app:v1 while the push targets …/app.
  • Only a colon after the final / is treated as a tag, so a registry port
    (e.g. localhost:5000/repo) is preserved.

Testing

  • Unit tests for stripOCITag (tag stripping, port preservation, no-op cases)
    and tag-preservation in parse output.
  • Integration tests asserting the attestation subject retains the tag while the
    registry-push path and storage record receive the stripped name.
  • Full suite green at 100% coverage; dist/ regenerated.

@bdehamer bdehamer changed the title fix: strip :tag from discovered OCI subject names fix: strip OCI image tag when pushing attestation to registry Jul 29, 2026
@bdehamer
bdehamer marked this pull request as ready for review July 29, 2026 16:59
@bdehamer
bdehamer requested a review from a team as a code owner July 29, 2026 16:59
Copilot AI review requested due to automatic review settings July 29, 2026 16:59
@bdehamer
bdehamer marked this pull request as draft July 29, 2026 16:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes registry-push failures when an OCI subject discovered from $GITHUB_ARTIFACTS_LIST includes a :tag, by preserving the tag in the signed attestation subject while stripping it at the @sigstore/oci push boundary.

Changes:

  • Add stripOCITag helper and use it in createAttestation for registry credentials lookup, registry URL derivation, artifact attachment, and storage record naming.
  • Keep OCI tags in parseArtifactsList output (still optionally lowercased) so provenance subjects remain faithful.
  • Add unit + integration tests and update fixtures; regenerate dist/.
Show a summary per file
File Description
src/attest.ts Strips :tag at registry-push/storage-record boundary while keeping the attestation subject unchanged.
src/artifacts.ts Adds stripOCITag and documents tag preservation behavior for discovered OCI subjects.
tests/unit/artifacts.test.ts Adds unit coverage for tag preservation and stripOCITag behavior.
tests/integration/attest.test.ts Ensures tag is preserved in attestation subjects but stripped for registry push and storage record creation.
tests/fixtures/mocks.ts Adds a tagged OCI subject fixture for integration tests.
dist/index.js Updates bundled output to reflect source changes.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 5/6 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread __tests__/unit/artifacts.test.ts
Comment thread src/artifacts.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review details

  • Files reviewed: 5/6 changed files
  • Comments generated: 0 new
  • Review effort level: Low

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review details

  • Files reviewed: 5/6 changed files
  • Comments generated: 0 new
  • Review effort level: Low

bdehamer and others added 5 commits July 29, 2026 11:22
An OCI subject discovered from $GITHUB_ARTIFACTS_LIST can carry a :tag
in its name (e.g. ghcr.io/owner/app:12345) when the producer captures a
tagged reference. The registry-push path passes the subject name to
@sigstore/oci's parseImageName, which only accepts a bare
"registry/repository" reference and throws "Invalid image name" on any
tag.

Normalize OCI names by stripping a trailing :tag before dedup and
registry push. The entry's digest already pins the exact image, so the
tag is redundant. A registry port (e.g. localhost:5000/repo) is
preserved by only stripping a colon that appears after the final path
separator.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1f0a618f-2ff5-464e-9c70-e29acccf2c3d
Preserve any `:tag` on discovered OCI subjects in the attestation subject and
strip it only when attaching/pushing the attestation to the registry, where a
bare `registry/repository` reference is required. The subject digest already
pins the exact image.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1f0a618f-2ff5-464e-9c70-e29acccf2c3d
This is an internal push-boundary detail that doesn't need end-user docs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1f0a618f-2ff5-464e-9c70-e29acccf2c3d
Guard stripOCITag against digest references (e.g. "…/app@sha256:…"): the ':'
inside a digest is not a tag separator, so bail out when an '@' is present to
avoid returning a corrupt reference. Add unit coverage for digest and
tag+digest forms.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1f0a618f-2ff5-464e-9c70-e29acccf2c3d
Rename stripOCITag -> bareImageName and strip both tag and digest suffixes so
the registry-push boundary always receives a valid bare "registry/repository"
reference, covering all four reference forms:

  foo/bar, foo/bar:tag, foo/bar@sha256:…, foo/bar:tag@sha256:…

The previous "@"-guard merely returned digest references unchanged, which
@sigstore/oci still rejects. A registry port (colon before the final path
separator) is still preserved. Add unit coverage for the digest and
port+digest forms.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1f0a618f-2ff5-464e-9c70-e29acccf2c3d
@bdehamer
bdehamer force-pushed the bdehamer/strip-oci-subject-tag branch from babaca7 to 4bf3eb4 Compare July 29, 2026 18:23
@bdehamer
bdehamer marked this pull request as ready for review July 29, 2026 18:23
@bdehamer
bdehamer merged commit 508db95 into main Jul 29, 2026
6 checks passed
@bdehamer
bdehamer deleted the bdehamer/strip-oci-subject-tag branch July 29, 2026 20:11
@bdehamer
bdehamer restored the bdehamer/strip-oci-subject-tag branch July 30, 2026 04:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants