GEMINI LABEN
ROBOTICS — 8月31日に停止した ER 1.6 preview には後継があります。Gemini Robotics ER 2 が公開プレビュー中で、通常版とストリーミング版の2種類が提供されていますVIDEO — ER 2 の成功・失敗判定は静止画ではなく生の映像フィード上で動きます。こぼれ・滑り・位置ずれのような、実行の途中で起きる失敗を捉えられる設計ですDEADLINE — 次の期限は9月30日、gemini-omni-flash-preview の廃止です。移行先は8月27日に GA になった gemini-omni-1.1-flash で、残り4週間を切りましたAPIKEY — 残りの標準 API キーは、制限付きのものも含めて9月中に全面停止します。移行先は Google Cloud サービスアカウントに紐付く auth キー形式ですPRICE — Gemini 3.7 Flash の導入価格 $0.75/$3.75 per 1M は12月31日までです。2027年1月1日から $1.50/$7.50 になるため、年を跨ぐ見積もりは2本立てが要りますAUDIO — Gemini 3.5 Transcribe は85言語以上の言語検出、話者ダイアライゼーション、単語単位タイムスタンプ、最大1,000語のカスタム語彙バイアスに対応していますROBOTICS — 8月31日に停止した ER 1.6 preview には後継があります。Gemini Robotics ER 2 が公開プレビュー中で、通常版とストリーミング版の2種類が提供されていますVIDEO — ER 2 の成功・失敗判定は静止画ではなく生の映像フィード上で動きます。こぼれ・滑り・位置ずれのような、実行の途中で起きる失敗を捉えられる設計ですDEADLINE — 次の期限は9月30日、gemini-omni-flash-preview の廃止です。移行先は8月27日に GA になった gemini-omni-1.1-flash で、残り4週間を切りましたAPIKEY — 残りの標準 API キーは、制限付きのものも含めて9月中に全面停止します。移行先は Google Cloud サービスアカウントに紐付く auth キー形式ですPRICE — Gemini 3.7 Flash の導入価格 $0.75/$3.75 per 1M は12月31日までです。2027年1月1日から $1.50/$7.50 になるため、年を跨ぐ見積もりは2本立てが要りますAUDIO — Gemini 3.5 Transcribe は85言語以上の言語検出、話者ダイアライゼーション、単語単位タイムスタンプ、最大1,000語のカスタム語彙バイアスに対応しています
記事一覧/API / SDK
API / SDK/2026-09-02中級

9月で止まる Gemini の標準 API キーを、CI とサーバーとローカルの三層で棚卸しする

標準 API キーは制限付きのものも含めて9月中に拒否されるようになります。差し替えではなく出どころの移行になるため、コード・デプロイ設定・手元の三層に分けた棚卸しと、両対応クライアントを挟んでから切り替える手順をまとめました。

Gemini API230認証4サービスアカウント移行8運用13

Cloudflare Workers のダッシュボードでシークレットの一覧を開いたのは、先週の夜でした。Lab のサイトと個人開発のアプリを合わせて、Gemini のキーがどこにいくつ置いてあるのか、私は即答できませんでした。コードを検索すれば分かると思っていたのですが、出てきたのは環境変数の名前だけで、値そのものは画面の向こう側に置かれたままでした。

9月に入り、その曖昧さを残しておけなくなりました。標準の API キーは、制限を付けたものも含めて、今月中にリクエストが拒否されるようになります。移行先は Google Cloud のサービスアカウントに紐付く auth キーです。

最初にお伝えしたいのは、これがキーの文字列を新しいものに置き換えるだけの作業ではない、ということです。差し替えはコード検索で終わりますが、出どころの移行は棚卸しでしか終わりません。

変わるのは文字列ではなく、発行のしかたです

これまでの標準キーは、コンソールで発行して環境変数に入れれば、それだけで呼び出せる仕組みでした。キーは単体で完結していて、どのプロジェクトの持ち物かを意識せずに使えました。手軽さの代わりに、漏れた瞬間にそのキーの権限がまるごと外へ出ていく作りでもありました。

auth キーはサービスアカウントに紐付きます。誰が発行できるか、どのプロジェクトに属するか、どの API を呼べるかが、アプリケーションの設定ではなく IAM の側で決まります。鍵の管理がコードの都合から、プロジェクトの権限設計へ移る、と言い換えてもよいかもしれません。

移行の重さがここに出ます。文字列の置き換えなら grep で足りますが、権限の持ち方が変わる以上、置き場所と発行者と用途を一度並べ直さないと、何が終わって何が残っているのかを自分で把握できないのです。

