starter-workflows
starter-workflows copied to clipboard
Feature: add pinning variable
For security reasons, it's common practice to pin third-party action dependencies by hash in workflows. It's recommended in OSSF scorecard, for example. It helps avoid situation where a dependencies is compromised: if the dependency is pinned by version or latest
or not pinned at all, a new version would be automatically picked up by the next workflow runs, leading to code execution.
Some starter workflows already follow this practice, e.g., https://github.com/actions/starter-workflows/blob/main/code-scanning/crunch42.yml#L43. There are many others that do so in this repo, which is great!
However, it may become cumbersome to maintain: a user who has previously submitted a starter-workflow will need to update the hashes once in a while. Usually, users do this by enabling tools like dependabot/renovabot on their own repo. To make the changes on the starter-workflow repo (here!), users now need to replicate the changes by submitting a PR to the starter-workflow repo. This is more work for both the repo owner and for the starter-workflow maintainers (PR reviews) each time dependabot/renovabot submits a PR on the original repo.
I wonder if it'd be useful to introduce a new variable like $hash
or $pin
, which could be used as follow in starter workflows:
uses: some/action@$hash("3.*.*") // Substitute the variable with the commit hash of the latest version "3.X.Y"
uses: some/action@$hash("3.2.*") // Substitute the variable with the commit hash of the latest version "3.2.X"
uses: some/action@$pin("hash", "3.2.*") // Substitute the variable with the the latest version "3.2.X"
uses: some/action@$pin("version", "3.2.*") // Substitute the variable with the latest version "3.2.X"
Alternatives considered: Configure dependabot on this repo. I don't this this would work because
- Dependabot only looks for workflows under
.github/workflows
, I suppose? - Only the owners of the starter workflow can tell whether an update may break their action. So it seems wiser to let them configure which dependency version should work in the workflow.
cc @josepalafox
I think I missed an important requirement in my initial feature description: third-party actions are not allowed in the workflow, it seems.
So we may simplify the feature by simply exposing a $last-release-hash
for the starter action:
uses: user/action@$last-release-hash
$last-release-hash
would be substituted with the latest released version's hash. This way, when developers publish a new action (using Publish this Action to Marketplace
), users who then enable this action via the market place would have the action pinned to the latest version's pin automatically.
follow-up: some users may still want to pin by hash the GitHub actions that are used in the workflow. So my original description is still relevant.
This issue has become stale and will be closed automatically within a period of time. Sorry about that.
Please don't close this issue, @github-actions bot!
Hey @laurentsimon, can you point us to an example of such pinned variables? Thanks
sure, here are some examples: https://github.com/actions/starter-workflows/blob/main/code-scanning/apisec-scan.yml#L56 https://github.com/actions/starter-workflows/blob/main/code-scanning/scorecards.yml#L30
In accordance with https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-third-party-actions, Pin actions to a full length commit SHA
.
Note that it would be even better if GitHub supported [email protected]:the_hash
so it'd be more obvious which version the hash corresponds to (containers support something similar).
Today most users use a comment:
action@the_hash # v1.2.3
But dependabot does not update the comment when bumping hashes :/
https://github.com/actions/starter-workflows/blob/main/code-scanning/apisec-scan.yml#L56
This is following the current convention by GitHub, right? Where can i find the actions written with hash pinned variable? Or is it a completely new concept for any provider?
Right. My feature request is the following: every time an action workflow releases a new version, they need to send a PR to this repo to upload the hash pin. This is time consuming both for us (releasers) and you (you need to review pull requests).
What I'm proposing is the ability to define a variable in the starter-workflow to say "Please take the hash pin of the latest version of my action when the user uses the starter workflow template".
Today you have support for variables like $default-branch
which is automatically set to the default branch of the user, but I'd like variables like $hash
or $pin(...)
to declare which hash should be automatically populated.
Does it help?
Yeah. That does help.
@laurentsimon while I completely agree to your assessment of the recurring effort needed to update the hash, any auto update of an action version can be a security hole for end user.
Actions today recommends pinning to a hash so that a workflow uses a well known and tested third party action. Commit SHA is immutable but a release version is not immutable. Imagine a scenarios where a hacker gets access to a third party action (which does not follow all appropriate security supply chain procedures) and publishes a patch update with malicious code. A hash
or pin
functionality would automatically start using that new patch version's sha.
PS: the same rule does not apply for any first party action as we do expect these actions to follow good security practices.
What you describe only happens at first installation, so it's low risk. This is the way everything works today: package managers do this: on first installation you must trust the hash you get for your dependencies (go install
, npm install
, etc), ie Trust-On-First-Use. After that the hash will not change if it's pinned by hash (lock file)- which this proposal does not change. I'm only suggesting the first workflow installation takes the latest hash (as described by the authors) and hardcode it in the workflow, not that the workflow use a version to pin the action.
What you describe only happens at first installation, so it's low risk. This is the way everything works today: package managers do this: on first installation you must trust the hash you get for your dependencies (
go install
,npm install
, etc), ie Trust-On-First-Use.
Trust on first use is based on the testing done by package managers. They would do due diligence before consuming any third party action. But in case of starter workflows, I am not sure they would be expected to do due diligence, especially given that these workflows are "suggested" by GitHub. Mind that the moment they commit and push these workflows, they will get triggered and these third party actions will have access.
@azooinmyluggage any thoughts here?
what do you mean by "testing done by package managers"?
"these third party actions will have access" I'm only suggesting a "pin variable" for the "main" action defined in the starter-workflow. For the scorecard starter-workflow, for example, it would be "ossf/scorecard-action".
My understanding is that the starter-workflow maintainers trust the authors of the actions to give them the hash pin for their action (I did this for the scorecard project myself many times). What's the difference with trusting them to say "take the hash for my latest version at first install" instead?
Today:
- Do you verify who sends the PR to update a starter-workflow?
- Do you check they are maintainers for the project's action?
- Do you verify the hash is from the main branch?
If you do that, great; but this can be automated. What else do you do?
Something else I want to point out is that users have dependbot installed. This means that existing users who have the action pinned by hash will receive updates anyway. The number of existing users is far greater than the number of users installing new starter-workflow on their repo. So if there's a risk of installing a malicious action, the existing user base matters more. If dependabot in unable to tell that a new version of an action is malicious, then all these users will be compromised. It does not matter what the original pin was.
There's a danger of making it harder for action maintainers to update their pin hash, and it may encourage them to use versions instead.
Just to be clear; I appreciate your questions and I think it's pretty useful to ask and discuss them. I'm only trying to see if we're decreasing usability for very little security gains.
This issue has become stale and will be closed automatically within a period of time. Sorry about that.
This issue has become stale and will be closed automatically within a period of time. Sorry about that.
I would like to re-open this issue.