◉CLAUDE LABEN
●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました●2.1.301 — vim の % モーション、VS Code パネルでの LaTeX 数式表示、使用量上限待ちのリトライ監視の上限が入りました(10/15)●2.1.299 — 200K トークン超で約54分放置した会話はアイドル圧縮。MCP の許可ルールは名指ししたサーバーだけに一致します●SONNET 4.5 — Claude API での提供終了は 11/30、残り45日。移行先は Sonnet 5.5●WINDOWS — 日本語の環境でだけフックが黙って壊れる報告があり、文字コードの確認が呼びかけられています●FAST MODE — Opus 5.5 の Fast mode がリサーチプレビューを終え、ベータヘッダーが不要になりました(10/15)●NEW — Cowork に渡したフォルダの先頭に、十行の約束ファイルを置いてみました
記事一覧/API & SDK
⬡ API & SDK/2026-07-12中級

APIキーに有効期限を付けると、失効は事故ではなく予定になる — 無人運用の鍵カレンダー設計

Console で APIキーに有効期限を設定できるようになりました。無人で回している夜間ジョブを止めないために、二重鍵の重ね替えとローカルの失効台帳で「予定された失効」を運用に組み込む方法をまとめます。

Claude API127APIキー自動運用17セキュリティ21個人開発130

ある朝、個人開発で回している複数サイトの夜間ジョブのうち一本だけがログに 401 を残して止まっていました。原因は単純で、以前ワークスペースを整理したときに古いキーを削除し、片方のジョブだけ差し替え忘れていた、というものでした。手で消したキーは、いつ、どのジョブが使っていたのかを後から思い出しにくいものです。

Console で APIキー・Admin APIキーに有効期限を設定できるようになりました。プリセット・任意の日付・無期限から選べ、7日以上のキーは失効前にメールで知らせてくれます。無人でモデルに処理を委ねている私自身の立場からすると、これは「鍵がいつか静かに切れる」という不安を、「この日に切れると分かっている」という予定に変えてくれる変更です。ただし、期限付きのキーは設計を誤ると、予定どおりに夜間ジョブを止めてしまいます。失効を事故ではなく予定として扱うための運用を、順を追ってまとめていきます。

有効期限は「いつか切れる不安」を「切れる日付」に変える

これまで APIキーは、自分か管理者が明示的に削除しない限り生き続けました。安心なようでいて、実際には「どのキーが古いのか」「もう使っていないキーが放置されていないか」を人間の記憶に頼る状態でした。放置された古いキーは、漏れたときの被害を大きくします。

有効期限を付けると、この関係が反転します。キーは決めた日付で必ず失効し、7日以上先に設定したキーは期限が近づくとメールで通知が届きます。つまり「気づいたら切れていた」ではなく「あと7日で切れると事前に分かる」状態になります。

一方で、無人運用では通知だけに頼るのは危ういという現実もあります。通知メールを見落とせば、期限当日にジョブが 401 で止まります。失効を安全に扱うには、通知を受け取る仕組みと、切れる前に鍵を入れ替える仕組みの両方が必要です。

無人運用でありがちな失敗は「単一キーの一発差し替え」

いちばん壊れやすいのは、本番で使っているキーを1本だけ持ち、期限が来たら新しいキーを作って古いキーを消す、という一発差し替えです。この方式には切れ目があります。古いキーを消してから新しいキーを環境変数へ反映するまでの数分間、あるいは反映を忘れた区間で、ジョブは認証に失敗します。

夜間の自動実行では、この数分の切れ目が「その日の処理がまるごと落ちる」ことに直結します。しかも失敗は静かで、翌朝ログを見るまで気づけません。認証エラーそのものの切り分けはClaude API 認証エラー 401 Invalid API Key の原因と解決方法で扱っていますが、有効期限の運用では「そもそも切れ目を作らない」ことが主眼になります。

二重鍵の重ね替えで切れ目をなくす

切れ目をなくす基本は、常に有効なキーを2本持つことです。片方が現役、もう片方が次の世代の準備、という形にします。

手順はこうです。まず現役キー(key-A)が期限の7日前になり通知が届いたら、新しいキー(key-B)を発行します。key-B にも同じように有効期限を付けます。次に、環境変数やシークレットストアの参照先を key-B へ切り替え、夜間ジョブを1回走らせて 200 が返ることを確認します。ここまでで key-A はまだ生きているので、切り替えに失敗しても key-A へ戻せます。最後に、key-B での稼働を1〜2日見届けてから key-A を無効化します。

この「重ねてから外す」順序が肝心です。先に古いキーを消してしまうと、二重鍵の意味がなくなります。スコープを絞ったローテーション設計そのものは漏洩しても請求が膨らむ前に止める — 無人パイプラインのAPIキー被害半径設計でも触れています。有効期限は、そのローテーションに「いつやるか」という締め切りを与えてくれる仕組みだと捉えると腑に落ちます。

Console の通知を待たず、ジョブ自身に失効を見張らせる

通知メールは便利ですが、受け取るのは人間です。人間が見落とす前提で、夜間ジョブ自身に「自分が使っているキーの残り日数」を確認させておくと安心です。

