Make sure some github action only run by the owner - github-actions

I have an action job which upload the context to other website. The token was set and stored in the secret.MY_TOKEN.
But others who make the pull request also trigger this action job using the token I set.
How to limit the privilege of executing the jobs that only I can run this action job.
fyi my ci.yml as follow:
name: foobar
on: [push, pull_request]
jobs:
upload:
runs-on: ubuntu-latest
steps:
....
- name: execute upload
env:
TOKEN: ${{ secrets.MYTOKEN }}
run:
upl --token ${TOKEN}
I assume there are two security problems here.
The token is printed in log file.
others who can use this private token by trigger action with their own purpose.

Use the github.repository_owner context
https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context
The syntax should be something like:
- if: github.repository_owner == 'owner_name'

There is a new feature which could help, since July 2022:
Differentiating triggering actor from executing actor
Starting next week, workflow re-runs in GitHub Actions will use the initial run’s actor for privilege evaluation.
The actor who triggered the re-run will continue to be displayed in the UI, and can be accessed in a workflow via the triggering_actor field in the GitHub context.
Currently, the privileges (e.g. – secrets, permissions) of a run are derived from the triggering actor.
This poses a challenge in situations where the actor triggering a re-run is different than the original executing actor.
The upcoming change will differentiate the initial executing actor from the triggering actor, enabling the stable execution of re-runs.
For more details see Re-running workflows and jobs.

I don't believe allowing actions to run only for certain users is a native feature.
However, you could simply check the action context actor and exit early if the actor is not the yourself (or the owner of the repo, or whatever condition you'd like).

Related

Checking condition when step is running on schedule in GitHub Actions

We have workflow in GitHub Actions which has both types that trigger on event, e.g.pull-request, and on schedule.
Most of the steps are the same except for running test step. What we would like is:
On pull-request without specific label provided: execute smoke test
On pull-request with specific label OR on schedule: execute full test
The check for label can be done with contains(github.event.pull_request.labels.*.name, 'full-tests').
The question is how to check when the it is run on schedule? From my understanding of the documentation, when on schedule there is no payload for github.event for schedule. However checking github.event == null doesn't seems to work.
Is there a specific way to check whether it is running on schedule?
What you want to use in that case is the github.event_name variable, which represents the name of the event that triggered the workflow run in the github context.
In your case, to run a job or a step if the workflow run triggered on a scheduled event, you will need to use:
if: ${{ github.event_name == 'schedule' }}
Reference

Add check to a specific workflow-run/check-suite using octokit

I have a project with Github Actions that implements multiple workflows that can be triggered by a single push event (depending on path filter).
So a push with a single commit can trigger multiple workflows, so far so good.
In each workflow I am running actions/github-script to create dynamic run-checks with the following step:
- uses: actions/github-script#v4
with:
github-token: ${{ inputs.github-token }}
script: |
const date = new Date();
const check = await github.checks.create({
owner: "${{ steps.vars.outputs.owner }}",
repo: "${{ steps.vars.outputs.repo }}",
name: "Custom Script",
started_at: date.toISOString(),
completed_at: date.toISOString(),
head_sha: "${{ inputs.sha }}",
external_id: "${{ github.run_id }}",
status: "completed",
conclusion: "success",
output: {
title: "Some funny title",
summary: "Build successful",
text: "Image pushed to https://${{ inputs.region }}.console.aws.amazon.com/ecr/repositories/private/${{ inputs.customer-id }}/modix/base/${{ inputs.image }}"
}
});
It is working like a charm, when a single workflow is triggered, but as soon as a push triggers multiple workflows, then only the first one that runs is showing the added check. all others but the first don't show the check but also no error?
Before I have tried the LouisBrunner/checks-action and it had the same problem so I created an issue: https://github.com/LouisBrunner/checks-action/issues/26. But now that it also fails by directly using octokit with github-script action, it feels like the problem is somewhere else...
UPDATE:
According to Gregors answer, I have tried giving the check a different name in each workflow by appending the run-id, I found that each parallel workflow is adding the check to the workflow that runs first... so the question now is, how to send it to a specific workflow run?
according to these docs, there is no dedicated parameter for that, it seems that it automatically detects the workflow using the head_sha?
name: "Custom Script ${{ github.run_id }}",
Try setting Custom Script to something different for each check run you create. I think multiple check runs with the same names are collapsed into only showing the last one. The reason is that that way you can override an status on a commit, by using the same name.
Sadly I found that it is simply impossible to attach a check to a specific workflow-run or check-suite. The problem is known for over a year now, but they didn't provide any solution yet. See in this thread.
In the name of a big automotive company, I have now submitted a feature request in the official feedback form of github.
PS: If the feature will be implemented in the future, I am going to create and accept another answer here.

Using a secret, private action

I am giving a coding lesson where students can upload answers to our quizzes using personal, private repositories. So here's how the repository structure of my organization looks like:
my_organization/student_1_project
my_organization/student_2_project
my_organization/...
my_organization/student_n_project
I would like to run a private GitHub Action at any push on a student repository. This Action would run partial reviews of the student's work, and notify me of stuffs. Its code would need to be unreachable from students, of course, otherwise providing hints & solutions.
I have three questions:
Can my workflow in e.g. my_organization/student_2_project be to use a private action my_organization/my_private_action? It seems like yes thanks to actions/checkout#v2 (see here) but pretty sure that involves playing with keys or tokens or secrets - I'm not so at ease with that and currently get an error although it does exist:
Error: fatal: repository 'https://github.com/my_organization/my_private_action' not found
Can it prevent the student (owner/admin of my_organization/student_2_project) to see the code in my_organization/my_private_action?
With the same constraints, could the private action be hosted in another organization?
Thanks a lot for your help!
This is how I understand the restrictions:
Using an action from a private/internal repository currently isn't supported directly, see this issue on the roadmap. A possible workaround is adding a personal access token with access to the private repo that contains the action and then checking it out like this:
- name: Get private repo with action
uses: actions/checkout#v2
with:
repository: yourorg/privateactionrepo
ref: master
token: ${{ secrets.PAT_TOKEN }}
path: .github/actions
You can then use the action in another step like
uses: ./.github/actions/actionname
The PAT can be a secret on the org level so you don't have to add it to every single student repo.
Since the student's repo has access to the PAT, they can use it to create a workflow that checks out the private repo and does whatever they want with it – upload its contents, print every file etc.
As long as the PAT has the permissions to check out the repo containing the action, the action can live anywhere, including in another organization.
Alternatively, if you want to prevent your students from seeing your action, you could add a workflow to your students' repositories that sends a request to the GitHub API and then have a trigger in your action on the repository_dispatch event.

Github action get tiggered from a new issue opened against a repo

Can you please tell me if it is possible to setup Github action which gets triggered
when a new issue opened against a repo?
If not, is there other way which I can automated when a new issue is filed in a repo?
Forllowing the GitHub workflow syntax for on.<event_name>.types, you can trigger an action on a new issue with:
name: "Set Issue Label and Assignee"
on:
issues:
types: [opened]
Example: Naturalclar/issue-action
Webhooks are not needed here:
Subcribing to a webhook event like the one for issues is not enough: you need to setup a listener which will process the JSON payload. (for instance, building a GitHub App with ProBot).
"if not": GitHub Actions are there to avoid using webhooks, if your project is on GitHub.com (webhooks can still be useful for on premise GitHub hosting servers for example)
You will need to subscribe to this webhook.
https://developer.github.com/webhooks/event-payloads/#issues
Webhook payload object
Key Type Description
action string The action that was performed. Can be one of opened, edited, deleted,
pinned, unpinned, closed, reopened, assigned, unassigned, labeled,
unlabeled, locked, unlocked, transferred, milestoned, or demilestoned.

Environment Variables in a JavaScript Github Action

I am writing a javascript github action. Inside my action.yml, I have the following:
runs:
using: node12
main: ./index.js
Inside my index.js, I am calling an api which requires a secret key. I want to use my own secret key. I don't want users who use my action to define their own key. How can I add my secret key to the file as a secret ort env variable ?
Secrets need to come from somewhere. Even if you encrypt your token for the external api and host it directly in the action's code, you still need a passphrase to decrypt it and that needs to come from a secrets entry by the user of your action as it would need to be hosted in their own repo or organization.
Example of encrypting a secret if you wanted to, but still requires a passphrase, therefore we are back on the same boat.
gpg --symmetric --cipher-algo AES256 my_secret.json
The reason this situation is not ideal is because from my understanding, you want to use one token for all users of your action. Therefore the secret will need to be public in some way as multiple users will need to have that token, so either you host the token directly in your action or tell users to provide it to you through their secrets setup as an action variable or env. Here is an example of the user sharing the token in two different ways to your action.
steps:
- name: Hello world action
with: # Set the secret as an input
super_secret: ${{ secrets.SuperSecret }}
env: # Or as an environment variable
super_secret: ${{ secrets.SuperSecret }}