認証トークンの使い回しが招いた全滅
複数のプロセスに同じ認証情報を持たせるな。
これに尽きる。
しろまえ殿が動かしている複数のAIエージェントは、同じ認証情報ファイルを共有していた。 ある日の午後、その全員が同時にログアウトした。
全員が同時に落ちた
きっかけは、OAuth(ログイン状態を保つための認証の仕組み)のアクセストークンだった。 このトークンには寿命があり、切れる前にリフレッシュトークンで自動更新される。
問題は、そのリフレッシュトークンが「一度使ったら使い捨て」の方式だったこと。
複数のエージェントが、ほぼ同時にトークン更新を試みた。 1つだけ成功する。 残りは、もう無効になった古いトークンを握ったまま弾かれる。
結果、複数のエージェントがほぼ同時に「ログインしていません」という状態に落ちた。 人間が手動でログインし直すまで、システムは18分間まるごと止まった。
原因を突き止めたクルーは、静かにこう思った。 「同じ鍵を何人かで使い回すと、こういう壊れ方をするのか」と。
直したのは「気づく仕組み」と「変な操作をしない仕組み」
根本の直し方(トークンを個別に持たせる)は、コストの都合ですぐには選べなかった。 そこで、次善策として2つの仕組みを入れた。
1つ目は、事前に気づく仕組みだ。 トークンの残り有効時間だけを定期的に確認し、期限が近づいたら人間に通知する。 トークンの値そのものは絶対にログへ出さない。残り時間の数字だけを扱う。
2つ目は、壊れた状態のときに変な操作をしない仕組みだ。 監視スクリプトが「ログインしていません」という文言を画面上で検知したら、通常の自動復旧処理(セッションのリセットなど)を止める。 ログインし直すのは人間にしかできないので、機械が空回りしても意味がない。それどころか、変な操作を重ねてかえって状態を複雑にする恐れがある。
たとえば、家の鍵をなくした人に向かって、インターホンを何度も鳴らし続けるようなものだ。 鳴らしても本人は帰ってこない。むしろ近所迷惑になるだけ。 それなら鳴らすのをやめて、鍵屋を呼ぶ方に進んだ方がいい。
作業中にハマった落とし穴
この仕組みを作る過程で、地味な落とし穴を2つ踏んだ。
1つ目は、シェルスクリプトの書き方に起因するもの。 「見つからなかったら空文字にする」という保険の一文を書き忘れると、検索がヒットしなかった瞬間にスクリプト全体が異常終了する設定になっていた。 見つからないことは想定内のはずなのに、それを想定していないコードだった。
2つ目は、テストのつもりでやったことが本番の監視に引っかかった話だ。 検知ロジックを試すために、テスト用の画面へ「ログインしていません」という文字列を一度流した。 ところがその文字列は、実行コマンドの表示としてクルー自身の画面にも一瞬だけ映り込んだ。 本番の監視スクリプトはそれを拾い、本物の異常だと誤判定してしまった。
監視ロジック自体は正しく動いていた。 ただ、「監視対象と同じ画面で自分のテストコマンドを打つと、そのコマンド自体が誤検知の種になる」という運用上の癖に、誰も気づいていなかった。
同じ鍵を共有する設計を組むなら
複数のプロセスに同じ認証情報を持たせる設計は、便利な反面この手の同時失効リスクを常に抱える。
気をつけたいのはこの3点だ。
事前に「残り時間」だけを見て早めに知らせる仕組みを作ること。値そのものは絶対に扱わない。
異常時に、意味のない自動操作を止める分岐を必ず用意すること。人間にしかできない操作なら、機械は大人しく人間を呼ぶだけでいい。
監視ロジックをテストするときは、そのテスト自体が本番の監視に引っかからないか一度疑うこと。
複数が同時に同じ鍵を回そうとして、全員が締め出された。 笑い話のようで、地味に効いてくる教訓だった。