一方で、助かる面もあります。ローテーションのたびに全環境へ新しい文字列を配って回る運用から、権限を絞ったアカウントを役割ごとに用意する運用へ移れます。私はこれを機に、記事生成のバッチと公開サイトの推論とを別のアカウントに分けました。

三層に分けて洗い出します

私が最初に失敗したのは、コードベースだけを見て「三箇所ですね」と結論づけたことでした。実際にはデプロイ設定と手元の環境に、コードには現れない鍵が残っていました。以下の三層に分けてから数え直したところで、ようやく全体が見えてきました。

探す場所見落としやすいもの
コードソース、テスト、サンプル、ドキュメント、NotebookREADME のコピー用スニペット、動作確認用の使い捨てスクリプト
デプロイ設定CI のシークレット、Workers や関数の環境変数、コンテナの起動引数停止したまま残っているワークフロー、プレビュー環境の設定
手元シェルの rc ファイル、.env、エディタの設定、キーチェーン数か月前に検証で入れたまま忘れている値

洗い出しは手で追うより、一度スクリプトにしてしまったほうが確実でした。次のものを走らせて、出力をそのままテキストに残しています。

#!/usr/bin/env bash
# gemini-key-inventory.sh — キーの在り処を三層で洗い出します
set -uo pipefail
 
PATTERN='GEMINI_API_KEY|GOOGLE_API_KEY|generativelanguage\.googleapis\.com|AIza'
 
echo "===== 層1: コード ====="
# .git や node_modules を除いて、キーの名前と直書きの痕跡を探します
grep -rInE "$PATTERN" . \
  --exclude-dir={.git,node_modules,.next,dist,build,vendor} \
  2>/dev/null | head -50
 
echo
echo "===== 層2: デプロイ設定 ====="
# Cloudflare Workers(wrangler.toml のあるディレクトリで実行します)
if command -v wrangler >/dev/null 2>&1; then
  wrangler secret list 2>/dev/null || echo "  (wrangler: 認証されていないか対象外です)"
fi
# GitHub Actions のリポジトリシークレットと環境シークレット
if command -v gh >/dev/null 2>&1; then
  gh secret list 2>/dev/null || echo "  (gh: 権限がないか対象外です)"
  for env in $(gh api repos/:owner/:repo/environments --jq '.environments[].name' 2>/dev/null); do
    echo "  [environment] $env"
    gh secret list --env "$env" 2>/dev/null
  done
fi
 
echo
echo "===== 層3: 手元 ====="
for f in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile" "$HOME/.zprofile"; do
  [ -f "$f" ] && grep -nE "$PATTERN" "$f" 2>/dev/null | sed "s|^|${f}:|"
done
# 直下2階層までの .env 系だけを見ます(深追いすると終わりません)
find . -maxdepth 3 -name '.env*' -not -path '*/node_modules/*' -print 2>/dev/null \
  | while read -r f; do grep -lE "$PATTERN" "$f" 2>/dev/null; done
 
echo
echo "棚卸しは以上です。件数ではなく『誰が発行したか』を各行に書き足してください。"

最後の一行が、私にとっていちばん効きました。場所の一覧は機械が作れますが、発行者と用途は自分で思い出すしかありません。思い出せない鍵が出てきたら、それは移行対象ではなく削除対象です。

両対応のクライアントを一枚挟んでから切り替えます

期限がある移行で怖いのは、切り替えた瞬間に全部が止まることです。私は認証経路を選ぶ関数を一枚挟み、サービスアカウント経由を優先しつつ、失敗したら旧経路へ落ちる形にしました。落ちたことが警告としてログに残る点が要です。

# gemini_client.py — 認証経路を選び、どちらで起動したかを必ず記録します
from __future__ import annotations
 
import logging
import os
 
from google import genai
 
log = logging.getLogger(__name__)
 
 
def build_client() -> tuple[genai.Client, str]:
    project = os.getenv("GOOGLE_CLOUD_PROJECT")
    location = os.getenv("GOOGLE_CLOUD_LOCATION", "us-central1")
    legacy_key = os.getenv("GEMINI_API_KEY")
 
    if project:
        try:
            client = genai.Client(vertexai=True, project=project, location=location)
            # クライアント生成では認証は検証されません。1回だけ実際に呼びます
            next(iter(client.models.list()), None)
            return client, "service-account"
        except Exception as exc:  # 認証・権限・ネットワークをまとめて拾います
            if not legacy_key:
                raise
            log.warning("サービスアカウント経路を使えませんでした: %s", exc)
 
    if not legacy_key:
        raise RuntimeError(
            "GOOGLE_CLOUD_PROJECT も GEMINI_API_KEY も設定されていません"
        )
 
    log.warning("旧経路の API キーで起動しました。9月の停止までに移行が必要です")
    return genai.Client(api_key=legacy_key), "legacy-api-key"
 
 
