Self-hosted runner security with public repositories

Documentation [1] says:

We recommend that you do not use self-hosted runners with public repositories.

Forks of your public repository can potentially run dangerous code on your self-hosted runner machine by creating a pull request that executes the code in a workflow.

Do I understand correctly that if self-hosted runner is only used in workflow which is triggered by push, it’s completely secure?

[1] https://help.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners#self-hosted-runner-security-with-public-repositories

Yeah, you are right. If your workflows is not triggered by pull request event, then dangerous code on fork repos could not run on your self-hosted runner.

Only collaborators has permission to push to your public repositories directly. If you could make sure your collaborators are safe , then workflows triggered by push event is secure.  

1 Like

Thanks! Then I suggest to change wording in documentation to be less scaring, and maybe add validation in runner which prints big bold warning whenever self-hosted runner is triggered in PR event in public repo.

I’m not sure this is safe. What happens if someaone creates a PR modifying the workflow to run on pull_requests?

Once a repo has been forked you aren’t in control of changes on the fork right? So it seems fine to me as long as the malicious code is not run on the main repo

@vivekteega Yeah, you are right. Please pay attention to pull requests from fork repo to your main repo. A workflow on pull_request event will get premerged code of forked repo to main repo and the codes in forked repo could be run in your self-hosted runner. 

Thank you for this info. I was very spooked as well by the big warning in the docs. I’m considering deploying a self-hosted running and just making a big comment in the workflow to say “DO NOT TRIGGER ON PRs”.

But it seems pretty fragile to me to “just” not run on PRs. That is a very easy thing to change without someone realizing that they’ve just opened themselves up a cybersecurity hole.

The rule I would expect from Github is: a self-hosted runner can only be triggered by code in repos where the self-hosted runner is active. So, basically, a hard-ban on PR/issue/etc triggers.


For a data point of comparison, Azure Pipelines makes you manually click a Permit button the first time a pipeline accesses a new runner. So it …should be? … impossible for it to have the same problem?

3 Likes

We’re investigating using self hosted runners at my work, but we’ve got hundreds of public repos so this issue is quite a blocker for us - something like @kousu suggests where you can prevent forked repos using self hosted runners at an organisation level would be very helpful.

What with a situation, where we have a public repository and would like to run the tests with some physical device, e.x. webcamera?
My original thought was to create a self-hosted runner and attach the device physically to it, but as the docs specified, it’s dangerous to use self-hosted instances on public repositories.
Are there any alternatives?

I am sorry to tell you that there is no alternatives. To test with physical device , you need to use self-hosted runner.
If it is possible for you, I would suggest you to use a private repo.

I think a good feature is if in the future we could trigger a workflow when an authorised user comments on an open PR. At the current moment it is hard to see how to deploy a self hosted runner in my development as ideally I would like to run CI before I push any new code to any of my branches.

Yeah I like the suggestion from @bdevierno1 . I would be great if the action can be triggered only by comment (e.g. /test) that is coming from one of the people that are part of the OWNERS file. Would that be possible?

or

what about blocking merging unless 1 approval from an owner is required? If that’s the case I would be great to have an action that can be triggered based on the “approved” status of a PR.

I think it would also be useful to have different event types for “internal” and “external” pull requests, where “internal” means pull request originates from the same repo with workflow. If workflow is triggered by internal PRs only it would require having write access to repo to run code on self-hosted runner.