14 人が閲覧(直近 30 日) GitHub

GitHub ActionsのEnvironments|承認ゲートと環境別シークレットの設計

GitHub ActionsのEnvironments|承認ゲートと環境別シークレットの設計

GitHub ActionsのEnvironments(環境)は、dev・stg・prodといった反映先ごとに、秘密情報と保護ルールをまとめて括るための単位です。ジョブに環境を1行紐づけるだけで、承認者の許可が下りるまでそのジョブを止めたり、そこでしか読めないシークレットを与えたりできます。本番反映をどこで人の判断に戻すかを、ワークフローのYAMLではなくリポジトリの設定側に置ける点が本質でした。

ここではワークフローの基本構造や、env・vars・secretsという変数の記法そのものには立ち入りません。全体像はGitHub Actionsとは?できること・使い方とCI/CD自動化の解説を、変数の書き方と受け渡しはGitHub Actionsの環境変数|env・vars・secretsの使い分けと受け渡しを参照してください。本記事は環境という単位に紐づく保護ルールと秘密情報の分離だけを扱います。記載した数値と仕様は2026年8月時点の公式ドキュメントで実測しました。

まとめ:Environmentsを入れる前に決める3つの分岐

先に結論から書きます。第一の分岐は、そのリポジトリがパブリックかプライベートかです。承認ゲートに相当する必須レビュアーと待機タイマー、そしてカスタム保護ルールは、GitHub Free・Pro・Teamではパブリックリポジトリでしか設定できません。受託開発の現場で多いプライベートリポジトリで承認を効かせたいなら、Enterpriseプランが前提になります。ここを確かめずに設計へ入ると、後半で作り直しが発生しました。

第二の分岐は、環境を秘密情報の入れ物として使うのか、止める仕掛けとして使うのかです。環境シークレットと環境変数、そしてデプロイ可能ブランチの制限は、Pro・Teamならプライベートリポジトリでも設定できます。つまり資格情報の分離とブランチの縛りだけならプランを上げずに実現でき、人の承認を挟む部分だけがプランに依存します。

第三の分岐は、待たせる時間の設計です。待機タイマーは1分から43,200分まで指定でき、その待ち時間は課金される実行分数に含まれません。承認待ちは最大30日、ワークフロー実行そのものは待機と承認を含めて35日で打ち切られます。深夜の反映を避けたい、あるいは監視が落ち着くまで数時間置きたいといった要件は、この範囲なら追加のスクリプトなしで表現できました。

Environmentsの基本|ジョブに環境を紐づけて何が変わるか

環境はリポジトリの設定画面から作成し、名前を付けて保存するだけで用意できます。作った環境をワークフローから使うには、ジョブの直下に environment を書きます。この1行があると、ジョブは実行開始前に環境の保護ルールを通過しなければならなくなり、通過するまで待機状態のまま停止しました。

environmentキーの書き方とデプロイ先URLの表示方法

最短の書き方は environment に名前を文字列で渡す形です。反映先のURLを実行画面へ出したいときは、name と url を持つマップ形式へ変えます。url にはステップの出力を式で渡せるため、動的に払い出されるプレビュー環境のアドレスも表示できました。

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: ${{ steps.deploy.outputs.endpoint }}
    steps:
      - uses: actions/checkout@v5
      - id: deploy
        run: echo "endpoint=https://example.com" >> "$GITHUB_OUTPUT"

環境名は自由に決められますが、後で述べるOIDCの条件式に環境名がそのまま入るため、production・staging のように英小文字で短く固定しておくと運用が楽になります。日本語名も付けられる一方、クラウド側の信頼ポリシーへ書き写す場面で扱いにくくなりました。

環境を分ける単位と分けなくてよいものを判断するための設計基準

環境を作りすぎると設定の重複が増えます。目安として、資格情報が違う、承認者が違う、反映を許すブランチが違う、のいずれかに当てはまるときだけ環境を分けてください。逆に、同じ資格情報で同じ承認者、違うのはリージョンやサフィックスだけ、という程度ならジョブのマトリックスや入力値で分ければ足ります。

プレビュー環境のようにプルリクエストごとに増える反映先は、環境を都度作るのではなく1つの環境へ集約し、URLだけを動的に変える構成が扱いやすい形です。手で押して起こす反映へ切り出す場合の入口はGitHub Actionsの手動実行(workflow_dispatch)|inputsの型定義とCLI・APIからの起動にまとめており、environment型の入力と組み合わせると、起動時に反映先を選ばせる形が作れました。

環境シークレットと環境変数|上限値と3階層で決まる優先順位の設計

環境に紐づけられるのはシークレットと構成変数の2種類です。どちらも組織・リポジトリ・環境という3つの階層に置けて、同じ名前が複数の階層にあるときの勝ち負けが決まっています。この優先順位を知らないまま環境側へ値を足すと、意図せず上位の値を覆い隠す事故になりました。組織シークレットのアクセスポリシーの絞り方や、棚卸しとローテーションの運用設計までを含めた全体像は、GitHub ActionsのSecrets管理で置き場所とOIDC移行の判断を整理した解説で確認できます。

環境シークレットは100個・48KBという現行の上限と設定時の注意点

公式ドキュメントの現行値は、組織シークレットが1,000個、リポジトリシークレットが100個、環境シークレットが環境あたり100個です。1つあたりのサイズは48KBまでで、証明書や鍵ファイルを丸ごと入れる用途では上限に当たることがあります。構成変数の側は、組織が1,000個、リポジトリが500個、環境あたりが100個で、こちらも1つ48KBまでという扱いでした。

変数にはもう1つ、リポジトリ変数と組織変数の合計が1実行あたり256KBまでという制限があります。環境変数はこの合計に含まれないため、リポジトリ側が上限へ近づいているときの逃がし先としても働きました。値の置き場所を決める際は、この差を踏まえて分散させてください。

同名なら環境が勝つ優先順位と読み替えの落とし穴を防ぐ確認方法

組織・リポジトリ・環境のすべてに同名のシークレットがある場合、環境レベルの値が優先されます。構成変数も同じ並びで、環境がリポジトリを上書きし、リポジトリが組織を上書きしました。上書きの向きは直感どおりですが、問題は上書きが起きたことがログに出ない点にあります。

jobs:
  deploy:
    environment: production
    steps:
      - run: aws s3 sync ./dist "s3://$BUCKET"
        env:
          BUCKET: ${{ vars.DEPLOY_BUCKET }}
          AWS_ROLE: ${{ secrets.AWS_ROLE_ARN }}

この記法だけを見ても、DEPLOY_BUCKET が環境の値なのかリポジトリの値なのかは判別できません。運用では、環境に置く変数へ ENV_ のような接頭辞を付けるか、環境ごとに名前を変えて明示的に切り替える方針が安全です。再利用ワークフローへ渡す場合の受け渡しはReusable Workflowsとは?GitHub Actionsのworkflow_callで再利用する方法で扱っており、呼び出し側の環境が何を渡すのかを併せて確認しておくと事故が減りました。

保護ルール4種の実装|承認・待機時間・ブランチ制限・カスタムゲート

環境に設定できる止め方は4種類あります。人が承認する必須レビュアー、時間で遅らせる待機タイマー、対象を絞るデプロイ可能ブランチとタグ、そして外部のGitHub Appへ判断を委ねるカスタムデプロイ保護ルールです。組み合わせて設定でき、すべてを満たすまでジョブは動きません。

必須レビュアーは最大6件・承認は30日で失効する場合の運用上の確認事項

レビュアーには最大で6人またはチームを登録できます。全員の承認は要らず、登録した中の1人が承認すればジョブは進みました。自分が起こした反映を自分で通してしまう運用を避けたい場合は、自己レビューを禁止する設定を併せて入れてください。管理者による保護ルールの迂回を許すかどうかも、同じ画面で切り替えられます。

承認待ちの上限は30日です。ここを過ぎると承認は成立せず、実行そのものも待機と承認を含めて35日で打ち切られます。長期の凍結期間を挟む運用では、承認待ちのまま放置するのではなく、いったん実行を止めて再度起こす手順に寄せる方が確実でした。

