How to make GitHub Actions safely access Secrets for PRs created from forks?
Asked Answered
A

2

10

I have a public repository that runs end-to-end tests. These tests require secrets that are stored in GitHub.

The corresponding workflow yaml file has pull_request entry as follows:

on:
  pull_request:
  ....

Problem: If I (the owner) create a pull request myself, the workflow would run correctly and access the secrets. If someone creates a PR from a fork, GitHub would ask me to approve the run, however once I approve, the workflow would not see the values of those secrets and the tests would fail.

If I change pull_request to pull_request_target, it would access the secrets correctly. However this way, it doesn't ask for my approval before running the workflow (thus the secrets can easily leak).

pull_request_target:
  branches:
    - main

Question: How to make GitHub actions access the secrets when running on PRs from forks while still requiring to approve the run?

Aluminous answered 22/8, 2023 at 9:43 Comment(0)
E
6

By default, all first-time contributors require approval to run workflows if they use the pull_request event. They no longer need approval for the same repository after the first contribution. The workflows will be triggered automatically. According to GitHub's official documentation, workflows for PRs against forked repos using pull_request events do not have access to the base repository secrets.

As a result, you will not be able to access the secrets in the workflow for PR against forked repository. You can obtain the secrets using pull_request_target, but a risk is involved. According to the official GitHub documentation, if you use pull_request_target event, you should not check out, build, or run untrusted code from the pull request. That is exactly what your workflow is doing.

There is a alternative, You can have a separate workflow with event workflow_run that will be triggered after the completion of CI pipeline. workflow_run allows you to execute a workflow based on execution or completion of another workflow. The workflow started by the workflow_run event is able to access secrets and write tokens, even if the previous workflow was not.

Still in both the cases (pull_request_target,workflow_run) there is risk associated. Please proceed with caution!

Hope this helps!

Expansive answered 30/8, 2023 at 18:34 Comment(0)
P
1

Unlike pull_request, pull_request_target run the workflow in the context of the target repository, so you have access to the secrets. You can reduce this vulnerability by adding labeled type, however it doesn't really make this a safe approach

From Keeping your GitHub Actions and workflows secure

As such this approach should only be used as a temporary solution, until a proper fix from the options above is applied. Since external users do not have the permission to assign labels, this effectively requires repository owners to manually review changes first and is also prone to human error.

Note that there is an important “gotcha” to any remediation put in place for a vulnerable workflow. All PRs that were opened before a fix was made to the vulnerable workflow will use the version of the workflow as it existed at the time the PR was opened. That means that if there is a pending PR, any updates to the PR may still abuse the vulnerable workflow. It is advisable to either close or rebase such PRs if untrusted commits may be added to them after a vulnerable workflow is fixed.

You may ask yourself: if the pull_request_target workflow only checks out and builds the PR, i.e. runs untrusted code but doesn’t reference any secrets, is it still vulnerable?

Yes it is, because a workflow triggered on pull_request_target still has the read/write repository token in memory that is potentially available to any running program. If the workflow uses actions/checkout and does not pass the optional parameter persist-credentials as false, it makes it even worse. The default for the parameter is true. It means that in any subsequent steps any running code can simply read the stored repository token from the disk. If you don’t need a repository write access or secrets, just stick to the pull_request trigger.

If you still want to go that way add the pull_request_target trigger with labeled type

on:
  pull_request_target:
    types: [labeled]

Create a label via Pull requests -> Labels -> new label and apply it to the pull request from Labels section in the right side menu when you are ready to merge the PR, this will trigger the workflow.

Prolific answered 30/8, 2023 at 12:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.