/var/www/yatta47.log

/var/www/yatta47.log

やったのログ置場です。スクラップみたいな短編が多いかと。

GCP OAuth の refresh_token が7日で切れる原因と対処法(テストモードの罠)

MCPサーバー(GA4、Search Console)の認証が7日おきに壊れる、という問題に遭遇しました。

エラーは invalid_grant。原因を調べていくと、GCPのOAuth同意画面が「テストモード」のままになっていたせいでした。

何が起きたか

MCP連携で使っているGA4とSearch ConsoleのAPIが、ある日突然401エラーになったんですよ。エラーメッセージはこれです。

{"error": "invalid_grant", "error_description": "Token has been expired or revoked."}

再認証すれば直ります。でもしばらくすると同じエラーが出る。

「refresh_tokenってそんなすぐ切れるもの?」と調べ始めて、7日という数字に気づきました。

原因

犯人はGCPのOAuth同意画面の「テストモード」でした。

GCPでOAuthを設定するとき、同意画面の「公開ステータス」がデフォルトで「テスト」になります。このテストモードには、refresh_tokenが7日で失効するという制限がある。

本番モード(「本番環境」ステータス)だと、refresh_tokenは6ヶ月間使用がなければ失効という挙動に変わります。個人利用なら実質ほぼ永続的に使えます。

条件はこの3つが重なったとき:

  • ユーザーの種類が「外部」
  • 公開ステータスが「テスト」
  • スコープがname/email/profile以外(GA4やSearch ConsoleのAPIスコープを含む場合)

Googleの「内部」ユーザータイプはGoogle Workspace契約者向けなので、個人アカウントでは選べません。外部+テストモードの組み合わせが一番ハマりやすい状況です。

対策

GCPコンソールのOAuth同意画面を「本番環境」に切り替えます。

  1. GCPコンソール → Google Auth PlatformAudience(旧UI: APIとサービス → OAuth同意画面)
  2. 「アプリを公開」ボタンをクリック
  3. 確認ダイアログで承認
  4. 公開ステータスが「本番環境」に変わったことを確認
変更前: 公開ステータス → テスト
変更後: 公開ステータス → 本番環境

「アプリの公開」という言葉の響きが怖いですが、個人利用であればGoogle のverification(審査)は不要です。「未確認のアプリ」という警告は出ますが、クリックスルーで進めます。この警告と7日失効は別の問題で、公開にすれば7日制限はなくなります。

切り替えた後は再認証が必要です。テストモードで取得したトークンは7日で失効するので、切り替え後に認証フローを通して新しいrefresh_tokenを取得し直します。

なぜ気づきにくいか

この罠がやっかいなのは、設定直後は何事もなく動くんですよ。

OAuthの設定が終わって疎通確認して、問題なく動いている。「よし、完了」となる。それから7日後に突然死ぬ。

設定作業とエラー発生のタイムラグが7日あるので、原因と結果が結びつきにくい。しかも invalid_grant のエラーだけ見ると「トークンを間違えてる?」とか「権限が変わった?」とか別の方向で調べ始めてしまう。

もう一つ、refresh_tokenの上限数にも注意が必要です。同一クライアントIDで発行できるrefresh_tokenは100件が上限で、超えると最も古いトークンから自動失効します。テストモードで何度も再認証を繰り返していると積み上がるので、急にトークンが切れたらこの上限を超えていないか確認するといいです。

まとめ

GCP OAuthのrefresh_tokenが7日で切れる場合、OAuth同意画面のステータスが「テスト」になっているのが原因です。

「本番環境」に切り替えるだけで7日制限は解除されます。個人利用であれば verification は不要です。

OAuth設定をしたら、同意画面の公開ステータスを確認しておくとこの罠を踏まずに済みます。

参考