Skip to content

Fix syncing cosign signature tags when using remote include_tags field#2328

Merged
gerrod3 merged 1 commit into
pulp:mainfrom
gerrod3:sig-tag-sync-fix
May 13, 2026
Merged

Fix syncing cosign signature tags when using remote include_tags field#2328
gerrod3 merged 1 commit into
pulp:mainfrom
gerrod3:sig-tag-sync-fix

Conversation

@gerrod3
Copy link
Copy Markdown
Contributor

@gerrod3 gerrod3 commented Apr 17, 2026

fixes: #2096
Assisted by: claude-opus-4.6

Need to work on tests for this, going to update our local GH packages to include some cosign attachments.

📜 Checklist

  • Commits are cleanly separated with meaningful messages (simple features and bug fixes should be squashed to one commit)
  • A changelog entry or entries has been added for any significant changes
  • Follows the Pulp policy on AI Usage
  • (For new features) - User documentation and test coverage has been added

See: Pull Request Walkthrough

@gerrod3 gerrod3 force-pushed the sig-tag-sync-fix branch 2 times, most recently from 17b7227 to 9f0c946 Compare April 24, 2026 16:03
@gerrod3 gerrod3 force-pushed the sig-tag-sync-fix branch 4 times, most recently from 2c2c13e to a1dde1b Compare May 6, 2026 17:10
self._full_tag_list, self.remote.include_tags, exclude_tags_and_cosign
)
else:
tag_list = self._full_tag_list
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.

Could you comment this inline a bit better?

e.g. if the goal was to fix the cosign tags being silently skipped, then why are the cosign tags being added to the exclusion list here?

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.

Is the point just to make a separate call to self._process_tags() w/ a separate log message?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yep, basically if we are using includes/excludes then I want to process all non cosign tags first, figure out every manifest that we synced, then go through and sync every cosign tag that matches a synced manifest. This is to ensure we only sync the cosign tags of the filtered tags the user requested. The process needs to be done in two steps to make sure we sync everything needed, but nothing extra.

If no includes/excludes then we can grab everything in one go, no need to differentiate between the two.

companion_tags, signature_source, msg="Processing Cosign Companion Tags"
)

def _find_cosign_companion_tags(self):
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.

Likewise some comments about the structure of the tags and the transformations going on here would be nice.

return True
return False

def _is_cosign_companion_tag(self, tag_name, media_type, content_data):
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.

Could be unit tested? self isn't actually required.

Copy link
Copy Markdown
Contributor

@dralley dralley May 11, 2026

Choose a reason for hiding this comment

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

Unit testing _has_cosign_signature and _find_cosign_companion_tags is likely possible also, just more difficult.

But in any case you can skip the unit tests if you think they aren't needed.

@gerrod3 gerrod3 force-pushed the sig-tag-sync-fix branch from a1dde1b to b574fb1 Compare May 13, 2026 01:56
@gerrod3 gerrod3 requested a review from dralley May 13, 2026 02:02
def _is_cosign_companion_tag(self, tag_name, media_type, content_data):
"""Check if a fetched tag is a cosign companion tag."""
if tag_name.startswith("sha256-"):
if len(tag_name) == 71:
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.

What is the significance of "71", specifically?

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.

(I know what it is from context elsewhere in the PR, but it's not obvious locally)

Copy link
Copy Markdown
Contributor Author

@gerrod3 gerrod3 May 13, 2026

Choose a reason for hiding this comment

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

Do you want me to change it to len("sha256-") + 64? Re:significance - v3 tags are just sha256- no suffix.

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.

Just comment as such


tags = container_tag_api.list(repository_version=synced_repo.latest_version_href)
manifests = container_manifest_api.list(repository_version=synced_repo.latest_version_href)
assert tags.count == 3 # manifest_a, sha256-<a-digest>.sig, sha256-<a-digest>.att
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.

Is there any way to check the actual names and not just the count?

@gerrod3 gerrod3 force-pushed the sig-tag-sync-fix branch from b574fb1 to 6bf1481 Compare May 13, 2026 03:08
self.stage._cosign_tags = [f"{cosign_key}.sig"]

self.assertTrue(await self.stage._has_cosign_signature(digest))
self.stage.remote.get_downloader.assert_not_called()
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.

Is this actually valuable / relevant?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For v2 tags we can just check the naming scheme of the tag since they have special suffixes. For v3 tags we need to check the manifest of the tag to make sure its internals are for a v3 tag. In theory we could check the internals of v2 to be safe or skip the internal check of v3 if the name is sha256-<digest>, but that's what this check is testing. V2 is just a name check, v3 is a manifest check and thus requires a request.

@gerrod3 gerrod3 merged commit 99f4472 into pulp:main May 13, 2026
13 of 14 checks passed
@gerrod3 gerrod3 deleted the sig-tag-sync-fix branch May 13, 2026 20:57
@patchback
Copy link
Copy Markdown

patchback Bot commented May 13, 2026

Backport to 2.26: 💚 backport PR created

✅ Backport PR branch: patchback/backports/2.26/99f4472004500aa82a76fa4886dae77f9c6605ac/pr-2328

Backported as #2361

🤖 @patchback
I'm built with octomachinery and
my source is open — https://github.com/sanitizers/patchback-github-app.

@patchback
Copy link
Copy Markdown

patchback Bot commented May 13, 2026

Backport to 2.27: 💚 backport PR created

✅ Backport PR branch: patchback/backports/2.27/99f4472004500aa82a76fa4886dae77f9c6605ac/pr-2328

Backported as #2360

🤖 @patchback
I'm built with octomachinery and
my source is open — https://github.com/sanitizers/patchback-github-app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

signatures missing

2 participants