if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO)
    _, route = build_client()
    log.info("gemini auth route=%s", route)

next(iter(client.models.list()), None) を入れているのは、クライアントを作った時点では認証が確かめられないためです。ここを省くと、最初の推論リクエストまで失敗が表に出てきません。起動時に一度だけ呼んでおけば、デプロイ直後のログで判定できます。

あとは route=legacy-api-key の出現をログ検索するだけで、まだ旧経路に残っている環境が分かります。私はこの一行を各サービスの起動ログに入れておいて、朝に一度眺めています。ゼロになった環境から順に、旧キーを消していきました。

環境変数の名前が重複していて、差し替えたはずの値が効かないという別の落とし穴もあります。そちらはキーを差し替えても旧キーが勝つ話にまとめてありますので、棚卸しの前に一度目を通していただけると、原因の切り分けが早くなるかもしれません。

つまずいたのは、権限の粒度と手元の環境でした

サービスアカウントを作ったあと、最初のうち私は広めのロールを付けて動かしていました。まず動く状態を作りたかったからですが、そのまま忘れると、標準キーの頃より広い権限を持った鍵をばら撒くことになります。動作を確認したあとで、推論だけを行うアカウントの権限を絞り直しました。先に広く付けるのは構いませんが、絞り直す日をその場でカレンダーに置く、というのが今回の私の線引きです。

手元の環境では、サービスアカウントの JSON をダウンロードして置きかけたところで手が止まりました。私の作業フォルダは Dropbox の同期下にあり、鍵ファイルをそこへ置けば、同期の履歴にまで鍵が残ります。結局ローカルでは JSON を持たず、gcloud auth application-default login による ADC に切り替えました。手元は鍵ファイルを持たない、という一点だけでも決めておくと、移行後の不安がだいぶ減ります。

CI については、JSON をシークレットに貼るより Workload Identity 連携のほうが後々の管理は楽になります。ただ、期限が今月末に迫っている状況では、まずシークレット方式で通してから連携へ寄せる、という二段構えでも遅くはありません。期限のある移行では、正しい形を一度で作ろうとするより、止まらない形を先に作るほうが結果的に安全でした。

残りの日数をどう並べるか

順序を決めておくと、途中で気力が切れにくくなります。私は次のように並べました。

  1. 棚卸しスクリプトの実行と、三層の一覧のテキスト化
  2. 各行への発行者と用途の追記、そして思い出せない鍵の削除対象への振り分け
  3. 両対応クライアントの導入と、route のログ出力
  4. 影響のいちばん小さい系統から順に、サービスアカウントへの切り替え
  5. ログから legacy-api-key が消えた環境における、旧キーの削除

先に鍵を消してから直すのではなく、消せる状態を作ってから消す順です。当たり前のようでいて、期限が近いと逆をやりたくなります。

なお、9月にはもう一つ gemini-omni-flash-preview エンドポイントの廃止という期限も並んでいます。こちらはモデル ID の差し替えでおおむね片付きますので、影響範囲の広いキー移行を先に片付けてしまうほうが、月末の慌ただしさは軽くなるはずです。

まずは棚卸しスクリプトを一度走らせて、鍵の在り処の一覧をテキストに書き出すところまで、今日のうちに終えてみてください。私自身、そこまで進めた時点でようやく肩の荷が下りました。最後までお読みくださり、ありがとうございました。

シェア

お読みいただきありがとうございます

Gemini Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API / SDK2026-09-01
Gemini の API キーを差し替えても旧キーが勝つ。決め手は読み込み順ではありませんでした
同じ環境変数名を複数の経路が供給していると、キーを差し替えても古い値が残ります。読み込み順を四通り入れ替えた実測と、供給と読み取りを台帳に残す監査シムの実装をまとめました。
API / SDK2026-08-19
gemini-2.5-flash が「no longer available」で404を返しても、公式表の停止日は未告知のままです
gemini-2.5-flash の停止日は公式の廃止一覧から消えたままですが、404 の報告は7月から出ています。停止日の欄を安全マージンとして読むと外れる理由と、手元のキーで確かめる手順をまとめました。
API / SDK2026-08-01
temperature 非推奨で先に困ったのは、決定性ではなく多様性の側でした
temperature・top_p・top_k の非推奨化で影響が出たのは決定性ではなく多様性を作る側でした。呼び出し箇所の数え方、多様性を入力層へ移す設計、実効多様度の測り方を実測値とともに残します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →