-
Notifications
You must be signed in to change notification settings - Fork 3
feat | GitHub workflow to pull and sign images #26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Reviewer's GuideAdds a GitHub Actions workflow that automates pulling, re-tagging, pushing, and cryptographically signing Docker images using repository_dispatch or manual triggers, OIDC-backed Docker Hub authentication, digest extraction, Cosign installation, and logging for post-sign verification. Sequence Diagram for the Image Pull, Tag, Push, and Sign WorkflowsequenceDiagram
actor User/System
participant GHA as GitHub Actions Workflow
participant DockerHub as Docker Hub
participant Cosign
User/System->>GHA: Trigger (repository_dispatch: sign-image / workflow_dispatch with payload)
GHA->>GHA: Checkout code
GHA->>DockerHub: Login (credentials from client_payload)
GHA->>DockerHub: Pull Image (client_payload.pull_tag)
GHA->>GHA: Extract image_name (from client_payload.push_tag)
GHA->>GHA: Get Image Digest (from client_payload.pull_tag)
GHA->>GHA: Install Cosign (v2.2.1)
GHA->>GHA: Tag Image (client_payload.pull_tag to client_payload.push_tag)
GHA->>DockerHub: Push Image (client_payload.push_tag)
GHA->>Cosign: Sign Image (client_payload.push_tag)
Cosign-->>GHA: Confirmation
GHA->>GHA: Output Digest for Verification
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @akash2237778 - I've reviewed your changes and found some issues that need to be addressed.
Blocking issues:
- Potential security risk in using repository_dispatch payload for credentials (link)
General comments:
- After pushing the image you should retrieve the new digest rather than using the digest from the original pulled image, so your verification output remains accurate.
- Make the cosign signing step explicit by specifying whether you’re using keyless OIDC or passing a private key (e.g. with --key), and ensure any required environment variables (COSIGN_PASSWORD or key) are defined so the workflow doesn’t hang.
Here's what I looked at during the review
- 🟡 General issues: 3 issues found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
||
on: | ||
repository_dispatch: | ||
types: [sign-image] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚨 issue (security): Potential security risk in using repository_dispatch payload for credentials
Store credentials as GitHub secrets instead of passing them via client_payload
, and restrict workflow dispatch permissions to trusted users.
uses: docker/login-action@v3 | ||
with: | ||
registry: docker.io | ||
username: ${{ github.event.client_payload.docker_username }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@uniqueg do you think Container Registry will remain same for one pubgrade instance? If yes, then we can move these registry credentials to Github Secrets.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instance: yes. Implementation: no. That is, one organization deploying Pubgrade will almost certainly use a different set of credentials than another organization deploying their own Pubgrade instance.
Would one code repository use different instances/deployments of Pubgrade, connected with different registries? Possibly. But it's not a feature we absolutely have to support. At least not now.
Does that answer your question?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @akash2237778! Looks pretty good, but I have a couple of questions. Most importantly, I think this really needs comprehensive documentation.
|
||
- name: Sign container image | ||
env: | ||
COSIGN_EXPERIMENTAL: "1" |
There was a problem hiding this comment.
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 that? Why is it required? What are potential risks?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This flag is needed to use Keyless signing in Cosign. I'll check if we can remove it with some latest version of cosign
run: docker tag ${{ github.event.client_payload.pull_tag }} ${{ github.event.client_payload.push_tag }} | ||
|
||
- name: Push Tagged Image | ||
run: docker push ${{ github.event.client_payload.push_tag }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we pushing before we are signing? Is this the usual flow, i.e., are only pushed images signed (on the registry)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct this is the usual flow, only pushed images are signed. But image integrity is maintained.
- name: Output Digest for Verification | ||
run: | | ||
echo "Image pushed and signed as ${{ github.event.client_payload.push_tag }} with digest $IMAGE_NAME@${{ steps.get-digest.outputs.digest }}" | ||
echo "Verify with: cosign verify $IMAGE_NAME@${{ steps.get-digest.outputs.digest }}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want to explicitly verify the signed image against the digest ourselves in an additional step so that we are sure everything worked as expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, we can do that. I'll push this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not immediately obvious why we are pulling an existing image, retag it, push it and sign it. Where does the original image come from? And what event would typically trigger this workflow?
Can you explain in the documentation, together with a concrete example, how this whole process works? The use case has to be crystal clear. Ideally include a diagram.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more question I have is in the linked issue: Do you think other container registries (Docker Hub) would work as well?
Description
This GitHub Actions workflow automates the process of pulling, tagging, pushing, and signing a container image. Triggered by a repository_dispatch event (sign-image) or manual workflow_dispatch, it runs on an ubuntu-latest environment with the following steps:
Checkout Code: Clones the repository using actions/checkout@v4.
Docker Hub Login: Authenticates with Docker Hub using provided credentials from repository_dispatch API call.
Pull Image: Pulls the specified container image using the pull_tag input.
Extract Image Name: Derives the image name from the push_tag input and stores it in the environment.
Get Image Digest: Retrieves the image digest for verification.
Install Cosign: Installs Cosign (v2.2.1) for signing the image.
Tag and Push Image: Tags the pulled image with push_tag and pushes it to Docker Hub.
Sign Image: Signs the pushed image using Cosign with experimental features enabled.
Output Digest: Logs the signed image's digest for verification.
The workflow uses OIDC token permissions for secure operations and outputs the digest for post-signing verification. It ensures a streamlined process for pulling, tagging, pushing, and cryptographically signing container images.
Fixes #25
Type of change
Please delete options that are not relevant.
Checklist:
Summary by Sourcery
Add a GitHub Actions workflow to automate pulling, tagging, pushing, and signing Docker images with Cosign
New Features:
Enhancements:
CI: