Skip to content
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

gh attestation verify fails with a reusable workflow. #9045

Closed
thepwagner opened this issue May 4, 2024 · 6 comments
Closed

gh attestation verify fails with a reusable workflow. #9045

thepwagner opened this issue May 4, 2024 · 6 comments
Assignees
Labels
bug Something isn't working gh-attestation related to the gh attestation command

Comments

@thepwagner
Copy link

thepwagner commented May 4, 2024

Describe the bug

The attestation verify feature matches the certificate SAN against the repository name. When the workflow uses a workflow_call/reusable worfklow, the SAN is the workflow name, which is not necessarily the same as the repository name.

This causes verifying artifacts produced by the target repository to fail.

Steps to reproduce the behavior

Example artifacts: https://github.com/thepwagner/ghcr-reaper/releases/tag/v0.0.1 from this workflow https://github.com/thepwagner/ghcr-reaper/blob/v0.0.1/.github/workflows/release.yaml

Expected vs actual behavior / Logs

I expect the provided examples to work:

$ gh attestation verify ghcr-reaper_0.0.1_linux_amd64.deb --repo thepwagner/ghcr-reaper
Loaded digest sha256:f1250d410cb32b3a5203885791c571fde4d239e1b2cc7f44f0ff552502a02aaa for file://ghcr-reaper_0.0.1_linux_amd64.deb
Loaded 1 attestation from GitHub API
✗ Verification failed

Error: verifying with issuer "sigstore.dev": failed to verify certificate identity: no matching certificate identity found

I can workaround by passing the workflow reference as an additional argument, but that's not expected:

$ gh attestation verify ghcr-reaper_0.0.1_linux_amd64.deb --repo thepwagner/ghcr-reaper --cert-identity 'https://github.com/thepwagner-org/actions/.github/workflows/golang-release-attest.yaml@refs/heads/github-attestations'
Loaded digest sha256:f1250d410cb32b3a5203885791c571fde4d239e1b2cc7f44f0ff552502a02aaa for file://ghcr-reaper_0.0.1_linux_amd64.deb
Loaded 1 attestation from GitHub API
✓ Verification succeeded!

sha256:f1250d410cb32b3a5203885791c571fde4d239e1b2cc7f44f0ff552502a02aaa was attested by:
REPO                    PREDICATE_TYPE                  WORKFLOW
thepwagner-org/actions  https://slsa.dev/provenance/v1  .github/workflows/golang-release-attest.yaml@refs/heads/github-attestations

Related

@thepwagner thepwagner added the bug Something isn't working label May 4, 2024
@cliAutomation cliAutomation added the needs-triage needs to be reviewed label May 4, 2024
@williammartin williammartin added the gh-attestation related to the gh attestation command label May 4, 2024
@kommendorkapten
Copy link

kommendorkapten commented May 6, 2024

Thanks for filing this issue ❤

Actually I think it works as expected, but there are a some improvements we can do here from our side, both on the documentation and the error messages.

The reason it fails now is because the artifact comes from one repo, but it's signed with a (reusable) workflow from another repo (which is also in another org, but it doesn't really matter). This is because the reusable workflow is where the build provenance attestation is created.

So even if we can assure that the artifact comes from the repo you specified, the identity of the signer is not known/trusted. That is why the extra parameter is needed. The regex version can also be used here:

gh attestation verify ghcr-reaper_0.0.1_linux_amd64.deb \
    --repo thepwagner/ghcr-reaper \
    --cert-identity-regex 'https://github.com/thepwagner-org/actions/.github/workflows/golang-release-attest.yaml.*'

If the repo the artifact originates from and the signer is identical, we trust the signer and so no extra parameter is needed.

@thepwagner
Copy link
Author

This is because the reusable workflow is where the build provenance attestation is created.

Understood, a different error message will help.

FWIW, that model surprised me. My assumption was the --repo flag would verify the artifact was produced by a workflow execution in the given repository. I did not think it would care if that workflow used a definition entirely within the repository or delegated via reusable workflow.

Specifically I expected gh would be looking at the 1.3.6.1.4.1.57264.1.18 extension (in my case https://github.com/thepwagner/ghcr-reaper/.github/workflows/release.yaml@refs/tags/v0.0.1), not the SAN.
I expected 1.3.6.1.4.1.57264.1.9 to be the kind of thing I'd need a rego policy to match against: an extra guarantee (and a worthwhile one!), but not something that I need a workaround to use.

(Bias: everything I've written prefers verifying the extensions to the SAN, if there's a good reason to prefer the SAN I'd like to learn!)

@kommendorkapten
Copy link

Yes, there are some options to chose from (different extensions). One of the reason to not trust the value in the extension in your example is that the identity of the issuer (SAN) is not known. So even if the extension's value matches your, how can you trust it when the signer is unknown?

The reusable workflow may perform arbitrary actions prior or during the build.

So the answer is sort of yes to both. The extension's values are where the data should be sourced from, but only if we trust the signer. Makes sense?

@phillmv
Copy link
Contributor

phillmv commented May 6, 2024

oh, hey @thepwagner! This turned out to be a good test case. Thanks for kicking the tires.

@andyfeller andyfeller removed the needs-triage needs to be reviewed label May 7, 2024
@malancas
Copy link
Contributor

v2.49.1 includes documentation when invoking gh attestation verify --help that includes examples of how to use the cert-identity and cert-identity-regex flags to specify the entity responsible for creating the attestation, which fits the reusable workflow use case here.

@malancas
Copy link
Contributor

malancas commented May 16, 2024

Closing this as documentation for this use case has been added in v2.49.1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working gh-attestation related to the gh attestation command
Projects
None yet
Development

No branches or pull requests

7 participants