-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
Have the starter docker-publish
action sign digests.
#1255
Conversation
# https://github.com/sigstore/cosign-installer | ||
- name: Install cosign | ||
if: github.event_name != 'pull_request' | ||
uses: sigstore/cosign-installer@1e95c1de343b5b0c23352d6417ee3e48d5bcd422 |
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.
uses: sigstore/cosign-installer@1e95c1de343b5b0c23352d6417ee3e48d5bcd422 | |
uses: sigstore/cosign-installer@main |
To be consistent with our guidance? Unless the style for these examples requires pinning to a git commit
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.
I was trying to be consistent with the other steps, which do this.
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.
We require that starter-workflows pin to a specific commit when including actions not maintained by GitHub. In addition pinning to a ref like main is not recommended as updates could break customers.
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.
@chrispat since we are a security-focused action, we recommend using @main
for the action to adopt fixes ASAP
and to optionally pin a specific release version of the tool itself if that degree of stability is desired. I appreciate the desire for stability in these starter workflows, though
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.
As folks involved in supply chain security, we also understand a desire to be very intentional about picking up changes to dependencies 😉
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.
Maybe encoding the @main
recommendation in a comment above that step is a reasonable compromise?
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.
You can see what Ruby does: https://github.com/actions/starter-workflows/blob/main/ci/ruby.yml#L29
(I'd encourage you to encourage pinning to a released tag, not @main
, that's more Actions-idiomatic.)
@andymckay @chrispat This workflow sends data to a 3rd party service for the purposes of providing a public log of the signing activity. I think this is a good reason to do it, but I'd love your insight on how best to set expectations on this for customers. |
4225ddf
to
cc91ee0
Compare
ci/docker-publish.yml
Outdated
# Sign the resulting Docker image digest except on PR | ||
# https://github.com/sigstore/cosign | ||
- name: Sign the published Docker image | ||
if: github.event_name != 'pull_request' |
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.
Was chatting with @steiza, and he brought up an interesting point here. For private repositories, the transparency log will effectively leak the identity of a private repository. We had the thought that we should add an if to only sign for public repositories. Users could obviously opt-in to signing for private repositories, but this would not leak their private repo information by default.
@mattmoor what do you think?
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.
That works for me if there's a way to express that in actions (I think the best UX here would be for it to show up as skipped like it would for PRs).
I suspect the next best would be for us to add an option to cosign that lets us toggle this off (perhaps with a clear warning) when the image is private (I can discuss with @dlorenc @dekkagaijin et al and try to land something in 1.4).
WDYT?
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.
I staged a fix in cosign for this here: sigstore/cosign#1116, which would let us drop the --force
(although I'll probably add a comment indicating that folks comfortable with this can add --force
to publish to the transparency log).
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.
Yep, it's very doable. You could add the step below, and then add the (!(env.IS_PRIVATE)) to your existing if statement and I think it would do the job.
- name: Confirm this is a public repository
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
TEMP=$(gh api repos/$GITHUB_REPOSITORY --jq '.private')
echo "IS_PRIVATE=$TEMP" >> $GITHUB_ENV
- name: Run if public
if: (!(env.IS_PRIVATE))
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.
Awesome TIL! I'll try that out and then update this. I realize that this'll end up skipping signing entirely, so we may still want to adopt the cosign change and drop this once we cut 1.4.
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.
ok, I was able to get this working in my little sample repo:
- name: Confirm this is a public repository
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
run: |
TEMP=$(gh api repos/$GITHUB_REPOSITORY --jq '.private')
echo "IS_PRIVATE=$TEMP" >> $GITHUB_ENV
- name: Sign the container image (if public)
if: ${{ env.IS_PRIVATE == 'false' }}
env:
COSIGN_EXPERIMENTAL: "true"
run: cosign sign ghcr.io/${{ github.repository }}@${{ steps.push-step.outputs.digest }}
This ran fine (with signing) in the public repo, and from a private repo instantiated from it the signing step was skipped. I'll update the PR with this shortly, thanks for the tip!
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.
Ok, cool this should be updated. When we cut cosign 1.4
we can simplify things, since my PR upstream landed.
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.
Given you have the whole event payload to work with already on disk you don't need to make the api call. Each event has a repository object and that will tell you if it is public or private. Should be something like ${{ github.event.repository.private == 'false' }}
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.
Looks like what @steiza also said. This should be fixed in the latest revision!
ci/docker-publish.yml
Outdated
# Sign the resulting Docker image digest except on PRs and private repos | ||
# https://github.com/sigstore/cosign | ||
- name: Sign the published Docker image | ||
if: ${{ github.event_name != 'pull_request' && env.IS_PRIVATE == 'false' }} |
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.
I came here to suggest that we only run this on public repos, but you beat me to it!
I think we could simplify the implementation a bit though, by not having the above step and just checking if: ${{ !github.event.repository.private }}
here.
It shouldn't be the default, but there might be use-cases where a private repo wants to use keyless signing, and is okay with the public record, so we could have an opt-in env variable (COSIGN_USE_PUBLIC_KEYLESS_SIGNING
?) that uses keyless signing regardless. Not required, just a suggestion.
Thanks for contributing this functionality!
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.
@steiza even better, I'll update the PR. The next version of cosign
will make it so we can always sign and for private repos they would add --force
if they want to publish to the transparency log, which feels like exactly the opt-in we want.
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.
Perfect, this is much tighter, and I just tried it on my public and private demo repos and it works like a charm. ✨
Thanks again @steiza !
7c81c83
to
326dc04
Compare
Quick update for everyone: I'm working on a communications plan so that we notify users when this change goes in. I'd like to target Monday 12/6 to get everything out, but we might need to move things around depending on internal reviews. Really appreciate all the collaboration here! |
Cool, I'll try to keep things rebased 👍 |
326dc04
to
b08ab3a
Compare
This change installs `sigstore/cosign` using the `cosign-installer` action, and uses sigstore's "keyless" signing process to sign the resulting image digest using the action's identity token (see: `id-token: write`). Signed-off-by: Matt Moore <mattomata@gmail.com>
b08ab3a
to
4e1ad5a
Compare
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.
Changes look good to me. Thanks for the collaboration all!
#1255
دریافت Outlook برای Android<https://aka.ms/AAb9ysg>
…________________________________
From: Bishal Prasad ***@***.***>
Sent: Monday, December 6, 2021 8:36:06 PM
To: actions/starter-workflows ***@***.***>
Cc: Subscribed ***@***.***>
Subject: Re: [actions/starter-workflows] Have the starter `docker-publish` action sign digests. (PR #1255)
Merged #1255<#1255> into main.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub<#1255 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/ATTU54E4E5QVCECS6NPN4IDUPTUP5ANCNFSM5IIGUMIQ>.
|
@mattmoor the updated workflow failed for my docker repo.
Can you please check it at priority and let me know if this can be widespread? |
I will check it out now, I was in a meeting when things merged, but I wonder if it is the capitals in your username, which I don't believe are allowed in Docker repository names (not sure how ghcr.io maps this?) |
Looks like that's the case: # crane ls ghcr.io/bishal-pdMSFT/docker-app
2021/12/06 10:15:51 reading tags for ghcr.io/bishal-pdMSFT/docker-app: parsing repo "ghcr.io/bishal-pdMSFT/docker-app": repository can only contain the runes `abcdefghijklmnopqrstuvwxyz0123456789_-./`: bishal-pdMSFT/docker-app Depending on how this is handled by |
Looks like buildkit is implicitly making the username lowercase: https://github.com/bishal-pdMSFT/docker-app/runs/4434089694?check_suite_focus=true#step:7:187 I assume this is roughly what we want here. Are github usernames guaranteed to be unique regardless of case? |
I confirmed that this works for me here: https://github.com/mattmoor/zero-friction-actions/runs/4434363881?check_suite_focus=true Let me open an issue here to track the uppercase issue, and discuss options for fixes. |
Looks like account name is case insensitive. I tried changing my account name to another name with different case and it was not allowed. |
Confirmed internally as well. It is case insensitive. |
And for the first time I realize the benefit of choosing a CAPS letter in my account name 😁 |
Looks like this is |
This change installs
sigstore/cosign
using thecosign-installer
action,and uses sigstore's "keyless" signing process to sign the resulting image
digest using the action's identity token (see:
id-token: write
).Signed-off-by: Matt Moore mattomata@gmail.com
Pre-requisites
Tasks
For all workflows, the workflow:
.yml
file with the language or platform as its filename, in lower, kebab-cased format (for example,docker-image.yml
). Special characters should be removed or replaced with words as appropriate (for example, "dotnet" instead of ".NET").For CI workflows, the workflow:
ci
directory.ci/properties/*.properties.json
file (for example,ci/properties/docker-publish.properties.json
).push
tobranches: [ $default-branch ]
andpull_request
tobranches: [ $default-branch ]
.release
withtypes: [ created ]
.docker-publish.yml
).For Code Scanning workflows, the workflow:
code-scanning
directory.code-scanning/properties/*.properties.json
file (for example,code-scanning/properties/codeql.properties.json
), with properties set as follows:name
: Name of the Code Scanning integration.organization
: Name of the organization producing the Code Scanning integration.description
: Short description of the Code Scanning integration.categories
: Array of languages supported by the Code Scanning integration.iconName
: Name of the SVG logo representing the Code Scanning integration. This SVG logo must be present in theicons
directory.push
tobranches: [ $default-branch, $protected-branches ]
andpull_request
tobranches: [ $default-branch ]
. We also recommend aschedule
trigger ofcron: $cron-weekly
(for example,codeql.yml
).Some general notes:
actions
organization, or