Skip to content

Configure permissions of GITHUB_TOKEN in workflows #566

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 26, 2023
Merged

Configure permissions of GITHUB_TOKEN in workflows #566

merged 1 commit into from
Jun 26, 2023

Conversation

per1234
Copy link
Contributor

@per1234 per1234 commented Jun 26, 2023

GITHUB_TOKEN is an access token that is automatically generated and made accessible for use in GitHub Actions workflow runs. The global default permissions of this token for workflow runs in a trusted context (i.e., not triggered by a pull_request event from a fork) are set in the GitHub enterprise/organization/repository's administrative settings, giving it either read-only or write permissions in all scopes.

In the case of a read-only default configuration, any workflow operations that require write permissions would fail with an error like:

403: Resource not accessible by integration

In the case of a write default configuration, workflows have unnecessary permissions, which violates the security principle of least privilege.

For this reason, GitHub Actions now allows fine grained control at a per-workflow or per-workflow job scope of the permissions provided to the token. This is done using the permissions workflow key, which is used here to configure the workflows for only the permissions required by each individual job:

https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs

Configuration Granularity

I chose to always configure permissions at the job level even though in some cases the same permissions configuration could be used for all jobs in a workflow. Even if functionally equivalent, I think it is semantically more appropriate to always set the permissions at the job scope since the intention is to make the most granular possible permissions configuration. Hopefully this approach will increase the likelihood that appropriate permissions configurations will be made in any additional jobs that are added to the workflows in the future.

Security Implications

The automatic permissions downgrade from write to read for workflow runs in an untrusted context (e.g., triggered by a pull_request event from a fork) is unaffected by this change.

API Request Implications

Even when all permissions are withheld (permissions: {}), the token still provides the authenticated API request rate limiting allowance (authenticating API requests to avoid rate limiting is a one of the uses of the token in these workflows).

Excess Permissions

Read permissions are required in the contents scope in order to checkout private repositories. Even though those permissions are not required when the workflows are installed in this public repository, the templates are intended to be applicable in public and private repositories both and so a small excess in permissions was chosen in order to use the upstream templates unmodified.

Testing

I did demonstration runs in my fork of the workflows that are not triggered by this PR:

I already made the same configuration change to the "Sync Labels" workflow in the arduino/ArduinoCore-renesas repo (arduino/ArduinoCore-renesas#4) so you can see the run of the updated workflow in that repo:

https://github.com/arduino/ArduinoCore-renesas/actions/runs/5368699575

Failure of "Check Markdown" workflow run

This is unrelated to the changes proposed here. The same failure is occurring even in the runs from the main branch:

https://github.com/arduino/arduino-lint/actions/workflows/check-markdown-task.yml?query=branch%3Amain

`GITHUB_TOKEN` is an access token that is automatically generated and made accessible for use in GitHub Actions workflow
runs. The global default permissions of this token for workflow runs in a trusted context (i.e., not triggered by a
`pull_request` event from a fork) are set in the GiHub enterprise/organization/repository's administrative settings,
giving it either read-only or write permissions in all scopes.

In the case of a read-only default configuration, any workflow operations that require write permissions would fail with
an error like:

> 403: Resource not accessible by integration

In the case of a write default configuration, workflows have unnecessary permissions, which violates the security
principle of least privilege.

For this reason, GitHub Actions now allows fine grained control at a per-workflow or per-workflow job scope of the
permissions provided to the token. This is done using the `permissions` workflow key, which is used here to configure
the workflows for only the permissions require by each individual job.

I chose to always configure permissions at the job level even though in some cases the same permissions configuration
could be used for all jobs in a workflow. Even if functionally equivalent, I think it is semantically more appropriate
to always set the permissions at the job scope since the intention is to make the most granular possible permissions
configuration. Hopefully this approach will increase the likelihood that appropriate permissions configurations will be
made in any additional jobs that are added to the workflows in the future.

The automatic permissions downgrade from write to read for workflow runs in an untrusted context (e.g., triggered by a
`pull_request` event from a fork) is unaffected by this change.

Even when all permissions are withheld (`permissions: {}`), the token still provides the authenticated API request rate
limiting allowance (authenticating API requests to avoid rate limiting is a one of the uses of the token in these
workflows).

Read permissions are required in the "contents" scope in order to checkout private repositories. Even though those
permissions are not required when the workflows are installed in this public repository, the templates are intended to
be applicable in public and private repositories both and so a small excess in permissions was chosen in order to use
the upstream templates unmodified.
@per1234 per1234 added type: enhancement Proposed improvement topic: infrastructure Related to project infrastructure labels Jun 26, 2023
@per1234 per1234 self-assigned this Jun 26, 2023
@codecov-commenter
Copy link

codecov-commenter commented Jun 26, 2023

Codecov Report

Patch and project coverage have no change.

Comparison is base (414314c) 90.05% compared to head (95b5035) 90.05%.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #566   +/-   ##
=======================================
  Coverage   90.05%   90.05%           
=======================================
  Files          44       44           
  Lines        6800     6800           
=======================================
  Hits         6124     6124           
  Misses        553      553           
  Partials      123      123           
Flag Coverage Δ
unit 90.05% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@per1234 per1234 merged commit 3fc8dee into arduino:main Jun 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: infrastructure Related to project infrastructure type: enhancement Proposed improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants