Find information about security best practices when you are writing workflows and using GitHub Actions security features.
Writing workflows
Use secrets for sensitive information
Because there are multiple ways a secret value can be transformed, automatic redaction is not guaranteed. Adhere to the following best practices to limit risks associated with secrets.
- Principle of least privilege
- Any user with write access to your repository has read access to all secrets configured in your repository. Therefore, you should ensure that the credentials being used within workflows have the least privileges required.
- Actions can use the
GITHUB_TOKEN
by accessing it from thegithub.token
context. For more information, see Contexts reference. You should therefore make sure that theGITHUB_TOKEN
is granted the minimum required permissions. It's good security practice to set the default permission for theGITHUB_TOKEN
to read access only for repository contents. The permissions can then be increased, as required, for individual jobs within the workflow file. For more information, see Use GITHUB_TOKEN in workflows.
- Mask sensitive data
- Sensitive data should never be stored as plaintext in workflow files. Mask all sensitive information that is not a GitHub secret by using
::add-mask::VALUE
. This causes the value to be treated as a secret and redacted from logs. For more information about masking data, see GitHub Actions のワークフロー コマンド.
- Sensitive data should never be stored as plaintext in workflow files. Mask all sensitive information that is not a GitHub secret by using
- Delete and rotate exposed secrets
- Redacting of secrets is performed by your workflow runners. This means a secret will only be redacted if it was used within a job and is accessible by the runner. If an unredacted secret is sent to a workflow run log, you should delete the log and rotate the secret. For information on deleting logs, see ワークフロー実行ログの使用.
- Never use structured data as a secret
- Structured data can cause secret redaction within logs to fail, because redaction largely relies on finding an exact match for the specific secret value. For example, do not use a blob of JSON, XML, or YAML (or similar) to encapsulate a secret value, as this significantly reduces the probability the secrets will be properly redacted. Instead, create individual secrets for each sensitive value.
- Register all secrets used within workflows
- If a secret is used to generate another sensitive value within a workflow, that generated value should be formally registered as a secret, so that it will be redacted if it ever appears in the logs. For example, if using a private key to generate a signed JWT to access a web API, be sure to register that JWT as a secret or else it won’t be redacted if it ever enters the log output.
- Registering secrets applies to any sort of transformation/encoding as well. If your secret is transformed in some way (such as Base64 or URL-encoded), be sure to register the new value as a secret too.
- Audit how secrets are handled
- Audit how secrets are used, to help ensure they’re being handled as expected. You can do this by reviewing the source code of the repository executing the workflow, and checking any actions used in the workflow. For example, check that they’re not sent to unintended hosts, or explicitly being printed to log output.
- View the run logs for your workflow after testing valid/invalid inputs, and check that secrets are properly redacted, or not shown. It's not always obvious how a command or tool you’re invoking will send errors to
STDOUT
andSTDERR
, and secrets might subsequently end up in error logs. As a result, it is good practice to manually review the workflow logs after testing valid and invalid inputs. For information on how to clean up workflow logs that may unintentionally contain sensitive data, see ワークフロー実行ログの使用.
- Audit and rotate registered secrets
- Periodically review the registered secrets to confirm they are still required. Remove those that are no longer needed.
- Rotate secrets periodically to reduce the window of time during which a compromised secret is valid.
- Consider requiring review for access to secrets
- You can use required reviewers to protect environment secrets. A workflow job cannot access environment secrets until approval is granted by a reviewer. For more information about storing secrets in environments or requiring reviews for environments, see Using secrets in GitHub Actions and デプロイに環境の使用.
Good practices for mitigating script injection attacks
Recommended approaches for mitigating the risk of script injection in your workflows:
Use an action instead of an inline script
The recommended approach is to create a JavaScript action that processes the context value as an argument. This approach is not vulnerable to the injection attack, since the context value is not used to generate a shell script, but is instead passed to the action as an argument:
uses: fakeaction/checktitle@v3
with:
title: ${{ github.event.pull_request.title }}
Use an intermediate environment variable
For inline scripts, the preferred approach to handling untrusted input is to set the value of the expression to an intermediate environment variable. The following example uses Bash to process the github.event.pull_request.title
value as an environment variable:
- name: Check PR title
env:
TITLE: ${{ github.event.pull_request.title }}
run: |
if [[ "$TITLE" =~ ^octocat ]]; then
echo "PR title starts with 'octocat'"
exit 0
else
echo "PR title did not start with 'octocat'"
exit 1
fi
In this example, the attempted script injection is unsuccessful, which is reflected by the following lines in the log:
env:
TITLE: a"; ls $GITHUB_WORKSPACE"
PR title did not start with 'octocat'
With this approach, the value of the ${{ github.event.pull_request.title }}
expression is stored in memory and used as a variable, and doesn't interact with the script generation process. In addition, consider using double quote shell variables to avoid word splitting, but this is one of many general recommendations for writing shell scripts, and is not specific to GitHub Actions.
Restricting permissions for tokens
To help mitigate the risk of an exposed token, consider restricting the assigned permissions. For more information, see Use GITHUB_TOKEN in workflows.
Using third-party actions
The individual jobs in a workflow can interact with (and compromise) other jobs. For example, a job querying the environment variables used by a later job, writing files to a shared directory that a later job processes, or even more directly by interacting with the Docker socket and inspecting other running containers and executing commands in them.
This means that a compromise of a single action within a workflow can be very significant, as that compromised action would have access to all secrets configured on your repository, and may be able to use the GITHUB_TOKEN
to write to the repository. Consequently, there is significant risk in sourcing actions from third-party repositories on GitHub. For information on some of the steps an attacker could take, see Secure use reference.
You can help mitigate this risk by following these good practices:
-
Pin actions to a full length commit SHA
Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. SHA を選択するときは、アクションのリポジトリからであり、リポジトリ フォークではないことを確認してください。
-
Audit the source code of the action
Ensure that the action is handling the content of your repository and secrets as expected. For example, check that secrets are not sent to unintended hosts, or are not inadvertently logged.
-
Pin actions to a tag only if you trust the creator
Although pinning to a commit SHA is the most secure option, specifying a tag is more convenient and is widely used. If you’d like to specify a tag, then be sure that you trust the action's creators. The ‘Verified creator’ badge on GitHub Marketplace is a useful signal, as it indicates that the action was written by a team whose identity has been verified by GitHub. Note that there is risk to this approach even if you trust the author, because a tag can be moved or deleted if a bad actor gains access to the repository storing the action.
Reusing third-party workflows
The same principles described above for using third-party actions also apply to using third-party workflows. You can help mitigate the risks associated with reusing workflows by following the same good practices outlined above. For more information, see Reuse workflows.
GitHub's security features
GitHub provides many features to make your code more secure. You can use GitHub's built-in features to understand the actions your workflows depend on, ensure you are notified about vulnerabilities in the actions you consume, or automate the process of keeping the actions in your workflows up to date. If you publish and maintain actions, you can use GitHub to communicate with your community about vulnerabilities and how to fix them. For more information about security features that GitHub offers, see GitHub セキュリティ機能.
Using CODEOWNERS
to monitor changes
You can use the CODEOWNERS
feature to control how changes are made to your workflow files. For example, if all your workflow files are stored .github/workflows
, you can add this directory to the code owners list, so that any proposed changes to these files will first require approval from a designated reviewer.
For more information, see コードオーナーについて.
Managing permissions for GitHub Actions settings in your organization
You can practice the principle of least privilege for your organization's CI/CD pipeline with GitHub Actions by administering custom organization roles. A custom organization role is a way to grant an individual or team in your organization the ability to control certain subsets of settings without granting full administrative control of the organization and its repositories.
GitHub Actions の場合、Organization 内の個人またはチームに対して以下のいずれかのアクセス許可を有効にすることができます。
- Organization のアクション ポリシーを管理: セルフホステッド ランナーの設定を除き、[アクション全般] 設定ページのすべての設定を管理するためのアクセス。
- Organization ランナーとランナー グループを管理: GitHub でホストされるランナー、セルフホステッド ランナー、ランナー グループを作成および管理し、セルフホステッド ランナーを作成できる場所を制御するためのアクセス。
- Organization のアクション シークレットを管理: アクションの Organization シークレットを作成および管理するためのアクセス。
- Organization のアクション変数を管理: アクションの Organization 変数を作成および管理するためのアクセス。
For more information, see カスタム組織の役割の情報.
Using OpenID Connect to access cloud resources
GitHub Actions ワークフローが OpenID Connect (OIDC) をサポートするクラウド プロバイダーのリソースにアクセスする必要がある場合、そのクラウド プロバイダーで直接認証されるようにワークフローを構成できます。 これにより、有効期間の長いシークレットとしてこれらの資格情報の格納を停止し、その他のセキュリティ上の利点を提供できます。 詳しくは、「OpenID Connect」をご覧ください。
メモ
OIDC のカスタム要求のサポートは、AWS では使用できません。
Using Dependabot version updates to keep actions up to date
リポジトリで使用されるアクションおよび再利用可能なワークフローのリファレンスを常に最新の状態に保つため、Dependabotを使用できます。 多くの場合、アクションはバグ修正および新しい機能で更新され、自動化プロセスの速度、安全性、信頼性が向上しています。 Dependabotは、依存関係の保守を自動的に実行するため、作業量が軽減されます。 詳細については、「Dependabot でアクションを最新に保つ」および「Dependabot のセキュリティ アップデート」を参照してください。
Allowing workflows to access internal and private repositories
プライベート リポジトリを他のリポジトリの GitHub Actions ワークフローからアクセスできるようにする場合、プライベート リポジトリに直接アクセスできない他のリポジトリの外部コラボレーターは、プライベート リポジトリに間接的にアクセスできます。 外部コラボレーターは、プライベート リポジトリのアクションまたはワークフローが使用されている場合に、ワークフローの実行をログで確認できます。 For more information, see アクションとワークフローを企業と共有する.
ランナーがこれらのアクションをダウンロードできるように、GitHub はスコープ付きのインストール トークンをランナーに渡します。 このトークンはリポジトリへの読み取りアクセス権を持ち、1 時間後に自動的に期限切れになります。
Preventing GitHub Actions from creating or approving pull requests
GitHub Actions ワークフローでの pull request の作成または承認を許可するか禁止するかを選択できます。 Allowing workflows, or any other automation, to create or approve pull requests could be a security risk if the pull request is merged without proper oversight.
For more information on how to configure this setting, see エンタープライズで GitHub Actions のポリシーを適用する, Disabling or limiting GitHub Actions for your organization, and リポジトリの GitHub Actions の設定を管理する.
Using OpenSSF Scorecards to secure workflow dependencies
Scorecards is an automated security tool that flags risky supply chain practices. You can use the Scorecards action and workflow template to follow best security practices. Once configured, the Scorecards action runs automatically on repository changes, and alerts developers about risky supply chain practices using the built-in code scanning experience. The Scorecards project runs a number of checks, including script injection attacks, token permissions, and pinned actions.
Hardening for GitHub-hosted runners
メモ
GitHub ホステッド ランナーは、現在 GitHub Enterprise Server ではサポートされていません。 GitHub public roadmap で、今後の計画的なサポートの詳細を確認できます。
Hardening for self-hosted runners
Self-hosted runners for GitHub do not have guarantees around running in ephemeral clean virtual machines, and can be persistently compromised by untrusted code in a workflow.
Be cautious when using self-hosted runners on private or internal repositories, as anyone who can fork the repository and open a pull request (generally those with read access to the repository) are able to compromise the self-hosted runner environment, including gaining access to secrets and the GITHUB_TOKEN
which, depending on its settings, can grant write access to the repository. Although workflows can control access to environment secrets by using environments and required reviews, these workflows are not run in an isolated environment and are still susceptible to the same risks when run on a self-hosted runner.
Enterprise の所有者と Organization の所有者は、リポジトリ レベルのセルフホステッド ランナーの作成を許可するリポジトリを選択できます。 "Manage organization runners and runner groups" アクセス許可を持つユーザーは、organization 内のリポジトリのリポジトリ レベルの自己ホスト ランナーの作成を許可するリポジトリのみを選択できます。
カスタム organization の役割の詳細については、「カスタム組織の役割の情報」を参照してください。
詳細については、「エンタープライズで GitHub Actions のポリシーを適用する」と「Organization について GitHub Actions を無効化または制限する」を参照してください。
When a self-hosted runner is defined at the organization or enterprise level, GitHub can schedule workflows from multiple repositories onto the same runner. Consequently, a security compromise of these environments can result in a wide impact. To help reduce the scope of a compromise, you can create boundaries by organizing your self-hosted runners into separate groups. You can restrict what workflows, organizations and repositories can access runner groups. For more information, see グループを使用してセルフホストランナーへのアクセスを管理する.
You should also consider the environment of the self-hosted runner machines:
- What sensitive information resides on the machine configured as a self-hosted runner? For example, private SSH keys, API access tokens, among others.
- Does the machine have network access to sensitive services? For example, Azure or AWS metadata services. The amount of sensitive information in this environment should be kept to a minimum, and you should always be mindful that any user capable of invoking workflows has access to this environment.
Some customers might attempt to partially mitigate these risks by implementing systems that automatically destroy the self-hosted runner after each job execution. However, this approach might not be as effective as intended, as there is no way to guarantee that a self-hosted runner only runs one job. Some jobs will use secrets as command-line arguments which can be seen by another job running on the same runner, such as ps x -w
. This can lead to secret leaks.
Using just-in-time runners
To improve runner registration security, you can use the REST API to create ephemeral, just-in-time (JIT) runners. These self-hosted runners perform at most one job before being automatically removed from the repository, organization, or enterprise. For more information about configuring JIT runners, see セルフホステッド ランナーの REST API エンドポイント.
メモ
Re-using hardware to host JIT runners can risk exposing information from the environment. Use automation to ensure the JIT runner uses a clean environment. For more information, see Self-hosted runners reference.
Once you have the config file from the REST API response, you can pass it to the runner at startup.
./run.sh --jitconfig ${encoded_jit_config}
Planning your management strategy for self-hosted runners
A self-hosted runner can be added to various levels in your GitHub hierarchy: the enterprise, organization, or repository level. This placement determines who will be able to manage the runner:
Centralized management:
- If you plan to have a centralized team own the self-hosted runners, then the recommendation is to add your runners at the highest mutual organization or enterprise level. This gives your team a single location to view and manage your runners.
- If you only have a single organization, then adding your runners at the organization level is effectively the same approach, but you might encounter difficulties if you add another organization in the future.
Decentralized management:
- If each team will manage their own self-hosted runners, then the recommendation is to add the runners at the highest level of team ownership. For example, if each team owns their own organization, then it will be simplest if the runners are added at the organization level too.
- You could also add runners at the repository level, but this will add management overhead and also increases the numbers of runners you need, since you cannot share runners between repositories.
Authenticating to your cloud provider
If you are using GitHub Actions to deploy to a cloud provider, or intend to use HashiCorp Vault for secret management, then it's recommended that you consider using OpenID Connect to create short-lived, well-scoped access tokens for your workflow runs. For more information, see OpenID Connect.
Auditing GitHub Actions events
You can use the security log to monitor activity for your user account and the audit log to monitor activity in your organization or enterprise. The security and audit log records the type of action, when it was run, and which personal account performed the action.
For example, you can use the audit log to track the org.update_actions_secret
event, which tracks changes to organization secrets.
For the full list of events that you can find in the audit log for each account type, see the following articles:
Understanding dependencies in your workflows
You can use the dependency graph to explore the actions that the workflows in your repository use. The dependency graph is a summary of the manifest and lock files stored in a repository. It also recognizes files in ./github/workflows/
as manifests, which means that any actions or workflows referenced using the syntax jobs[*].steps[*].uses
or jobs.<job_id>.uses
will be parsed as dependencies.
The dependency graph shows the following information about actions used in workflows:
- The account or organization that owns the action.
- The workflow file that references the action.
- The version or SHA the action is pinned to.
In the dependency graph, dependencies are automatically sorted by vulnerability severity. If any of the actions you use have security advisories, they will display at the top of the list. You can navigate to the advisory from the dependency graph and access instructions for resolving the vulnerability.
Enterprise owners can configure the dependency graph and Dependabot alerts for an enterprise. For more information, see 企業の依存関係グラフの有効化.
Being aware of security vulnerabilities in actions you use
For actions available on the marketplace, GitHub reviews related security advisories and then adds those advisories to the GitHub Advisory Database. You can search the database for actions that you use to find information about existing vulnerabilities and instructions for how to fix them. To streamline your search, use the GitHub Actions filter in the GitHub Advisory Database.
You can set up your repositories so that you:
- Receive alerts when actions used in your workflows receive a vulnerability report. For more information, see Monitoring the actions in your workflows.
- Are warned about existing advisories when you add or update an action in a workflow. For more information, see Screening actions for vulnerabilities in new or updated workflows.
Monitoring the actions in your workflows
You can use Dependabot to monitor the actions in your workflows and enable Dependabot alerts to notify you when an action you use has a reported vulnerability. Dependabot performs a scan of the default branch of the repositories where it is enabled to detect insecure dependencies. Dependabot generates Dependabot alerts when a new advisory is added to the GitHub Advisory Database or when an action you use is updated.
メモ
Dependabot only creates alerts for vulnerable actions that use semantic versioning and will not create alerts for actions pinned to SHA values.
An enterprise owner must first set up Dependabot for your enterprise before you can manage Dependabot alerts for your repository. For more information, see エンタープライズ向けの Dependabot の有効化.
リポジトリのDependabot alertsタブの開いた・閉じたすべてのDependabot alertsおよび対応するDependabot security updatesを表示できます。 For more information, see Dependabot アラートの表示と更新.
Screening actions for vulnerabilities in new or updated workflows
When you open pull requests to update your workflows, it is good practice to use dependency review to understand the security impact of changes you've made to the actions you use. 依存関係レビューを使うと、すべてのPull Reqeustにおける以下の変更による依存関係の変化とセキュリティについての影響を理解しやすくなります。pull request の [Files Changed](変更されたファイル) タブ上のリッチ diff で依存関係の変更をわかりやすく視覚化できます。 依存関係レビューは、以下のことを知らせます:
- リリース日と合わせて、追加、削除、更新された依存関係
- これらのコンポーネントを使うプロジェクトの数
- これらの依存関係に関する脆弱性のデータ
If any of the changes you made to your workflows are flagged as vulnerable, you can avoid adding them to your project or update them to a secure version.
For more information about dependency review, see 依存関係の確認について.
"依存関係レビュー アクション" とは、GitHub Actions コンテキスト内の pull request の差異を報告できる特定のアクションです。 以下を参照してください。dependency-review-action
リポジトリで 依存関係レビュー アクション を使って、pull request に依存関係レビューを適用できます。 このアクションは、pull request のパッケージ バージョンの変更によって発生した依存関係の脆弱なバージョンをスキャンし、関連するセキュリティの脆弱性について警告します。 これにより、pull request で何が変更されているかをより正確に把握でき、リポジトリに脆弱性が追加されるのを防ぐことができます。 For more information, see 依存関係の確認について.
Keeping the actions in your workflows secure and up to date
リポジトリで使用されるアクションおよび再利用可能なワークフローのリファレンスを常に最新の状態に保つため、Dependabotを使用できます。 多くの場合、アクションはバグ修正および新しい機能で更新され、自動化プロセスの速度、安全性、信頼性が向上しています。 Dependabotは、依存関係の保守を自動的に実行するため、作業量が軽減されます。 詳細については、「Dependabot でアクションを最新に保つ」および「Dependabot のセキュリティ アップデート」を参照してください。
The following features can automatically update the actions in your workflows.
- Dependabot version updates open pull requests to update actions to the latest version when a new version is released.
- Dependabot security updates open pull requests to update actions with reported vulnerabilities to the minimum patched version.
メモ
- Dependabot は、
actions/checkout@v4
などの GitHub リポジトリ構文を使って、GitHub Actions に対する更新のみをサポートします。 Dependabot は、ローカルで参照されているアクションまたは再利用可能なワークフロー (たとえば、./.github/actions/foo.yml
) を無視します。 - Docker Hub と GitHub Packages Container registry URL は現在、サポートされていません。 たとえば、
docker://
構文を使用した Docker コンテナー アクションへの参照はサポートされていません。 - Dependabot では、GitHub Actions のパブリック リポジトリとプライベート リポジトリの両方がサポートされます。 プライベート レジストリ構成オプションについては、「Dependabot オプション リファレンス」の「
git
」を参照してください。
For information on how to configure Dependabot version updates, see Dependabot のバージョン アップデートの設定.
For information on how to configure Dependabot security updates, see Configuring Dependabot security updates (Dependabot セキュリティ アップデートの構成).