AI Security Playbook

解説 / 約20分

APIキーを替えたのに、古いキーが使われている?

保存先を更新し、新しい起動でも確認した。その先に残る旧プロセスや定期処理、発行元の失効までを、図と架空の版名でたどる。

実践 · APIキーの保存先を把握し、動いているアプリへの反映を確かめる方へ。

読む前の補足
  • 保存した版と、実行中のアプリが使う版を分ける。
  • 通常更新と漏えい時で、失効の判断を変える。
  • サービスと定期処理、更新後と失効後の証拠を確認する。
この記事の目次

APIキーを新しく発行し、クラウドの設定も書き換えました。新しく起動したアプリから、外部APIへ接続できることも確認しています。

ところが翌朝、定期処理だけが失敗しました。画面からの操作は動くのに、夜間の処理は古いキーを使っていたのです。

これは仕組みを説明する架空の場面です。この記事は、AIで作ったアプリを公開し、外部APIのキーを自分で管理する人に向けたもの。「新しい値を保存できた」の先で、どこまで交換が届いたかを見ていきます。

外部APIのキーを更新するときに新しいキーは、動いているアプリまで届いた?

キーを替える場所は、一つではない

シークレットは、APIキーやパスワードなど、秘密として扱う情報です。ローテーションは、それを新しいものへ交換すること。ここでは外部APIへの接続に使うキーを扱います。

「設定を更新した」という言葉には、少なくとも3つの違う状態が隠れています。

交換の3つの場所を分ける

  1. 発行元

    新しいキーを発行し、旧キーの有効性を管理。

  2. 保存先

    使わせる版を保存・指定する。

  3. 稼働先

    プログラムが読み込んだ値で接続する。

保存値を替えることと、稼働への反映、発行元での失効は別の操作です。

シークレット管理サービスへ新しいキーを保存しても、外部APIの発行元が古いキーを無効にしたとは限りません。また、保存済みの値と、アプリのメモリに読み込まれた値は別です。

プロセスは、起動して動いているプログラムです。起動時にキーを一度だけ読み、接続用のクライアントを作る実装なら、保存先を更新しても、そのクライアントは古い値を持ち続けることがあります。

例えば「朝から動いているWebアプリ」「夜だけ動く集計」「手元の管理用スクリプト」は、同じキーを使っていても別の利用者です。Webアプリ一つの成功を、全部の成功へ広げないのが出発点です。

更新したのは、どの場所?

「新しいキーにした」を、「発行した」「保存した」「この実行が読み込んだ」「古いキーを失効した」に言い換えると、残った仕事を見つけやすくなります。

Cloud Runでは、読むタイミングを区別する

一例としてCloud Runでは、シークレットを環境変数、つまり実行環境からプログラムへ渡す値として使う場合、インスタンスの起動時に値が解決されます。latestを指定しても、起動済みの値が常に追従するという意味ではありません。Googleは環境変数では特定の版を指定することを推奨しています。Cloud Run公式資料

一方、ファイルとして接続するボリュームマウントでは読取時に値を取得します。新しい版を追う設定でも、アプリが起動時に読んでメモリへ保存したままなら、アプリ側の使う値まで自動で替わるとは限りません。特定の版に固定したファイルは、その指定も別に確認します。

同じ保存先でも、読む時点が違う

  1. 起動時に読む

    起動済みのプロセスには、以前の値が残り得る。

  2. ファイルから読む

    読取で取得しても、アプリ内のキャッシュは別に確認。

Cloud Runの環境変数とマウントの例です。別サービスの挙動は公式仕様で確かめます。

この違いはCloud Runの例です。別のクラウド、ライブラリ、CIでは、再読込・キャッシュ・再起動の仕様をそれぞれ確認します。毎回取得する設計にも、通信の失敗や遅延、利用料金という別の考慮があります。「毎回取得すれば解決」ではなく、取得失敗時に古い値を使うのか、処理を止めるのかも決めます。

Cloud Runの公式資料では、環境変数の取得に失敗すると起動できず、マウントされた値も実行中の読取に失敗し得ると説明されています。交換の計画には、キーの有効性と、保管場所を読める権限・可用性の両方が必要です。

保存先を替えても、起動済みのコピーは替わらない

次は、自分のPCのNode.jsで動かせる架空例です。Node.jsを用意していない人は、コード下の結果だけでも読み進められます。demo-Aとdemo-Bは版の名前で、キーの値ではありません。環境変数やファイル、ネットワークは読み書きしません。

let savedVersion = "demo-A";
function startClient() {
  return { version: savedVersion };
}
const oldClient = startClient();
savedVersion = "demo-B";
const newClient = startClient();

// 発行元でBだけが有効になった状態を、架空の集合で表す。
const acceptedVersions = new Set(["demo-B"]);
function result(client) {
  return acceptedVersions.has(client.version) ? "受理" : "拒否";
}
console.log("保存先:", savedVersion);
console.log("起動済み:", oldClient.version, result(oldClient));
console.log("新しく起動:", newClient.version, result(newClient));

結果はこうなります。

保存先: demo-B
起動済み: demo-A 拒否
新しく起動: demo-B 受理

保存先はBでも、先に作ったクライアントはAです。この例の拒否は、集合をBだけにした結果です。実際のAPIキーを失効させるコードではありません。 実サービスでは、発行元での失効と反映時間、アプリの読込方法を確かめます。

どこまで替わった? 3つの状態を比べる

保存先だけBに更新

起動済みのAは残り得る

新しい保存値と、アプリが読み込んだ値を分けて追います。

新しい起動がBで成功

古い実行は別に確認

一つの成功だけで、旧リリースや定期処理まで確認済みにはしません。

発行元でAを失効

残るAは接続に失敗し得る

新しい版での接続と、旧実行・次回の処理を確認します。

架空の版A・Bの比較です。実際の再読込と失効の仕様はサービスで異なります。

「古い版が残るか」と「古い版が接続先に受理されるか」は別の問いです。両方を分けて確認すると、更新漏れによる停止と、古いキーが使えるまま残るリスクを区別できます。

通常の交換と、漏えいしたキーへの対応を分ける

漏えいの兆候がない計画的な交換なら、提供元が複数キーの併用を認めている場合に、新旧を短期間重ねて切り替える方法があります。キーが一つだけのサービスでは、この方法をそのまま使えません。メンテナンス時間や別の認証方法など、提供元の手順に合わせます。

漏えいの兆候がない通常更新

  1. 新しいキーを用意

    併用が許可される場合、必要な権限で発行。

  2. 稼働先を切り替える

    利用先を更新し、限定した操作で確認。

  3. 旧キーを失効

    旧実行の残りと、失効後の動作も確認。

複数キーを併用できないサービスは、提供元の切替手順に合わせます。

新しいキーでは、接続成功だけでなく、必要な権限・対象のアカウント・テスト環境か本番かも照合します。権限が足りないキーや、別のプロジェクトのキーを保存しても、文字列としての更新は成功してしまいます。

漏えいした、または漏えいを疑う根拠がある場合は、無停止の切替を待ち続けません。 発行元の事故対応手順に従い、悪用を止めるための迅速な失効や権限制限を判断します。停止の影響と不正利用の影響を比較し、接続先の管理者へ連絡します。詳しくは漏えい時の対応へ。

漏えい時は、悪用を止める判断を優先

  1. 露出や不正利用の根拠

    対象キーと接続先を特定し、提供元の手順へ。

  2. 失効と制限

    被害と停止の影響を考え、迅速に判断。

  3. 新しい認証で復旧

    利用先を確認し、侵害された値へ戻さない。

無停止の準備を待ち続けず、通常更新と分けて対応します。

保管サービスの古い版を無効にする操作と、外部API側でキーを失効する操作は別です。保存先から消しただけで、既に持ち出されたキーまで使えなくなったとは判断できません。

キーの値を見せずに、使う版を追う

確認には、公開して差し支えない内部の版名とリリース・実行IDを対応付けます。キーそのもの、キーを含む環境変数一覧、接続ヘッダーをAIや公開ログへ貼らないでください。

保管場所の事故が、接続先のキー交換につながった

分類:事故の公表。 CircleCIは2023年1月4日に利用者へ事故を通知し、1月12日の当事者報告で、シークレットのローテーションと失効を呼びかけました。CircleCIの事故報告

ここからの学びは、保管・実行基盤側の事故でも、そこから利用する外部サービスの認証情報が対応対象になり得ることです。全利用者が不正利用されたという意味ではありません。自分の対象期間・保管していた情報・接続先は、当事者の通知と自分の記録で照合します。

別の運用例として、numekudiさんのシークレット更新の記事は、保存値だけでなく、実行中のアプリや定期処理への反映を取り上げています。これは著者による運用報告であり、上のCircleCI事故と同じ出来事ではありません。本教材の架空例も、原記事の環境を再現した実験ではありません。

Webが動いていても、定期処理は別に確かめる

ジョブは、集計や通知など、決まった処理を実行して終わる仕事です。Webアプリとは別の設定、別の起動時刻、別のキーを持つことがあります。

画面の裏にも、別の利用先がある

  1. 同じ接続先のキー

    どこで使うかを一覧にする。

  2. Webサービス

    旧リリースへの流量や別URLも見る。

  3. 定期ジョブ

    次回・再試行・実行中の処理を確認。

  4. CI・管理用の実行

    別環境の設定と読込方法も照合。

一つの成功を、すべての利用先の成功として扱いません。

棚卸しでは、公開中のリリースだけでなく、まだリクエストが届く古い版、別URLで呼べる版、実行中のジョブ、次回の定期実行、再試行や手動実行の設定も見ます。利用先を特定できないキーは、「全部更新できた」としません。

確認のために、本番の請求・メール送信・更新ジョブを重ねて実行しないでください。提供元が用意する安全なテスト操作や、影響を限定した検証方法を選びます。ヘルスチェックの成功が、外部APIへ新しいキーで接続した証拠になるとは限りません。

キーごとの利用記録が発行元で見られるなら、旧キーの使用を追う助けになります。ただし、夜間だけ動く処理は昼間に記録がなくても不思議ではありません。利用記録がないことだけで、すべての旧実行がなくなったとは断定しません。

一人でも、3つの役割で見直す

利用先を把握する人:どこで使うかをそろえる

Web、本番とテスト、定期処理、CI、管理用の実行環境を一覧にします。各利用先の担当・設定名・読込時点・次の実行を記録し、分からない場所は未確認として残します。アプリ画面の成功だけで全体を代表させません。

アプリを更新する人:読み込んだ版を実行と結び付ける

保存先の版と、反映したリリース・ジョブ定義・実行IDを照合します。起動済みのクライアントを更新する必要があるかは、実装で確認します。ログに必要なのは接続結果と安全な版の識別であり、キーの内容ではありません。

発行元を管理する人:旧キーの失効を確かめる

新旧併用の可否、キーの権限、失効操作と反映時間を確認します。失効後に新しい実行が動くことと、旧キーが無効なことを、提供元が認める手段で確認します。漏えいなら通常更新とは別の優先度で判断します。

個人開発では同じ人が担当して構いません。AIには一覧や設定差分の整理を頼めますが、実キーを渡す必要はありません。AIの「更新済み」は、実行記録と失効状態の代わりにはなりません。

交換が届いたと判断するための証拠

  • 利用先: Web・定期処理・CIなどの利用先と、今回対象か対象外かが分かる一覧がある。不明な利用先は完了扱いにしない。
  • 新しい版: 保存先の版と、必要な権限・アカウント・環境を照合した記録がある。キーの値は記録に含めない。
  • 稼働への反映: リリースや実行IDと読込版の対応、影響を限定した接続確認の結果がある。保存の成功だけで終えない。
  • 旧実行: 古い版への流量・別URL・実行中/次回のジョブを確認し、残る対象と対応期限が分かる。
  • 失効後: 発行元での旧キー失効状態と、新しい版での動作結果がある。失効状態を確認できなければ未確認とする。
  • 異常時: 誰へ連絡し、何を止め、どの安全な版へ戻すかが決まっている。漏えいキーを復活させる復旧案にしない。

次の定期実行まで、更新を追う

交換を、次の動作までつなぐ

  1. 版と実行を照合

    キーの内容ではなく、版と実行IDで追う。

  2. 失効後を確認

    新しい版で動き、旧キーが無効かを見る。

  3. 未確認を残す

    次回の定期実行と担当・期限を決める。

以前のアプリへ戻す場合も、有効なキーとの組み合わせを確認します。

通常更新でも、古いキーを失効した後の動作まで見て一区切りです。次回の定期実行が未確認なら、予定と確認担当を残します。エラー増加や外部APIの拒否を見たら、値を表示せず、利用先・版・実行時刻から切り分けます。

以前のアプリへロールバック、つまり戻す場合も注意が必要です。古いリリースが失効済みのキーを参照していれば、戻したことで接続できなくなります。復旧できるコードの版と、有効で適切なキーの組み合わせを考えます。

また、署名用や暗号化用の鍵は別の設計が必要です。交換が既存のログイン状態や暗号化済みデータへ影響する場合があり、APIキーの手順をそのまま流用しません。

替えたか、ではなく届いたか

保存先の更新、新しい実行の成功、旧キーの失効。その3つをつなぐと、翌朝の処理まで見渡せます。

APIキーの置き場所、外部サービスが止まったとき、漏えい時の対応も合わせて確認してください。

一次資料と参考記事

情報確認日:2026年10月24日。クラウドの読込仕様、発行元の失効方法、権限や併用の可否は、利用中のサービスの公式資料で再確認してください。

書いた人

マーケティングの現場から、AIをつくり、仕事で使う側へ。実際に試したことや、つまずいたことを、図解と具体例で伝えています。

この記事のURL:https://nekoai-lab.github.io/ai-security-playbook/learn/secret-rotation/

続けて読む

シリーズ · 全14記事のうち5記事目

次に読む自分の画面が正しく見える、その先へ。本人・他人・未ログインの結果で、認可と添付・共有の境界を理解する。
読む順番・ルートを見るAIで作って公開する基本
  1. AIに渡す情報を、送る前に分ける
  2. 「学習しない」AIなら、仕事の個人情報を使える?
  3. AIで作ったアプリの、動く場所を知る
  4. AIに「APIキーを設定して」と言われた。どこに入れるのが正解?
  5. APIキーを替えたのに、古いキーが使われている?
  6. ログインと、データを使う権限を分ける
  7. 公開したのは、本当に見せたいファイルだけ?
  8. コードには書いていない。名前やメールは、どこから公開される?
  9. 緑のチェックが付いた。その変更を公開していい?
  10. AIレビューが合格した。その結果を、どこまで信じていい?
  11. AIにデプロイを頼んだ。その認証情報は、どこまでできる?
  12. AIで作ったサービスを、公開する前に確かめる
  13. 外部サービスが止まったら、自分のアプリはどうなる?
  14. 漏えい・異常・消失に気づいたとき、最初にすること

APIキー・会話・データの教材へ戻る →