やり方は素朴で、キーを発行したときに、そのキーのラベルと有効期限日をローカルの台帳へ書いておき、毎晩ジョブの先頭で残り日数を計算するだけです。Console の API はキーの秘密値を後から返しませんが、期限日は自分で記録できます。

import json
from datetime import date, datetime
from pathlib import Path
 
LEDGER = Path.home() / ".claude_key_ledger.json"
WARN_DAYS = 10  # Console の7日通知より前に自分でも気づくための余白
 
def check_key_expiry(active_label: str) -> None:
    """夜間ジョブの先頭で呼ぶ。残り日数が閾値を切ったら警告を出す。"""
    if not LEDGER.exists():
        print("[key-check] 台帳がありません。キー発行時に expires_at を記録してください")
        return
 
    ledger = json.loads(LEDGER.read_text())
    entry = ledger.get(active_label)
    if not entry:
        print(f"[key-check] ラベル {active_label} が台帳に未登録です")
        return
 
    expires = datetime.strptime(entry["expires_at"], "%Y-%m-%d").date()
    remaining = (expires - date.today()).days
 
    if remaining < 0:
        raise SystemExit(f"[key-check] {active_label} は {abs(remaining)} 日前に失効しています。停止します")
    if remaining <= WARN_DAYS:
        print(f"[key-check] 警告: {active_label} はあと {remaining} 日で失効します。次世代キーを準備してください")
    else:
        print(f"[key-check] {active_label} は残り {remaining} 日。問題ありません")
 
# 台帳の例(キー発行時に追記する)
# {
#   "prod-nightly-2026-07": {"expires_at": "2026-10-10", "note": "夜間4サイト用"}
# }
 
if __name__ == "__main__":
    check_key_expiry("prod-nightly-2026-07")

このスクリプトを夜間ジョブの最初のステップに置くと、Console のメール通知を見落としても、ログに残り日数が毎晩記録されます。閾値(WARN_DAYS)を Console の7日通知より前に置いているのは、人間が動ける余白を自分の側でも確保するためです。すでに失効していれば処理を止め、盲目的に 401 を量産しないようにしています。

どの期限を選ぶか — 用途別の目安

有効期限の長さは、キーの用途と差し替えの手間で決めます。短くするほど漏洩時の生存期間は縮みますが、重ね替えの頻度は上がります。私の場合の目安を挙げておきます。

用途期限の目安考え方
本番の夜間バッチ60〜90日四半期に一度の重ね替えなら手が回る。通知+台帳で二重に監視する
検証・実験用7〜30日使い終わったら放置されがち。短くして自動的に片づける
CI・一時的な自動化可能なら無期限を避けるキーそのものをやめて鍵なし方式に寄せる選択肢がある
手元の対話・下書き用30〜60日個人利用でも定期的に入れ替える習慣をつける

CI や一時的な自動化については、そもそも長命の静的キーを持たない方向も検討に値します。発行のたびに短命の資格情報へ寄せる考え方はClaude API の静的キーをやめる — Workload Identity Federation で CI と本番を鍵なしに切り替えるにまとめています。有効期限は静的キーを使い続ける場合の安全弁、鍵なし方式はキーそのものを減らす一手、と役割が分かれます。

まとめ — 次の一歩

有効期限は、鍵を「いつか切れるかもしれない不安の種」から「切れる日付が決まった管理対象」へ変えてくれます。ただし通知を受け取るのは人間なので、無人運用では二重鍵の重ね替えとローカルの失効台帳をあわせて用意しておくと、夜間ジョブを止めずに済みます。

まず一歩として、いま本番で使っているキーに期限を付け、その期限日を台帳へ書き、上のスクリプトを夜間ジョブの先頭に足してみてください。次にキーを更新するときには、消す前に重ねる順序を試せます。小さな仕込みですが、ある朝ログに 401 だけが残る、あの静かな失敗を減らせます。実運用の参考になれば幸いです。

シェア

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

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

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

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

関連記事

⬡ API & SDK2026-09-17
画像は20枚ずつ送っています — 21枚目から全画像に別の上限がかかると知った日
素材フォルダの62枚を一度に送ったら invalid_request_error で落ちました。容量ではなく枚数が原因です。視覚トークンを28pxのパッチで数え直し、枚数・寸法・ペイロードの3つの上限を同時に見てバッチを組むまでの記録です。
⬡ API & SDK2026-09-06
訳文は自然なのに、実行時に落ちる翻訳がありました
多言語アプリの文言を Claude API で訳したとき、意味は正しいのに書式指定子だけが壊れることがあります。重大度で分けた受け入れ検査と、壊れた行だけを訳し直す修復ループを実装と実測でまとめました。
⬡ API & SDK2026-05-15
壁紙アプリの一括カテゴリ分類を Claude Vision API で自動化した話 — 実運用で見えた精度と限界
個人開発の壁紙アプリで画像のカテゴリ分類をClaude Vision APIに任せた実体験の記録です。SonnetとHaikuのモデル選択、75枚の手動検証で確かめた分類精度、実運用で踏んだ落とし穴、途中で落ちても再開できるバッチ設計、そして実際にかかったコストの感覚まで正直に書きました。