AI エージェントが作ったレポートや記事、設定ファイルを、人の確認なしで本番に出す仕組みを作ろうとしている方向けの記事です。読み終わると、余計な変更を止める検査の置き場所と、定期点検の workflow で書き込みできる認証情報を AI の手順に渡さない構成が分かり、その経路を GitHub Actions で動かす月額を自分の条件で見積もれるようになります。
この記事で分かること
- 自動公開の安全を、AI の判断ではなく「AI を使わない検査」に預ける構成
- 4 つの AI なし検査(許可パス・SVG・公開フラグ・build)が、それぞれ何を止めるか
- 週次点検の workflow で、書き込みできるトークンを AI の手順が終わった後の最後の手順だけで作る方法
- この経路の GitHub Actions の月額(2026-11-06 時点の料金表で筆者が計算)
記事の品質の機械検証(AI 生成ブログの品質ゲート)や公開の自動化(公開完了までの自動化)とは別に、この記事は「出してよいパスだけ通す」と「トークンは最後だけ」に絞ります。
ざっくり言うと:安全の要は AI の判断ではなく、AI なしの検査にある
AI に「記事以外は触らないで」と頼んでも、守られる保証はありません。だから、本番に出る直前に、AI を使わないスクリプトで「差分が決まった場所のファイルだけか」を確かめます。
もう 1 つの柱は、AI を GitHub Actions の中で動かす場合の 書き込みトークン(GitHub に変更を書き込める認証情報)の置き場所です。筆者の週次点検の workflow では、AI が動いている間は書き込みできるトークンを存在させず、AI の手順がすべて終わった最後の手順でだけ作ります。こうすると、AI が予想外の動きをしても、リポジトリに書き込む手段が AI の手順にありません。
費用は、筆者の条件では月 1 ドル前後でした。公開回数を 12 倍にしても、GitHub の Free プランの無料分の 4 割ほどに収まります(計算は後半で示します)。
構成図:記事を本番に出す経路と 4 つの AI なし検査
図 1 は、筆者がこのサイトの運用で試した、記事を本番に出す経路です。左の灰色の枠が AI の作った成果物、青い点線の枠が AI なしの検査です。
図 1 のとおり、AI の成果物は、4 つの検査をすべて通らないと main に入りません。どれか 1 つで止まれば、本番には何も出ません。
なぜ develop からそのまま出さないか:記事以外の変更が 252 コミット溜まっていた
筆者の運用では、develop(開発中の変更を集めるブランチ)に、記事以外の変更が 252 コミット溜まっていました。develop をそのまま本番用の main に合わせると、利用者がまだ確認していない変更まで本番に出てしまいます。
そこで、main から新しく作った release ブランチ(本番に出す分だけを集める作業用ブランチ)に、develop から記事の .mdx と画像だけを取り込む方式にしました。差分が「記事と画像」以外を含んでいたら、スクリプトが scope エラーで止めます。
つまり「何を出すか」を AI の作業ブランチの中身に任せず、出す側が範囲を決めて取り込みます。
4 つの AI なし検査:何を止め、止め損ねると何が起きるか
release ブランチに取り込んだ後、4 つの検査を順に通します。どれも正規表現やスクリプトで判定し、AI の判断を使いません。図 2 と表 1 は、それぞれの役割を並べたものです。
表 1: 4 つの AI なし検査の役割(筆者の運用記録から整理)
| 検査 | 何を止めるか | AI の判断 | 止め損ねると | 筆者の運用での結果 |
|---|---|---|---|---|
| 許可パス | 記事の .mdx と記事用の画像以外のファイル | 使わない | 記事以外の 252 コミットが本番に出る | 範囲外のファイルがあれば scope エラーで停止 |
| SVG | script 要素・foreignObject 要素・on* 属性・外部への href | 使わない | 本番で SVG を直接開いたとき、スクリプトや外部読み込みが動く | 13 本の記事で errors 0。script を入れた SVG はエラー |
| 公開フラグ | draft: true のままの記事 | 使わない | 公開するつもりのない状態で出る | draft: true はエラー、draft: false は通過 |
| build | 構文が壊れたページ | 使わない | deploy の失敗や、壊れたページの公開 | 手元で build してから PR を作成 |
検査 1 許可パス:差分のファイル名を正規表現で照合する
差分のファイルのパスを 1 つずつ正規表現と照合し、「記事の .mdx」と「記事用フォルダの画像(決まった拡張子)」だけを許可します。この検査が漏れると記事以外の変更が本番に出るため、筆者は許可パスの検査を安全の要と位置づけました。
検査 2 SVG:本番で直接開かれる前提で止める
SVG(図を文字で記述する画像形式)は、中にスクリプトを書けます。また foreignObject という要素を使うと、ブラウザでは主に HTML を SVG の中に埋め込めます(MDN の foreignObject の解説)。
本番では SVG の URL を直接開けるため、script・foreignObject・on* 属性(クリック時などに動く処理を書く属性)・外部への href があればエラーにしました。AI が図を描く経路では、図も処理が動きうるファイルとして扱うのが安全だと考えられます。
検査 3 公開フラグと検査 4 build
公開フラグの検査は、記事の先頭の draft(下書きかどうかの印)が false のものだけを通します。最後にサイト全体を build(公開用のファイルを組み立てる処理)し、secret 検査(gitleaks というツールで鍵やパスワードの紛れ込みを調べる処理)も通します。
書き込みトークンは最後の手順だけ:permissions・persist-credentials と App トークンの作る位置
この節は、AI を GitHub Actions の中で動かす、公開済み記事の週次点検の workflow での構成です(前の節の公開経路の話ではありません)。検査を AI なしにしても、AI が動く手順の中に書き込みトークンがあれば、検査を飛ばして直接 push できてしまいます。そこで筆者は、週次点検の workflow で、トークンの位置を次のように分けました。
図 3 は、週次点検の 1 回の実行で、トークンがどこに存在するかを時間の順に示したものです。
workflow 全体の権限を読み取りだけにする
GITHUB_TOKEN(Actions が自動で用意するトークン)は、workflow が明示的に渡さなくても、各 action が github.token から使えます(GITHUB_TOKEN による認証)。そのため、AI の手順から GITHUB_TOKEN を完全に隠すことはできません。
そこで、workflow の先頭で permissions キーを使い、GITHUB_TOKEN の権限を読み取りだけにします。公式ドキュメントも、permissions キーで workflow 全体またはジョブごとに権限を最小限に絞るよう勧めています。
permissions:
contents: read
筆者の週次点検の workflow も、全体をこの設定にしています。GITHUB_TOKEN が AI の手順に届いても、読み取りしかできません。
checkout でトークンを残さない
GitHub Actions でリポジトリを取り出す actions/checkout は、既定では認証トークンをジョブの中に残し、ジョブ後の掃除で消します。persist-credentials: false を指定すると、最初から残しません(actions/checkout の README)。
- uses: actions/checkout@v4
with:
persist-credentials: false
筆者の週次点検の workflow では、checkout の 5 か所すべてをこの設定にしました。これで、チェックアウトしたフォルダに認証情報が残らず、AI の手順で git を使ったときにトークンが使われません。ただし、書き込みを防いでいる本体は前の項の permissions の設定で、persist-credentials: false だけでは防げません。
書き込みトークンは publish 手順でだけ作る
書き込みに使うのは GitHub App(権限を細かく決められる GitHub の連携アプリ)のトークンです。筆者は、このトークンを作る手順(actions/create-github-app-token)を、AI の手順がすべて終わった後の publish 手順の中に 1 か所だけ置きました。権限は、contents・pull-requests・issues の write に限っています。
週次点検の手順は「AI なしの plan → AI の audit と fix → AI なしの check → 別の AI の verify → AI なしの publish」の順です。修正後には、差分が記事と図のフォルダだけかを AI なしで確かめ、本番へは前の節の release の経路で出します。
費用試算:公開 1 回の分数 × 月の回数 + 週次点検(2026-11-06 時点)
料金の前提
GitHub Actions の料金は、GitHub Actions の課金の公式ページを 2026-11-06 に確認した値で計算します。
表 2: 計算に使った料金の前提(2026-11-06 時点)
| 項目 | 値 | 出典 |
|---|---|---|
| 標準の Linux ランナー(2 コア)の単価 | 1 分 0.006 ドル | 課金の公式ページ |
| Free for organizations の含まれる実行分 | 月 12 ドル(Linux で 2,000 分ぶん) | 同上。2,000 分は筆者が 12 ÷ 0.006 で計算 |
| Pro・Team の含まれる実行分 | 月 18 ドル(3,000 分ぶん) | 同上 |
| Enterprise Cloud の含まれる実行分 | 月 300 ドル(50,000 分ぶん) | 同上 |
| 分数の数え方 | ジョブごとに 1 分未満を切り上げ | ランナーの料金の参照ページ |
| 失敗した実行 | 失敗までの分も数え、再実行分と合算 | 課金の公式ページ |
含まれる実行分は、Private リポジトリで使った分から引かれ、毎月の請求サイクルの初めに戻ります。Public リポジトリの標準ランナーは、この枠とは別に無料です。
公開 1 回の分数は deploy だけになった
筆者のサイトでは GitHub Actions の CI を廃止し、CI の待ち時間も build も手元のスクリプトに移しました。そのため、公開 1 回で動く Actions は、main への push で起動する deploy の 1 ジョブだけです。
deploy の実行時間は直近の記録で 57〜85 秒、平均 75 秒です。1 ジョブなので切り上げると 1〜2 分になり、試算では上限側の 2 分を使います。
週次点検は 5 ジョブ構成で、成功した回の実行時間は約 7〜14 分でした。ジョブごとの切り上げで最大 5 分増えるとみて上限側の 19 分とし、月曜が 5 回ある月を想定して月 5 回とします。
計算結果
月の分数 = 公開回数 × 2 分 + 5 回 × 19 分
月額(ドル) = 月の分数 × 0.006
筆者のパイプラインは 1 日最大 6 本の記事を作る設定です。そこで月の公開回数は、6 本を 1 回の release にまとめる場合(月 30 回)と、1 本ずつ出す場合(月 180 回)を基本に、90 回と 360 回も並べました。
表 3: 月の公開回数ごとの Actions 分数と月額(筆者計算、2026-11-06 時点の料金)
| 月の公開回数 | deploy(分) | 週次点検(分) | 合計(分) | 月額(ドル) | Free の 12 ドルに対する割合 |
|---|---|---|---|---|---|
| 30 | 60 | 95 | 155 | 0.93 | 7.8% |
| 90 | 180 | 95 | 275 | 1.65 | 13.8% |
| 180 | 360 | 95 | 455 | 2.73 | 22.8% |
| 360 | 720 | 95 | 815 | 4.89 | 40.8% |
図 4 と表 3 から、次の 3 点が分かります。
- 月 30 回の公開では、週次点検の 95 分が deploy の合計 60 分より大きくなります。費用を左右するのは、公開回数より点検の長さです。
- 無料分の 2,000 分を使い切るのは、筆者が (2,000 − 95) ÷ 2 で計算すると月約 950 回の公開です。
- 週次点検の 5 ジョブが毎回すべて時間切れ(合計 210 分)になる最悪の場合でも、月 30 回の公開なら 1,110 分、6.66 ドルで、無料分に収まります。
週次点検が 1 回失敗して再実行した週は、失敗した 22 分の実行(切り上げで最大 27 分)と再実行の 19 分を合わせ、46 分(0.276 ドル)が上乗せされる計算です。
確認できなかったこと
当月の実際の使用分と請求額は、権限がなく確認できませんでした(プランが Free であることだけ確認)。AI のモデルを呼ぶ API の費用は Actions の料金とは別で、試算に入れていません。
つまずき:筆者の運用で起きたこと
画像を含む記事の PR が、自動 Merge から外れた
筆者の環境には、許可パスの検査が 2 種類あります。1 つは記事の PR を develop に自動 Merge するときの検査で、もう 1 つは前の節の release の検査です。
記事の PR は画像を含むため、前者の検査で自動 Merge の対象から外れました。そこで、記事と画像の両方を許可する release の経路を別に作りました。許可パスは経路ごとに決める必要があります。
CI の登録直後は no checks reported になる
これは、筆者のサイトで GitHub Actions の CI を廃止する前の記録です。CI がある環境では、PR を作った直後は検査がまだ登録されておらず「no checks reported」と表示されます。
待つ処理がこの表示で失敗したり、逆に待ちすぎて止まったりしないかが問題になります。筆者は、待ちのループが登録の前後どちらでも正しく動くかを確認項目にしました。
また公開のスクリプトでは、push を 3 回までやり直し、エラーの出力をログに残しています。
自分の環境に移すときの手順
- 本番に出してよいファイルの種類と場所を書き出します(例: 記事の .mdx と記事用フォルダの画像)。
- 書き出した範囲を正規表現にし、差分のファイル名と照合して、範囲外があれば止めるスクリプトを書きます。
- ファイルの形式ごとに、中身の危ない要素(SVG なら
scriptなど)を止める検査を足します。 - 公開フラグと build の検査を足し、4 つがすべて通ったときだけ main に入れます。
- AI を GitHub Actions で動かす場合は、workflow の
permissionsをcontents: readにします。 - AI が動く手順の checkout には
persist-credentials: falseを付けます。 - 書き込みトークンを作る手順を、AI の手順がすべて終わった後の 1 か所だけに置きます。
つまずきやすい点
squash で取り込むと、ブランチの親子関係が切れる
release ブランチを main に入れるときは、merge commit(2 つのブランチの履歴を両方残す取り込み方)を使います。squash merge(複数のコミットを 1 つにまとめる取り込み方)を使うと、元のコミットと別物として扱われ、次の release で同じ変更が再び差分に出ます。筆者のスクリプトが merge commit で main に入れているのは、このためです。
検査そのものを AI に書かせると、検査を緩められる
許可パスの正規表現や検査のスクリプトを、成果物を作る AI と同じ手順で書き換えられる状態にすると、AI が自分の成果物に合わせて検査を広げる可能性があります。検査のファイルは成果物と別の経路で管理し、検査のファイル自体が許可パスの外にあることを確かめるのが安全と考えられます。
無料分はプランと Public・Private で変わる
表 2 のとおり、含まれる実行分はプランで違い、この試算は Private リポジトリの場合です。また含まれる実行分は分数ではなく金額で決まるため、単価の高いランナーを使うと、同じ金額で動かせる分数が減ります。
まとめ
- 自動公開の安全の要は、AI の判断ではなく、出してよいパスだけを通す AI なしの検査に置きます。
- AI を Actions で動かす場合は、
permissionsをcontents: readにし、書き込みトークンは AI の手順がすべて終わった後の最後の手順でだけ作ります。 - 筆者の条件では月の Actions 費用は約 0.93 ドルで、公開回数を 12 倍にしても無料分の 4 割ほどでした。費用を左右するのは公開回数より定期点検の長さです。
自分の環境で経路や費用を見積もり直したい方、AI に任せる範囲の決め方を相談したい方は、お問い合わせからご連絡ください。AI が作った SQL の確認に不安がある場合は、BigQuery SQL レビューパックも用意しています。
参考にした一次情報
- GitHub Docs: GitHub Actions の課金(2026-11-06 確認)
- GitHub Docs: Actions ランナーの料金(2026-11-06 確認)
- actions/checkout の README(2026-11-06 確認)
- GitHub Docs: GITHUB_TOKEN による認証(2026-11-06 確認)
- MDN Web Docs: foreignObject(2026-11-06 確認)