待機タイマーは1分から43,200分まで指定できる場合の設定手順

待機タイマーは、ジョブが起動条件を満たしてから実際に走り出すまでの遅延を分で指定します。指定できるのは1から43,200までの整数で、上限の43,200分は30日に相当しました。承認と組み合わせると、承認が下りた後にさらに待たせる構成も作れます。同じ環境へのデプロイが重ならないようにする制御は承認とは別の層で、GitHub Actionsのconcurrency|groupの設計とcancel-in-progress・queueの選び方が担当します。

実務で効くのは、この待ち時間が課金対象の実行分数に含まれない点です。監視の様子を見ながら段階的に広げる反映では、ジョブを走らせたまま sleep で待つ実装がよく使われますが、その方式は待った分だけ分数を消費しました。料金側の考え方はGitHub Actionsの料金|2026年改定後の分単価・無料枠とコスト削減の判断基準に整理しており、待ち時間の長い反映ほど待機タイマーへ寄せる価値が出ます。

デプロイ可能ブランチとタグはfnmatch準拠で書く場合の照合時の注意点

反映を許す参照の絞り方は3通りです。制限なし、保護ブランチのみ、そして名前のパターンで選ぶ方式が選べます。パターン方式ではブランチとタグを別々に登録でき、releases/* のようなワイルドカードも書けました。

注意点は、ワイルドカードがスラッシュにマッチしない仕様です。パターンの照合はRubyのFile.fnmatchに準じており、releases/* は releases/v1 に一致しますが releases/2026/v1 には一致しません。階層の深いブランチ名を使っている場合は、パターンを階層の数だけ登録するか、ブランチ命名の側を1階層へ揃えてください。発火条件そのものの設計はGitHub Actionsのトリガー(on)|イベント選定とbranches・pathsフィルタの設計で扱っており、on側のフィルタと環境側の制限は役割が違うため、両方を書いて二重に縛る形が基本になりました。

カスタムデプロイ保護ルールで外部の判断へ委ねる際の判定条件の設計方法

4つ目は、GitHub Appが作るカスタムデプロイ保護ルールです。監視サービスや変更管理の仕組みと連携し、外形監視が正常であること、変更申請が承認済みであることといった条件を、GitHub側の承認画面と同じ流れで扱えました。標準の3種で表現できない社内規程がある場合の逃がし先になります。

ただしこのカスタムルールも、Free・Pro・Teamではパブリックリポジトリ限定という制約を受けます。プライベートリポジトリで社内規程を機械的に効かせたいなら、Enterpriseへ上げるか、後述するように環境の外側で仕組みを作るかの二択でした。

プライベートリポジトリで承認が動かないプラン条件の実際を見極める方法

ここが本記事で最も伝えたい部分です。Environmentsは作れるかどうかと、保護ルールが効くかどうかが別々に決まっており、日本語の解説記事ではこの線引きがほとんど書かれていません。設計を始める前に、自分のリポジトリがどの列に該当するかを確かめてください。

機能 パブリック プライベート(Free) プライベート(Pro・Team)
必須レビュアー 設定できる 不可 不可(Enterprise要)
待機タイマー 設定できる 不可 不可(Enterprise要)
カスタム保護ルール 設定できる 不可 不可(Enterprise要)
ブランチとタグの制限 設定できる 不可 設定できる
環境シークレット 設定できる 不可 設定できる
環境変数 設定できる 不可 設定できる

承認と待機がパブリック限定になる範囲の見極め方とプラン別の確認手順

表のとおり、止める仕掛けの3種はFree・Pro・Teamではパブリックリポジトリ限定です。プライベートリポジトリで承認ゲートを効かせられるのはEnterpriseだけと考えてください。一方、資格情報の分離とブランチの縛りはPro・Teamでも動くため、環境を作る意味は残ります。

プランを上げない前提で承認を挟むなら、環境の外側で組む選択になります。実務でよく採るのは、反映用のワークフローを手動起動に限定し、起動できる人をリポジトリの権限で絞る形でした。承認の記録は残りませんが、誰がいつ押したかは実行履歴に残るため、監査の要求が軽い案件なら成立します。

公開範囲を切り替えたときに保護ルールが失われる挙動と再設定の判断基準

もう1つ落とし穴があります。パブリックリポジトリをプライベートへ変換すると、設定済みの保護ルールと環境シークレットは無効化されました。再びパブリックへ戻せば元の設定が復元される旨がドキュメントに書かれているものの、プライベートの期間は承認ゲートが素通りになる点に注意してください。

オープンソースとして公開していたリポジトリを社内へ引き取る移行では、この切り替えのタイミングで本番反映が無防備になります。移行の当日は反映用ワークフローを止めておき、プランと保護ルールの再設定を終えてから再開する段取りを組んでください。

デプロイ履歴とOIDC|環境スコープで権限を絞る実装手順と設定例

環境を使うと、GitHub側にデプロイという記録が積み上がります。この記録は画面から追えるだけでなくAPIからも取得でき、いつどのコミットがどの環境へ入ったかを機械的に照会できました。もう1つ、クラウドの認証を環境単位で縛れる点も、環境を使う実利として大きい部分です。

Deployments APIに残る履歴を運用の証跡として使う

環境を指定したジョブが走ると、リポジトリのDeploymentsに実行が記録され、対象のコミットや状態、environment に url を書いていればその宛先まで残ります。リポジトリのトップ画面からも環境ごとの直近の反映が見えるため、どの環境が今どのコミットで動いているかを口頭で確認する手間が減りました。

受託案件では、この履歴を月次の報告資料へそのまま転用できます。反映の回数、対象コミット、承認した人といった情報が同じ場所に揃うため、別途表計算で台帳を作る運用を廃止できた案件がありました。切替方式そのものを見直す段階ではブルーグリーンデプロイメントとは|仕組み・他方式との違いとAWS実装も併読してください。

subクレームのenvironmentスコープと不変サブジェクト

OpenID Connectでクラウドへ認証する構成では、GitHubが発行するトークンのsubクレームに環境名が入ります。ジョブが環境を参照している場合、subは repo:octo-org/octo-repo:environment:prod のような形になり、クラウド側の信頼ポリシーでproduction環境から来た実行だけに本番ロールを渡すという縛りが書けました。長期の資格情報を配らずに環境ごとの権限差を作れる、実装上の勘所です。id-tokenを含むスコープ全体の決め方はGitHub Actionsのpermissions|GITHUB_TOKENの既定権限と最小権限の設計にまとめました。

"token.actions.githubusercontent.com:sub":
  "repo:octo-org/octo-repo:environment:production"

ここで2026年の変更を押さえておいてください。2026年7月15日以降に作成されたリポジトリでは、所有者IDとリポジトリIDを含む不変サブジェクト形式が既定になりました。名前空間が再利用されたときに同じsub値を別人が作れてしまう問題への対処で、形式は repo:所有者@所有者ID/リポジトリ@リポジトリID:environment:環境名 という並びに変わります。既存リポジトリは明示的に切り替えるまで従来形式のままで、GitHub Enterprise Serverでは提供されていません。新規に作ったリポジトリで信頼ポリシーが通らない場合、まずこの形式差を疑ってください。

受託開発でEnvironmentsを採る条件と見送ってよい場面

採用条件は3つに絞れます。1つ目は、本番の資格情報を検証環境のワークフローから読めない状態にしたい場合です。これはPro・Teamのプライベートリポジトリでも成立し、環境シークレットへ移すだけで、検証用ジョブが誤って本番へ書き込む経路を物理的に断てました。導入コストが小さく効果が明確なため、ここだけは全案件で入れて構いません。

2つ目は、反映の可否を判断する情報がリポジトリの外にある場合です。営業時間中は反映しない、業務側の確認が済むまで待つといった条件は、コードで表現するより承認者へ委ねる方が正確に回りました。ただし前述のとおり、プライベートリポジトリでこれを使うにはEnterpriseが要ります。プランの費用と、承認を人手の運用で回す費用を並べて判断してください。

3つ目は、監査で反映の証跡を求められる場合です。誰が承認し、どのコミットがいつ入ったかがGitHub内に閉じて残る点は、外部の申請システムと突き合わせる運用より確実に安く付きました。

逆に見送ってよい場面もはっきりしています。反映先が1つしかなく、資格情報も1組しかない小規模な案件では、環境を作っても設定画面が1段増えるだけで得るものがありません。反映がすべて自動で、人の判断を挟む余地が最初から無い構成も同様でした。この場合はブランチ保護と権限設計だけで足り、環境の追加は後から必要になった時点で行えば間に合います。CI/CD全体をどこまで自動へ寄せるかという前提の整理はCI/CDとは?仕組み・パイプラインと導入すべき企業の判断基準を参照してください。

すでに動いているパイプラインへ後から環境を差し込む場合、資格情報の移設と保護ルールの設定、そして反映手順書の書き換えが同時に発生します。引き渡し後の運用まで含めた設計を外部へ委ねたいときは、保守運用 / 内製化支援で現行のワークフローを読んだうえでの移行計画から相談を受けています。

よくある質問

環境を作っただけでジョブは止まりますか?

止まりません。環境を作成しただけでは何も起きず、ジョブ側に environment を書いて紐づけ、かつ環境へ保護ルールを設定して初めて待機が発生します。設定したのに止まらない場合は、ジョブに environment を書き忘れているか、プラン条件で保護ルールが有効になっていないかのどちらかを疑ってください。

承認待ちの間もGitHub Actionsの分数は消費されますか?

消費されません。待機タイマーによる待ち時間は課金対象の実行分数に含まれない旨がドキュメントに明記されており、承認待ちも同様にジョブが走っていない状態です。ただし実行全体の上限である35日は待機と承認を含めて数えられるため、長時間の停止を前提にした設計は避けてください。

環境シークレットとリポジトリシークレットは併用できますか?

できます。同名の場合は環境レベルの値が優先され、リポジトリレベル、組織レベルの順に負けました。共通の値はリポジトリや組織へ置き、環境ごとに変わる値だけを環境へ置く分け方が管理しやすい形です。名前が衝突すると上書きが起きたことに気付けないため、接頭辞で区別しておくと安全になります。

デプロイ可能ブランチの指定でreleases配下が全部通りません

ワイルドカードがスラッシュにマッチしない仕様が原因です。releases/* は1階層下までしか一致しないため、releases/2026/v1 のような深い名前は別途パターンを登録する必要があります。照合はRubyのFile.fnmatchに準じており、階層を跨ぐ表現は用意されていません。ブランチ命名を1階層へ揃える方が運用は簡単になりました。

プライベートリポジトリで承認ゲートを安く実現する方法はありますか?

GitHubの機能だけで実現するならEnterpriseが必要です。プランを上げない前提なら、反映用ワークフローを手動起動に限定して起動権限を絞る、あるいは反映用リポジトリだけを分離して環境の設定条件を満たす、といった回避策になります。承認の記録が残らない点は割り切りが要るため、監査要件の有無で選んでください。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.09 テックブログ IDCFクラウド(IDCフロンティア)不正アクセス・ランサムウェア:影響先・復旧・データは戻るか
  2. 2026.10.08 テックブログ 大阪公立大学のランサムウェア被害と仮想化基盤の停止|全授業休講に至った経緯とバックアップを守る設定
  3. 2024.11.08 テックブログ OpenAPI GeneratorでJavaコードを自動生成する方法|CLI導入からSpring・ライブラリ選択まで
  4. 2026.10.09 テックブログ 京王電鉄のランサムウェア被害とグループ共通基盤:決済・ポイント・予約が止まった範囲と遮断の初動
  5. 2026.10.09 テックブログ ニッスイのサイバー攻撃で日水物流の入出荷停止|委託先クラウド障害に荷主が備える手順

RELATED POSTS 関連記事

目次