この記事は CyberAgent Developers Advent Calendar 2025 11日目の記事です。

はじめに

こんにちは、Amebaの認証チームでバックエンドエンジニアをしている佐藤(@Taka_input)です。

この記事では Amebaの認証刷新プロジェクトで最近行なったアクセストークン機能の刷新について紹介していこうと思います。

認証刷新プロジェクトとは

かつてAmebaでは、スマートフォン(SP)向けサービス群を共通IDで統合し、巨大なソーシャルグラフを構築する「デカグラフ構想」を掲げました。

SP市場への急速な適応と最適化を最優先するため、この構想下の認証基盤は、既存のAmeba(PC主体の基盤)とはあえて切り離された独立したシステムとして構築されました。その結果、ユーザー情報は既存Amebaデカグラフ(SP)で別々に管理される状態となりました。

その後、既存の資産を活かしつつ、早急な連携を実現するため、これら二つの異なる基盤を統合したデカグラフ認証基盤が誕生しました。これにより、1つの認証基盤ではありつつも実態は裏側でユーザー情報が二重管理され続けており、無理やり連携させている構造になっていました。

その結果以下のような課題が生じていました。

  • 運用課題: トランザクションの処理や整合性の確保が困難
  • UX課題: ログアウトしたはずなのに、片方のシステムからしかログアウトできていないなどのユーザー体験の悪化

これらの課題を解決するために立ち上げられたのが「認証刷新プロジェクト」です。 本プロジェクトの目的は、複雑化した「デカグラフ認証基盤への依存」を断ち切り、二重管理構造を解消することで、一つの新しいシステムへと移行することでした。

新認証認可システム「Ameba Connect」の概要

この刷新プロジェクトの一環として、新しい認証認可システム「Ameba Connect」が開発されました。Ameba Connectは、OpenID ConnectおよびOAuth 2.0に準拠した、Ameba内製のIdP(Identity Provider)です。

Ameba Connectのログイン画面
Ameba Connectのログイン画面

これまでのAmeba Connectは、アクセストークンの発行・管理において引き続きデカグラフのAPIに依存していました。今回のタスクの目的は、このアクセストークンに関するシステムを刷新し、デカグラフへの依存を完全に排除し運用負荷やその他課題を解決できることを目指しました。

刷新要件

アクセストークン機能の刷新では以下のエンドポイントが対象でした。

以下はAuthorization Code Flowの図で、赤枠の部分が刷新対象になります。

Authorization Code Flowの図。赤枠は今回の刷新対象エンドポイント

刷新の中で議論したことは様々あるのですが、今回はアクセストークンの形式を識別式型か内包型にするのかの議論についてピックアップしたいと思います。

トークン形式について

一般的にトークンの形式は大きく2種類あり、識別式型と内包型があります。

識別式型

UUIDやハッシュ値などのランダムな文字列をトークンとして扱います。IdPはトークンに紐づく情報(有効期限やスコープなど)をDBに登録します。

また、識別式型トークンは不透明なトークン(Opaque Token)とも呼ばれています。

内包型

トークン自体に紐づく情報を含めます。JWT(Json Web Token)が広く使われています。

デカグラフ認証基盤ではアクセストークンに識別型を用いていましたが、刷新後のシステムでは内包型のJWTの導入を検討しました。JWTにすることでトークン自体に有効期限などを含め、リソースサーバーのトークン検証リクエストを減らしIdPへの負荷が軽減されると考えたからです。

しかし、JWT形式での刷新を進める上でいくつかの障壁が発生しました。 

JWTによる課題

1. 既存システムとの互換性

先述した通り既存のアクセストークンは識別式型です。そのためJWT対応できるかの実装調査・対応のための追加実装が RP・リソースサーバー側で必要になることがわかりました。

調査の中で出た課題をいくつか紹介します。

  • アクセストークンの書式・文字列長チェック
    • JWTはヘッダー・ペイロード・署名をドット(.)で繋げているため従来の書式と違いが出る可能性がありました
    • JWT形式のアクセストークンは認可時の情報によって紐づく情報( clientID や認可scope など)が変化します。そのため固定長のアクセストークンを想定しているケースでは影響があります
  • アクセストークンをデータストアに保存
    • 一部のリソースサーバーはアクセストークンの有効期限をTTLにしてキャッシュすることでトークン検証リクエストを抑えていました。例えばキャッシュのためにMemcachedを使っていた場合、キャッシュキーは最大250文字です。先述の通りJWTのアクセストークンは可変長なので保存できない場合があります
    • 他にも 多くのブラウザはCookie1つにつき4096バイトの上限がありますし、RDSに固定長で保存している場合も懸念が必要でした

2. JWTクレーム

JWTを採用する場合、JWTクレームに何を入れるべきか、そしてその値をDBなどで管理できているのかを事前に精査することをお勧めします。

