注: GitHub ホステッド ランナーは、現在 GitHub Enterprise Server でサポートされていません。 GitHub public roadmap で、今後の計画的なサポートの詳細を確認できます。
OpenID Connect の概要
多くの場合、GitHub Actions ワークフローは、ソフトウェアをデプロイするため、またはクラウドのサービスを使うために、クラウド プロバイダー (AWS、Azure、GCP、HashiCorp Vault など) にアクセスするように設計されています。 ワークフローは、このようなリソースにアクセスできるように、パスワードやトークンなどの資格情報をクラウド プロバイダーに事前に提供します。 通常、このような資格情報は GitHub にシークレットとして格納されており、ワークフローは、実行時に毎回このシークレットをクラウド プロバイダーに提示します。
ただし、ハードコーディングされたシークレットを使うには、クラウド プロバイダーで資格情報を作成し、それをシークレットとして GitHub に複製する必要があります。
OpenID Connect (OIDC) を使って、有効期間が短いアクセス トークンをクラウド プロバイダーに直接要求するようにワークフローを構成するという別の方法を採ることもできます。 クラウド プロバイダー側でも OIDC をサポートする必要がある場合は、アクセス トークンを要求できるワークフローを制御する信頼関係を構成する必要があります。 現在 OIDC をサポートしているプロバイダーとして、アマゾン ウェブ サービス、Azure、Google Cloud Platform、HashiCorp Vault などがあります。
OIDC を使う利点
OIDC トークンを使うようにワークフローを更新することで、次のような優れたセキュリティ プラクティスを採用できます。
- クラウド シークレットなし: 有効期間が長い GitHub シークレットとしてクラウドの資格情報を複製する必要はありません。 代わりに、クラウド プロバイダー上で OIDC 信頼を構成し、OIDC を介して有効期間が短いアクセス トークンをクラウド プロバイダーに要求するようにワークフローを更新することができます。
- 認証と認可の管理: クラウド プロバイダーの認証 (authN) および認可 (authZ) ツールを使ってクラウド リソースへのアクセスを制御することで、ワークフローから資格情報を使用する方法をより細かく制御できます。
- 資格情報のローテーション: OIDC を使う場合、1 つのジョブに対してのみ有効であり、自動的に失効する有効期間が短いアクセス トークンがクラウド プロバイダーから発行されます。
OIDC の概要
次の図は、GitHub の OIDC プロバイダーがワークフローやクラウド プロバイダーとどのように統合されているかを示す概要です。
- クラウド プロバイダー内に、クラウド ロールと、クラウドへのアクセスを必要とする GitHub ワークフローとの間に OIDC 信頼を作成します。
- ジョブを実行するたびに、GitHub の OIDC プロバイダーによって OIDC トークンが自動生成されます。 このトークンには、認証対象の特定のワークフローに関する、セキュリティが強化された検証可能な ID を確立するための複数の要求が含まれています。
- このトークンを GitHub の OIDC プロバイダーに要求し、クラウド プロバイダーに提示するステップまたはアクションをジョブ内に含めることができます。
- クラウド プロバイダーは、トークンで提示した要求の検証を完了した後に、ジョブの期間中にのみ使用できる有効期間の短いクラウド アクセス トークンを提供します。
クラウドを使った OIDC 信頼の構成
GitHub の OIDC プロバイダーを信頼するようにクラウドを構成する場合は、受信する要求をフィルター処理する条件を追加する必要があります。これは、信頼できないリポジトリやワークフローがクラウド リソースに対してアクセス トークンを要求できないようにするためです。
- クラウド プロバイダーは、アクセス トークンを付与する前に、信頼設定で条件を設定するために使われた
subject
と他の要求が、要求の JSON Web トークン (JWT) 内のものと一致するかどうかを確認します。 そのため、クラウド プロバイダーで subject や他の条件を正しく定義するように注意する必要があります。 - OIDC 信頼の構成手順と、(Subject やその他の要求を使って) クラウド ロールの条件を設定する構文は、利用しているクラウド プロバイダーによって異なります。 例については、「サブジェクト要求の例」を参照してください。
OIDC トークンの概要
各ジョブは GitHub の OIDC プロバイダーに OIDC トークンを要求し、その応答として、自動的に生成された JSON Web トークン (JWT) が返されます。これは生成されたワークフロー ジョブごとに一意です。 このジョブを実行すると、OIDC トークンがクラウド プロバイダーに提示されます。 クラウド プロバイダーは、トークンを検証するために、OIDC トークンの subject とその他の要求がクラウド ロールの OIDC 信頼定義に事前に構成されている条件と一致するかどうかを確認します。
次の OIDC トークン例では、octo-org/octo-repo
リポジトリ内の prod
というジョブ環境を参照する subject (sub
) を使っています。
{
"typ": "JWT",
"alg": "RS256",
"x5t": "example-thumbprint",
"kid": "example-key-id"
}
{
"jti": "example-id",
"sub": "repo:octo-org/octo-repo:environment:prod",
"environment": "prod",
"aud": "https://HOSTNAME/octo-org",
"ref": "refs/heads/main",
"sha": "example-sha",
"repository": "octo-org/octo-repo",
"repository_owner": "octo-org",
"actor_id": "12",
"repository_visibility": "private",
"repository_id": "74",
"repository_owner_id": "65",
"run_id": "example-run-id",
"run_number": "10",
"run_attempt": "2",
"actor": "octocat",
"workflow": "example-workflow",
"head_ref": "",
"base_ref": "",
"event_name": "workflow_dispatch",
"ref_type": "branch",
"job_workflow_ref": "octo-org/octo-automation/.github/workflows/oidc.yml@refs/heads/main",
"iss": "https://HOSTNAME/_services/token",
"nbf": 1632492967,
"exp": 1632493867,
"iat": 1632493567
}
GitHub の OIDC プロバイダーがサポートするすべての要求を確認するには、https://HOSTNAME/_services/token/.well-known/openid-configuration
の claims_supported
のエントリを確認します。
このトークンには、標準の対象ユーザー、発行者、サブジェクト要求が含まれています。
要求 | 要求の種類 | 説明 |
---|---|---|
aud | 対象ユーザー | 既定では、これはリポジトリ所有者 (リポジトリを所有する Organization など) の URL です。 カスタマイズできるのは、この要求のみです。 ツールキットのコマンド (core.getIDToken(audience) ) を使ってカスタムの対象ユーザーを設定できます |
iss | 発行者 | OIDC トークンの発行者: https://HOSTNAME/_services/token |
sub | サブジェクト | クラウド プロバイダーによって検証されるサブジェクト要求を定義します。 常に予測可能な方法でアクセス トークンを割り当てるには、この設定が不可欠です。 |
OIDC トークンには追加の標準要求も含まれています。
要求 | 要求の種類 | 説明 |
---|---|---|
alg | アルゴリズム | OIDC プロバイダーによって使用されるアルゴリズム。 |
exp | 有効期限 | JWT の有効期限を特定します。 |
iat | 発行時刻 | JWT が発行された日時。 |
jti | JWT トークン識別子 | OIDC トークンの一意識別子。 |
kid | キー識別子 | OIDC トークンの一意のキー。 |
nbf | 期間の開始時刻 | この時刻より前に JWT を使用することはできません。 |
typ | Type | トークンの種類について説明します。 これは JSON Web トークン (JWT) です。 |
トークンには、GitHub によって提供されるカスタム要求も含まれています。
要求 | 説明 |
---|---|
actor | ワークフロー実行を開始した個人アカウント。 |
actor_id | ワークフロー実行を開始した個人アカウントの ID。 |
base_ref | ワークフロー実行における pull request のターゲット ブランチ。 |
OIDC 要求を使ったクラウド ロールに対する信頼条件の定義
OIDC を使う場合、クラウド プロバイダー内のリソースにアクセスするには、GitHub Actions ワークフローにトークンが必要です。 ワークフローはクラウド プロバイダーにアクセス トークンを要求します。そこで、JWT から提示された詳細が確認されます。 JWT の信頼構成が一致した場合、クラウド プロバイダーは、応答として一時的なトークンをワークフローに発行します。これを使って、クラウド プロバイダー内のリソースにアクセスできるようになります。 特定の組織のリポジトリから送信された要求のみに応答するようにクラウド プロバイダーを構成することができます。また、後述する追加の条件を指定することもできます。
通常、Audience と Subject の要求は、GitHub ワークフローへのアクセスにスコープを設定する目的で、クラウド ロールやリソースに対する条件の設定時に組み合わせて使います。
- Audience: 既定では、この値には組織またはリポジトリ所有者の URL を使います。 これを使って、特定の組織内のワークフローのみがクラウド ロールにアクセスできるように条件を設定できます。
- Subject: 既定では、事前に定義された書式があります。GitHub の Organization、リポジトリ、ブランチ、関連付けられた
job
環境など、ワークフローに関する主要なメタデータの一部を連結したものです。 連結したメタデータからサブジェクト要求を組み立てる方法については、「サブジェクト要求の例」を参照してください。
より詳しい信頼条件が必要な場合は、JWT に含まれる issuer (iss
) と subject (sub
) の要求をカスタマイズできます。 詳しくは、「トークン クレームのカスタマイズ」を参照してください。
また、OIDC トークンでサポートされている要求は他にも多数あり、これらの条件設定にも使用できます。 さらに、クラウド プロバイダーがアクセス トークンへのロール割り当てを許可していて、さらに細かいアクセス許可を指定できる場合があります。
注: クラウド プロバイダーがアクセス トークンを発行する方法を制御するには、少なくとも 1 つの条件を定義し、信頼できないリポジトリがクラウド リソースにアクセス トークンを要求できないようにする必要があります。
subject 要求の例
次の例は、"Subject" を条件として使う方法を示しています。また、連結したメタデータから "Subject" を組み立てる方法について説明します。 subject は job
コンテキストの情報を使い、特定のブランチ、環境内で動作するワークフローからの要求に対してのみアクセス トークン要求を許可するようにクラウド プロバイダーに指示します。 以下のセクションでは、使用できる一般的な subject について説明します。
特定の環境にフィルター処理する
ジョブから環境を参照するときに、subject 要求には環境名が含まれます。
特定の環境名にフィルター処理する subject を構成することができます。 この例で、ワークフロー実行は、octo-org
組織が所有する octo-repo
というリポジトリ内にある Production
という環境を持つジョブから開始されている必要があります。
- 構文:
repo:<orgName/repoName>:environment:<environmentName>
- 例:
repo:octo-org/octo-repo:environment:Production
pull_request
イベントにフィルター処理する
pull request イベントによってワークフローがトリガーされたとき、ジョブが環境を参照していない場合に限り、subject 要求には pull_request
文字列が含まれます。
pull_request
イベントにフィルター処理する subject を構成することができます。 この例で、ワークフロー実行は、octo-org
組織が所有する octo-repo
というリポジトリ内の pull_request
イベントによってトリガーされている必要があります。
- 構文:
repo:<orgName/repoName>:pull_request
- 例:
repo:octo-org/octo-repo:pull_request
特定のブランチにフィルター処理する
ジョブから環境を参照していない場合、かつ pull request イベントによってトリガーされたワークフローではない場合にのみ、subject 要求にはワークフローのブランチ名が含まれます。
特定のブランチ名にフィルター処理する subject を構成することができます。 この例で、ワークフロー実行は、octo-org
組織が所有する octo-repo
というリポジトリ内にある demo-branch
というブランチから開始されている必要があります。
- 構文:
repo:<orgName/repoName>:ref:refs/heads/branchName
- 例: repo:octo-org/octo-repo:ref:refs/heads/demo-branch`
特定のタグにフィルター処理する
ジョブから環境を参照していない場合、かつ pull request イベントによってトリガーされたワークフローではない場合にのみ、subject 要求にはワークフローのタグ名が含まれます。
特定のタグにフィルター処理する subject を作成できます。 この例で、ワークフロー実行は、octo-org
組織が所有する octo-repo
というリポジトリ内の demo-tag
というタグで開始されている必要があります。
- 構文:
repo:<orgName/repoName>:ref:refs/tags/<tagName>
- 例:
repo:octo-org/octo-repo:ref:refs/tags/demo-tag
クラウド プロバイダーでの subject の構成
クラウド プロバイダーの信頼関係で subject を構成するには、その信頼の構成に subject 文字列を追加する必要があります。 次の例は、さまざまなクラウド プロバイダーが同じ repo:octo-org/octo-repo:ref:refs/heads/demo-branch
subject を異なる方法で受け入れる方法を示しています。
クラウド プロバイダー | 例 |
---|---|
アマゾン ウェブ サービス | "HOSTNAME/_services/token:sub": "repo:octo-org/octo-repo:ref:refs/heads/demo-branch" |
Azure | repo:octo-org/octo-repo:ref:refs/heads/demo-branch |
Google Cloud Platform | (assertion.sub=='repo:octo-org/octo-repo:ref:refs/heads/demo-branch') |
HashiCorp Vault | bound_subject="repo:octo-org/octo-repo:ref:refs/heads/demo-branch" |
詳細については、「クラウド プロバイダーの OpenID Connect を有効にする」を参照してください。
OIDC 向けのアクションの更新
OIDC を使って認証するためにカスタム アクションを更新するには、Actions ツールキットの getIDToken()
を使って、GitHub の OIDC プロバイダーに JWT を要求することができます。 詳細については、npm パッケージ ドキュメントの「OIDC トークン」を参照してください。
また、curl
コマンドを使用し、次の環境変数を使って JWT を要求することもできます。
変数 | 説明 |
---|---|
ACTIONS_ID_TOKEN_REQUEST_URL | GitHub の OIDC プロバイダーの URL。 |
ACTIONS_ID_TOKEN_REQUEST_TOKEN | OIDC プロバイダーに対する要求のベアラー トークン。 |
次に例を示します。
curl -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" "$ACTIONS_ID_TOKEN_REQUEST_URL&audience=api://AzureADTokenExchange"
アクセス許可設定の追加
ジョブまたはワークフローの実行には、id-token: write
の permissions
設定が必要です。 id-token
の permissions
設定が read
または none
の場合、OIDC JWT ID トークンを要求することはできません。
この id-token: write
設定により、次のいずれかの方法を使用して、GitHub の OIDC プロバイダーから JWT を要求できます。
- ランナーで環境変数を使用する (
ACTIONS_ID_TOKEN_REQUEST_URL
およびACTIONS_ID_TOKEN_REQUEST_TOKEN
)。 - アクション ツールキットから
getIDToken()
を使用する。
ワークフローの OIDC トークンをフェッチする必要がある場合は、ワークフロー レベルでアクセス許可を設定できます。 次に例を示します。
permissions:
id-token: write # This is required for requesting the JWT
contents: read # This is required for actions/checkout
1 つのジョブに対して OIDC トークンのみをフェッチする必要がある場合は、そのジョブ内でこのアクセス許可を設定できます。 次に例を示します。
permissions:
id-token: write # This is required for requesting the JWT
ワークフローの要件に応じて、ここで追加のアクセス許可を指定する必要がある場合があります。
再利用可能なワークフローについては、id-token
の permissions
設定を、呼び出し元ワークフロー レベルか、再利用可能ワークフローを呼び出す特定のジョブで write
に設定してください。 詳しくは、「ワークフローの再利用」を参照してください。
OIDC 向けのワークフローの更新
シークレットではなく OIDC アクセス トークンを使うように YAML ワークフローを更新できるようになりました。 一般的なクラウド プロバイダーは公式のログイン アクションを公開しているので、OIDC を簡単に使い始めることができます。 ワークフローの更新の詳細については、「クラウド プロバイダーの OpenID Connect を有効にする」の後半に掲載されているクラウド固有のガイドを参照してください。
クラウド プロバイダーの OpenID Connect を有効にする
特定のクラウド プロバイダーに対して OIDC を有効にして構成する方法については、次のガイドを参照してください。
- 「アマゾン ウェブ サービスでの OpenID Connect の構成」
- 「Azure での OpenID Connect の構成」
- 「Google Cloud Platform での OpenID Connect の構成」
- 「HashiCorp Vault での OpenID Connect の構成」
別のクラウド プロバイダーに対して OIDC を有効にして構成する方法については、次のガイドを参照してください。