slsa-framework / slsa-verifier

Verify provenance from SLSA compliant builders
Apache License 2.0
223 stars 48 forks source link

Feature: only accept reusable workflow pinned by version #12

Open laurentsimon opened 2 years ago

laurentsimon commented 2 years ago

The reusable workflow can be pinned by hash, version or tag in general.

However:

  1. Pinned by hash makes it pretty hard to retrieve the branch during verification.
  2. Pinned by branch (like main) should be discouraged.

The OIDC token (which we use to retrieve the workflow identity/pin) currently does not report the version/branch used. So for now we will only accept version/tag pinning during verification. Once GitHub adds support, we can accept hash pins.

naveensrinivasan commented 2 years ago

Pinned by hash makes it pretty hard to retrieve the branch during verification.

@laurentsimon Can you please explain why so? A specific example would be helpful to understand. Thanks

laurentsimon commented 2 years ago

Well, sort of what I described. The OIDC currently does not contain all the information we'd like and only contains trusted-workflow.yml@XXX where XXX is how the user pinned the trusted builder. If users use a hash, the verifier would need to use GitHub API to match it to a branch and verify it's the main branch. If they use a branch... well.. they should not use the main branch directly because we may be breaking things at head. So the only viable solution today is to ask users to pin by version: we, the maintainers, should be only releasing branches from the main branch, so if they trust us this works.

Later when GitHub adds support in the OIDC token to indicate the branch and hash of the trusted builder, we'll be able to let users pin by hash and we'll be able to verify the hash corresponds to the main branch via the information in the certificate (see https://github.com/slsa-framework/slsa-github-generator-go/blob/main/images/cert.svg) which is a mere copy of the information in the OIDC token.

Does this help?

MarkLodato commented 2 years ago

@laurentsimon The verifier could have a list of acceptable hashes, either hard-coded or via some signed mechanism (TUF? attestation?) This avoids the need for us to trust the protection of tags on our repo.

laurentsimon commented 2 years ago

You're right, we could do that. There are going to be quite a few generators though, and we'll have to be sure to add new hashes after each release. This is do-able, just a little more error prone for us. Some builders may be "out of our control", for example pipy seem interested in owning their builder.

It may become useful to have a builder's version, since new versions may have new features or breaking changes. (We can map each tag to a version, though).

Using version/tag pinning seems simpler to start with (due to the OIDC token limitation). We could later introduce support for hashes. If we introduce hashes right now, it may be harder to take it way from users if it becomes untenable to maintain.

I'm not against doing it, mostly trying to weigh the pros and cons.

Wdut?

/cc @asraa

MarkLodato commented 2 years ago

I think we have the following considerations:

laurentsimon commented 2 years ago

+1, good summary.

laurentsimon commented 2 years ago

Enforcing pinning by version is done in https://github.com/slsa-framework/slsa-verifier/pull/63 Keeping this issue open for now.

joshuagl commented 2 years ago

I just discovered that GitHub now supports tag protection rules:

Only users with admin or maintain permissions in the repository will be able to create protected tags, and only users with admin permissions in the repository will be able to delete protected tags.

It's not clear from the docs what permissions are required to mutate/overwrite a tag, but this may mitigate some of the insider risk of tags?

ianlewis commented 2 years ago

I just discovered that GitHub now supports tag protection rules:

Only users with admin or maintain permissions in the repository will be able to create protected tags, and only users with admin permissions in the repository will be able to delete protected tags.

It's not clear from the docs what permissions are required to mutate/overwrite a tag, but this may mitigate some of the insider risk of tags?

Yeah, we should enable that so that it's not a risk for folks who are simply contributors. I just added a tag rule for all tags ("*").

datosh commented 1 year ago

I just integrated the generator into a project that is also using Renovate with the pinning rule enforced. Manual overwrite for slsa generator package would look like this:

  "packageRules": [
    {
      "matchManagers": ["github-actions"],
      "matchPackageNames": ["slsa-framework/slsa-github-generator"],
      "pinDigests": false
    }
  ]

Would it be helpful to document this somewhere for users of the generator? Any recommendations for a location? Seems a bit too much detail for the README.

laurentsimon commented 1 year ago

Great idea @datosh

How about linking to your renovatebot config in the generator repo in this section https://github.com/slsa-framework/slsa-github-generator#referencing-slsa-builders-and-generators?

We can create a RENOVATEBOT.md to link to in the same repo? Wdut?

datosh commented 1 year ago

Thanks for the quick response @laurentsimon. I put together a quick PR. What do you think?

How about linking to your renovatebot config in the generator repo

Do you mean linking to the repository where I actually use slsa generator to show a live working example? I can add the link, just wasn't sure if that's what you mean.

stevehipwell commented 1 year ago
  • Ease of use on caller's side:
    • Hash: medium, dependabot keeps it up-to-date, but it's less readable

@MarkLodato I think this might have changed to medium-to-easy since Dependabot now supports keeping a version comment up to date as part up updating digests?

MarkLodato commented 1 year ago

@MarkLodato I think this might have changed to medium-to-easy since Dependabot now supports keeping a version comment up to date as part up updating digests?

👍

jul-sh commented 5 months ago

The reusable workflow can be pinned by hash, version or tag in general.

Pinning by hash does not appear to be functional, hence one can only depend on released tags. As mentioned before in this thread that doesn't seem ideal for defense in depth.

It's also an issue for bug fixes though! In our case provenance generation was blocked by a breaking bug (https://github.com/slsa-framework/slsa-github-generator/issues/3571). The fix is merged, but we are unable to use them, since it's not yet included in a release tag.

Supporting pinning by hash would solve that problem (https://github.com/slsa-framework/slsa-github-generator/issues/3573).

laurentsimon commented 5 months ago

@ramonpetgrave64 let's work on a relaese