RFC9068 にはJWT型のアクセストークンに関する仕様が定まっており、最初はその内容を参考に進めました。確認していく中で aud (audience) クレームに関する課題に直面しました。

RFC9068によるとaudクレームは必須です。またこのクレームはJWTの利用が想定されている主体の識別子が入るため、アクセストークンとIDトークンでは入れるべき値が異なります。

  • IDトークン
    • RPがユーザー認証を確認するのに使用するため、RPの識別子(clientID)が入ります
  • アクセストークン
    • RPは受け取ったトークンをリソースサーバーにそのまま渡し、リソースサーバーがトークンの検証を行うためリソースサーバーの識別子が入ります

Ameba Connectでは現状リソースサーバーの識別子(URLなど)を保持しておらず値を埋めることが難しいことが後になってわかりました。

ただしこちらの記事でも紹介されていますが、RFC9068はいくつか問題を抱えていることがわかっており、あくまで参考程度に考えておくのが良さそうです。

3. 無効化の検知

トークンが無効化されるのはトークンの有効期限が切れた時だけではありません。

例えば、ユーザーがパスワードを変更やログアウト、そしてトークンが漏洩した際は無効化されるケースがあります。JWTには有効期限クレーム(exp)がありますが、クレームを検証するだけでは例に上げた無効化イベントを検知することができないのです。

この課題に対し、いくつかの対策を検討しました。

  1. アクセストークンの有効期限を短くする: トークンが無効化された後も使われ続けるリスクを減らすため、トークン自体の有効期限を短く設定する方法です。しかし、これはユーザーの利便性を損なう可能性があり、根本的な解決にはなりません。
  2. クリティカルなリソースサーバーでの都度検証: 課金システムのような、常に有効なアクセストークンを扱う必要があるクリティカルなリソースサーバーの場合トークンイントロスペクションエンドポイントを都度呼び出してもらい、トークンの有効性を確認することを考えました。

ですがJWTの最大のメリットは、リソースサーバーがIdPに問い合わせることなく、トークン検証を完結できる点にあります。都度イントロスペクションエンドポイントを叩いてしまうと、このJWTのメリットが失われ、パフォーマンス向上の効果がなくなってしまいます。

4. 対応工数

これが一番大きな課題でした。先述した課題の通り、JWT対応をする場合はRP・リソースサーバーの実装確認と追加実装が必要不可欠です。

Amebaは2024年に20周年を迎えており、Ameba Connectを使用しているRPは運用フェーズのものも多いです。そのため実装に詳しい担当者が不在のケースも多々あります。特に認証はコア機能のため変更を加えるとなると確認工数もかなりかかることが見込まれました。

そしてJWTにすることで大きなメリットを享受できるのはリソースサーバーとIdPであり、RP側の対応へのモチベーションを上げづらいです。

課題を踏まえて

これらの課題を総合的に検討した結果、プロジェクトの最優先事項である「デカグラフ依存の解消」を早期に達成するため、アクセストークンの形式として識別式型を継続して採用するという決断を下しました。

識別式型を継続することで、RPやリソースサーバー側の大幅な改修を回避でき、デカグラフのAPI呼び出しを新しいAmeba ConnectのAPIへと置き換える作業に集中できました。これにより、複雑な技術的負債の解消という本来の目標を、現実的なスケジュールで達成できました。

エンドポイントを/v2/に切り出す案もありましたが、全てのRPとリソースサーバー側でエンドポイントの向き先変更が必要になるのと、認証基盤の刷新スケジュールが各プロダクトの移行スケジュールに完全に依存してしまいコントロールが難しくなる可能性がありました。デカグラフの早期脱出が最優先だったためこの案は見送り既存のエンドポイントで実現することにしました。

アクセストークン刷新を終えて

アクセストークン刷新が完了したことで、トークンに依存していたデカグラフのAPI依存からも脱却することができました。現在ではデカグラフAPIの依存から完全に脱却することができ認証刷新プロジェクトの目標の1つを達成することができました🎉

しかしながらまだ課題は残っており引き続き認証刷新プロジェクトは継続していく予定です。今後も滑らかな認証体験を追求すべくAmeba Connectの改善を行なっていこうと思います!

まとめ

今回の刷新ではスケジュールの都合や既存仕様との兼ね合いから識別子型を選択しましたが、これから新規に認証基盤を作る、あるいは制約の少ない環境であれば、課題を認識しつつJWTを採用するのはアリだと思います。

また今回弊社で議題に上がった課題のみを取り上げていますが、アクセストークンの形式に関する包括的な内容はこちらの記事が非常に勉強になるため興味がある方は一読をお勧めします。

アクセストークンの実装を検討する際に、この記事の実例が少しでも参考になれば嬉しいです。最後まで読んでいただきありがとうございました!