🚥

マイクロサービス間通信における認証認可およびアクセス制御

2023/12/05に公開

はじめに

2023年4月に基盤エンジニアとして Ubie に入社しました nerocrux です。主に Ubie の ID 基盤の開発と保守運用を担当しています。
この記事は、2023 Ubie Engineers アドベントカレンダー 5 日目の記事となります。

Ubie では、モジュラモノリスを採用しつつ、マイクロサービスアーキテクチャも採用しており、領域によってサービスを分けて、それぞれの担当チームが開発と保守運用をしています。
クライアントから一つのリクエストを受け取ったあとに、Ubie のバックエンドではリクエストを受け取ったサービスだけがそのリクエストを処理することもあれば、別のサービスにディスパッチし、複数のサービスがひとつのリクエストを処理して結果を返すこともあります。

マイクロサービス間の通信が Ubie の内部で発生したとしても、必ずしも無制限で自由に行われていいわけではないです。
Ubie ではお客様から大事な問診情報等の個人データを扱っており、個人や医療機関向けにサービスを展開しています。秘匿性の高いデータやサービスの健全性を影響する機能に対して、従業員や外部からのアクセスを制限することはもちろん、Ubie 基盤内部からアクセスできるサービスを必要最小限に制限することも、Ubie のシステムを守る一つ重要なポイントだとと考えています。
またサービスを保守しているチームとしては、自分の担当サービスの安定運用を保証する、またクリティカルな機能を不用意に誤って実行されてしまうような事故を防ぐためでも、アクセスの正当性を検証できるための仕組みが必要でした。

本記事では、このような背景のもとに Ubie 社が採用した、社内サービス間通信をセキュアにするための認証認可およびアクセス制御の取り組みを紹介します。

認証認可とアクセス制御

本編に入る前にまずは認証認可とアクセス制御の話を少ししたいと思います。

近年、ゼロトラストとともに「Identity is the new perimeter」という考え方が広がっており、認証認可や OAuth といったキーワードがそれなりに認知されたと思います。
Web サービスの開発者は、サービス提供にあたって、サービスが保持しているリソースを守るために、インフラ上の防衛措置に加えて、認証認可の仕組みを必要不可欠な要素の一つとして導入しています。

Web サービスは利用者に対して、まず「認証」の仕組みを通して、利用者の本人確認を実施します。利用者の「アイデンティティ」を確認した後に、サービスは「認可」の仕組みを通して、該当ユーザーはどのようなリソースにアクセスできるかを決定します。
この一連の動作が終わった後に、サービスがユーザー(が操作しているクライアント)に対して、ユーザー(およびクライアント)の権限情報が含まれる「アクセストークン」を発行します。ユーザーは「アクセストークン」をもって、権限範囲内のリソースにアクセスして、Web サービスを利用します。

認証認可のフローには、「ユーザー」「ユーザーが操作するクライアント」「リソース」等、様々な参加者が存在するため、動作が複雑であるものの、OpenID Connect や OAuth 2 といったプロトコルによって標準化されており、長年にわたって様々なサービスにて運用されました。そのため、OpenID Connect や OAuth 2 を利用して認証認可を設計・実装するためのベストプラクティスが数多く出ており、エンジニアとしては比較的安全に自分のプロダクトに導入できると考えます。

しかし Web サービスの実装者にとっては、認証認可を実装できたら終わりではありません。ユーザー/クライアントに対しての権限付与は認可の責務であるが、実際クライアントから API へリクエストを送った際に、リソース側が何もしないわけではなく、リクエストに含まれた認可情報(アクセストークン)のもとに、API コールを許可して処理を行うか、それとも拒否するかを正しく判断する必要があります。この処理を本文では アクセス制御(英語で Enforcement)と呼んでます。

Web サービスを提供する各社が採用する技術スタック、インフラ構成やアーキテクチャ等が大きく異なりますし、アクセス制御はあくまでも Web サービス内部的な話のため、アクセス制御に関するベストプラクティス的なものが少なく感じます。
OAuth 2 で発行したアクセストークンを根拠にしてリソース側で制御する場合、トークンにどのような情報を含めれば、リソース側で精緻にアクセス制御を実施できるかは、自社の状況に応じて考えなければなりません。
よく見るパターンでは、アクセストークンに「Scope」というパラメータを含めて、リソース側は「自分にアクセスするために○○ Scope が必要」のルールを作って、

  • アクセストークンが有効であること
  • アクセストークンに「○○」Scope が含まれていること
    の 2 点を確認した上で、アクセスを許可します。

もちろんトークンに含める情報は、必ずしも「Scope」のみである必要がなく、ほかにも様々な情報を含めて、リソース側のアクセス制御の根拠にすることが可能です。ただし含める情報が多ければ多いほど、制御の精度が高くなるものの、認可サーバーおよびリソースサーバーの実装負担と難易度が上がると考えます。

マイクロサービスアーキテクチャにおけるアクセス制御の難しさ

マイクロサービスアーキテクチャを採用したシステムでは、各サービスが正しくアクセス制御を実施できる状態を作るのが難しく感じます。

モノリシックなサービスの場合、外向けの API と、その API が触れるリソースは一元的に実装・管理されているため、どの API がどのリソースを触れるか、その API (リソース)にアクセスするためにどのような権限が必要かは比較的に設計しやすいと思います。
またリクエストに付随しているアクセストークンに対して、検証および情報取得は1 回のみ実施すれば、サービス内すべての API がその結果を得られるため、API の実装者は比較的容易にアクセス制御を実装できると考えます。

一方で、マイクロサービスアーキテクチャにおいては、外向けの API を提供するマイクロサービスがすべてのリソースを持っているわけではなく、リソースは複数のマイクロサービスに分散されています。ひとつのリクエストを処理するため、複数のマイクロサービス間で通信が発生し、処理を行い、結果をまとめて返すシナリオが多々あります。

リソースを持つマイクロサービスは、自分が持つリソースを責任もって守るため、内部通信であっても、アクセス元から様々なコンテキスト情報を要求して、アクセス制限を行う必要があります。
外向けに API を提供するマイクロサービスでは、アクセストークンをもとにアクセス制御を実施可能ですが、内部通信が発生する場合、通信経路上のすべてのマイクロサービスが正しくアクセス制御を行えるよう、アクセストークンに含まれている情報 + α を伝搬していく必要があると考えています。

このあたりの仕様策定は、すべてのマイクロサービスに利用されるため、サービス間通信で利用されるプロトコルや各マイクロサービスの実装言語を考慮して、実現可能性を評価する必要があります。
また、各マイクロサービスに実装していただくものとなりますので、Developer Experience を考慮し、実装を容易にするためのツールを提供する必要もあると考えます。

Ubie の取り組み

Ubie の現状

前述のとおり、Ubie は現在マイクロサービスアーキテクチャを採択しており、マイクロサービスの数はそれほど多いわけではないですが、二桁はいっていると思われます。

マイクロサービスは基本的に GCP (GKE)上で動作しています。開発言語はこれから Go と Typescript(Nodejs)に統一する方針になりましたが、以前開発されたもののなかで Kotlin や Ruby で作られたものも存在している状況です。

なお、サービス間通信に使われるプロトコルは、HTTP と gRPC が混在しています(最近では GraphQL に統一したい動きが出てきました、これについては後述)。

CIAM (顧客 ID とアクセス管理)

Ubie では、症状検索エンジン Ubie やスマホ問診等、社内の C 向けプロダクト用に独自で OpenID Connect / OAuth 2 準拠の認証認可基盤を開発しています。この認証基盤は Orthrus と名付けられています。

例えばユーザーが症状検索エンジン Ubie (以降、ユビー と呼びます)にサインインしようとする際、ユーザーはまず Orthrus にリダイレクトされ、Orthrus 上で認証認可を行ったあとユビーに戻ると同時に、該当ユーザーのアクセストークンがユビーに発行されます。

この仕組みは現在社内向けのいくつかのプロダクトにしか利用されていませんが、今後事業の成長に応じて、社外の Web サービスと ID 連携が必要な場合でも利用できるように考慮されています。

EIAM(従業員 ID とアクセス管理)

従業員の ID とアクセス管理基盤として、Ubie では Azure AD を利用しています。
Azure AD は社内で利用する SaaS との連携はもちろん、自前で開発している各種管理ツールへのシングルサインオンにも利用されます(※)。

従業員が自分の社員アカウントを利用して管理ツールにサインインした後に、職種等に応じて権限が付与されたアクセストークンを Azure AD から取得して、そのトークンを使って社内各マイクロサービスのリソースにアクセスします。

Azure AD では、Microsoft Graph API 等 Microsoft のシステム上に管理されている従業員のリソースにアクセスする目的ではなく、自前の API を保護する目的で 検証可能な JWT 形式のアクセストークン を OAuth 2 プロトコルで発行する機能も提供していますし、アクセストークンを細かくカスタマイズすることが可能になっています。
例えば、従業員が所属するグループなどの属性情報や、従業員に付与するアプリロールの情報をアクセストークンに組み込むことが可能となっています。
このような機能を利用することで、ABAC もしくは RBAC でアクセス制御の仕組みを設計することが可能です。

※ Ubie 社内では数多くの管理ツールを運用しており、現時点ではすべての管理ツールが Azure AD を利用してシングルサインオンおよび権限管理を利用しているわけではなく、管理画面ごとに独自で認証と権限管理の仕組みを開発しているところもあります。今後、Azure AD のカスタマイズ性の高いトークンを活用するため、できる限り自前の仕組みから Azure AD に統合したいと考えています。

Ubie におけるアクセス制御の仕組み

Ubie のシステムは GCP 上で動作しており、元々 Istio の Authorization Policy を利用してサービス間の通信を制限する、最低限の仕組みしかありませんでした。ビジネスの成長とともに、マイクロサービス側はできればアプリケーション層で、より細かくアクセスを制約できるようにしたいという要件がありました。

このような要望に対して、マイクロサービス間通信する際に、Ubie が信頼する ID 管理システムが認証認可のもとで発行したトークンを根拠に、アクセス制御を行えるようにしました。

アクセス制御に利用する根拠としては、主に 2 つあります。

  • アクセス元となるユーザーおよびクライアントに関連する情報
    • ユーザー情報とは、ユーザー ID、ユーザーの性質(顧客なのか、従業員なのか)、従業員であればその従業員のロールや権限、そして認証手段や時刻などの情報
    • クライアント情報とは、ユーザーが操作しているクライアントの一意的識別子(症状検索エンジン ユビーなのか、スマホ問診なのか、管理ツールの場合はどの管理ツールか等)
  • アクセス元となるサービスの一意識別子

前者については、ユーザーが利用する CIAM / EIAM が発行したユーザーコンテキストのアクセストークンを利用しています。
後者については、弊社の全サービスは GCP 上で動作しているため、Google が発行する、サービスのアイデンティティを示す Google ID Token を利用しています。

それぞれについてもう少し詳しく説明します。

ユーザーコンテキストのアクセストークン

Ubie では、主に以下 2 種類のユーザーコンテキストのアクセストークンを利用しています。

  • 顧客向けの Orthrus が発行しているアクセストークン
  • 従業員向けの Azure AD が発行しているアクセストークン

クライアントからの API コールを処理するために、複数のマイクロサービスにリクエストが経由する場合、これらのアクセストークンをリクエストに入れることで、各マイクロサービスがアクセストークンの有効性を検証した上で、トークンに含まれるコンテキストを抽出すれば、アクセス制御を行うことが可能です。

ただし、素直にこの 2 種類のアクセストークンをそのまま流すことで、いくつかのデメリットがあります。

まず異なる ID 基盤が発行したアクセストークンの仕様が異なるため、取り扱う方法も異なります。全マイクロサービスにアクセストークンを区別してもらい、正しく取り扱ってもらうことは大変難しく考えます。

また、Ubie が利用する認可サーバー / トークンの種類をむやみに増やしませんが、ビジネス要件に応じて今後増える可能性がないとは言い切れません。

さらに、上記 2 種類のアクセストークンは、どちらも比較的長い有効期限を持つため、サービス間通信や特定のマイクロサービスの不適切な取扱いによって漏洩する際のセキュリティへの影響が深刻だと認識しています。認証基盤チームとしては全マイクロサービスがトークンを適切に取り扱っているかをモニタリングするには、それなりに大変な負荷になるため、できれば外部クライアント向けに発行したアクセストークンの流通範囲を狭めたい気持ちがあります。

これらの理由から、外部クライアント向けに発行したアクセストークンの情報をサービス間で安全に伝搬する目的で、Internal Access Token (IAT)と呼ぶ新しいトークンを作りました。

IAT は JWT 形式のもので、Orthrus が作成し非対称暗号方式で署名しています(トークン検証用に、内部向けに公開鍵を jwks endpoint で公開します)。

外向けに API を公開しているマイクロサービスが、受け取ったリクエストに含まれているアクセストークン(Orthrus もしくは Azure AD が発行したもの)を Orthrus に送信しますと、Orthrus が受信したトークンの有効性を検証した上で、そのトークンに含まれる情報を IAT の payload に入れて、IAT を署名します。
IAT の Payload に、主に以下のようなクレームを設けています。

  • jti: IAT の一意的識別子、UUIDv4。
  • sub: アクセス元の一意的識別子。ユーザーのアカウント ID 等。
  • iss: トークン発行者の Orthrus であることを示す文字列。環境ごとに異なる。
  • subject_type: subject の種別を示す文字列。Orthrus ユーザーなら orthrus_user、従業員なら employee
  • auth_issuer: 元となるアクセストークンの発行者。Orthrus アクセストークンであれば、Orthrus の URL。Azure AD アクセストークンであれば、そのトークンを発行する Azure AD テナントの URL。
  • auth_client: 現在取り扱っている元となるアクセストークンは、すべて OAuth 2 のアクセストークンであるため、OAuth 2 でいう Client ID の値がこのクレームに入る。ユーザーがどのクライアントを利用しているかを判断できるようになっている。
  • auth_scopes: auth_client と似たように、OAuth 2 アクセストークンの「scope」値がこのクレームに入る。

ちなみに IAT の aud (audience)クレームに値を入れていません。なぜならば 1 つの IAT は特定一つのマイクロサービスに利用されるわけではなく、リクエスト経路上のすべてのサービスに行き渡ります。
内部通信を開始するマイクロサービス(IAT を Orthrus から取得するサービス)も、IAT を発行する Orthrus としても、このリクエストはどのマイクロサービス上で利用されるか、リクエストの経路を完全に把握することが困難なため、audience を指定することが難しいです。
すべての API コールのリクエスト経路を判明できる仕組みを作れるならいいですが、今後 GraphQL の導入を含めて考えると、このような仕組みを運用する難易度とコストが高いと予想しているため、audience の不備によるリスクを理解した上で設定していません。

外部クライアントに発行したアクセストークンではなく、IAT というものを新たに作り、プラットフォーム内に流通させることによって、各サービスが IAT の仕様のみを取り扱えればよい形になりますので、実装が楽になります。なお認証基盤チームでは、各言語向けに IAT を取り扱うための開発ツールを提供しており、ツールを利用することでより簡単かつセキュアに IAT を取り扱うことができるようになっています。こちらについては Developer Experience について の節で説明します。

また、顧客もしくは従業員が操作するクライアントからのリクエスト(アクセストークンが含まれているリクエスト)を経由しているすべてのマイクロサービスに IAT が渡されるため、マイクロサービスがリクエストを送信する際に原則として IAT をリクエストに入れる必要があります。

サービスアイデンティティを示すトークン

場合によってマイクロサービスは自分が提供する API に対して、「特定のマイクロサービスしかアクセスできないように制限したい」という要望があります。もしくは監査目的で、「自分の API にどのマイクロサービスからのアクセスがあったか」を記録したい場合もあります。
サービスの「アイデンティティ」で制限を行う場合、Istio の AuthorizationPolicy を利用するのが手段の一つですが、アプリレイヤーでより柔軟に実装するため、Ubie では Google ID Token (以降 GIDT と呼びます)を利用しています。

Google は OpenID Connect によって ID Token を発行する仕組みを提供しています。GCE / GKE 上で動作しているマイクロサービスに関しては、Workload Identity を構成すれば、Google Metadata Service からプロジェクト内特定のサービスアカウントの ID Token を取得できます。この ID Token には、GCP 範囲で一意的な識別子(Email 形式のサービスアカウント名)が含まれており、マイクロサービスのアイデンティティを識別に利用できると考えています。
GIDT は JWT 形式のもので、Google の秘密鍵で署名されており、署名検証用の公開鍵はGoogle の jwks endpoint で公開されています。

GIDT を利用してアクセス制御を行う際に、主に以下二つのクレームを利用しています。

  • email: サービスアカウント名(Email 形式)。マイクロサービスの一意的な識別子として利用する。
  • aud: audience。トークン取得時に指定可能で、「このトークンの利用先マイクロサービスの識別子」として利用する。

通信元マイクロサービスは audience クレームの値を指定して、Google から GIDT を取得します。通信先マイクロサービスは GIDT を受信した後に、email および aud 値を検証します。

  • email クレーム値は「自分が許可しているマイクロサービスであるか」を確認します。
  • aud クレーム値は「自分自身」である場合以外にトークンを拒否します。これによって、トークンの悪用(GIDT を受け取ったサービスが他人の GIDT を別サービスになりすまして利用する)を防止することが可能になります。

GIDT に「送信元」と「利用先」を示す情報が含まれていますが、「送信元」じゃないところに盗まれたら、「送信元」として「利用先」に利用できてしまいます。そのため GIDT は機密性の高いトークンになりますので、取り扱う際に十分な注意が必要です。

GIDT は IAT と違って、クライアントが所持するトークンを内部用のトークンと変換する必要がないため、リクエストごとに新しいものを取得する必要がなくて、再利用可能です。

Developer Experience について

IAT と GIDT はどちらも JWT のため、正しく取り扱うことは簡単ではありません。
JWT の署名及び標準クレームの検証につきましては、独自で実装するのではなくライブラリに頼って実装することで、より安全かつ容易に実装できます。ただし社内すべてのマイクロサービスに各自でライブラリを選定して実装してもらうには、各チームに大きな負担となりますし、実装に差が出てしまう可能性があると考えています。
また、トークンに Ubie の用途にあわせて独自のクレームもありまして、アクセス制御する際にこれらのクレームを正しく利用するには難易度が高いと感じました。
このような背景から、IAT と GIDT を利用してアクセス制御のロジックを書きやすい開発ツールを社内全マイクロサービスに提供することにしました。

現在、開発ツールは HTTP / gRPC に対応しており、言語としては Go と Typescript (nodejs) のものを提供しています。
既存の Kotlin と Ruby で作られたマイクロサービスに関しては、基本的にこれらの言語のサービスが増えることないので、開発ツールを提供せずに実装する状況です。

開発ツールは、主に以下の機能を提供しています。

  1. リクエスト送信側向け
  • Orthrus / Azure AD アクセストークンを用いて Orthrus から IAT の取得
  • Google から Google ID Token の取得
  • IAT / GIDT をリクエスト header に追加する middleware
  1. リクエスト受信側向け
  • header から IAT や GIDT の取得し、有効性を検証する機能
  • 検証済みのトークンから各クレームの情報を抽出し、API 側がアクセスしやすい形にする機能
  • アクセス制御のロジックを容易に実装できる便利メソッド

現時点では、IAT / GIDT のクレームを利用してアクセス制御を行うには、基本的に API の中でロジックを自前で書く必要があります。開発者の負担を軽減するため、開発言語、通信プロトコル、フレームワークごとに、いくつかの便利なメソッドを提供しています。

例えば Nodejs のマイクロサービス(弊社では Nestjs フレームワークを利用してます)を対象に、Nestjs の Guards をカスタマイズしたものを提供しています。開発者は、アクセス制御のルールを定義し、Controller につける Guards に渡すことで、Guards が勝手にリクエストから IAT もしくは GIDT の有効性を検証した上でその中身を取り出し、定義されているルールに満たせるかを検証してくれます。

// Create two reflectors used for accessing execution context inside AuthGuard and ServiceIDGuard.
const reflectorAuthGuard = app.get<Reflector>(Reflector);
const reflectorServiceIDGuard = app.get<Reflector>(Reflector);

// Create orthrus client for validating IAT / GIDT.
// Note: orthrusURL is different in each environment.
const orthrusURL = "https://example.com";
const OrthrusClient = new Orthrus(orthrusURL);

app.useGlobalGuards(new AuthGuard(reflectorAuthGuard, OrthrusClient));
app.useGlobalGuards(new ServiceIDGuard(reflectorServiceIDGuard, OrthrusClient));

// Create guards.
const AuthGuard = NewAuthGuard();
const ServiceIDGuard = NewServiceIDGuard();

// Define authorization rule based on IAT claims.
const myAuthGuardRule = NewAuthRule("subject_type", [SubjectTypes.OrthrusUser, SubjectTypes.Employee], RuleValidators.Anyof);

// Define authorization rule based on GIDT claims.
// - email: array of the email address of the services you allow for this API
// - audience: the email address of your own service
const myServiceIDGuardRule = ServiceIdentityAuthRuleSet(["allowed-service-email@xxx.gserviceaccount.com"], "current-service-mail@xxx.gserviceaccount.com");

// Then in your controller, use both decorators to specify rules for both guards.
// In this way, "myAuthGuardRule" will be evaluated by "AuthGuard" and "myServiceIDGuardRule" will be evaluated by "ServiceIDGuard".
// The access will only be allowed only if BOTH rules satisfied.
@AuthGuard.Rules(myAuthGuardRule)
@ServiceIDGuard.Rules(myServiceIDGuardRule)
async say(request: SayRequest): Promise<SayResponse> {
  // controller logics

  return new SayResponse({
    sentence: "hoge",
  });
}

また、開発ツールではよく利用されるだろうと想定しているルールをいくつか用意しています。例えば subject_type = employee のユーザーからのアクセスのみを許可する、等。

@AuthGuard.Rules(EnsureSubjectTypeEmployee)
async say(request: SayRequest): Promise<SayResponse> {
  // controller logics

  return new SayResponse({
    sentence: "hoge",
  });
}

このような機能は Typescript / Nestjs のみならず、Go / chi 向けにも類似する機能を提供しています。

  1. テストの利便性を高めるための Mock 等の開発ツール
    そもそも JWT を作ることが難しいし、本物の IAT を取得してテストに使うのもあまり気持ちよくないので、Mock な IAT / GIDT を作る/検証するための機能をテスト用に SDK で提供しています。

今後の展望

中央集権式のアクセス権限管理

現在 Ubie では、API へのリクエストに対するアクセス制御のロジックは、各マイクロサービスに各自実装してもらっている状況です。つまり、NIST SP800-207 に定義している PDP (Policy Decision Point、ポリシーによってアクセスを許可するか拒否するかを判断するコンポネント) と PEP (Policy Enforcement Point、PDP の判断結果に応じて実際アクセスを許可すか拒否するかを実行するコンポネント) は、どちらも「各マイクロサービス」が担っている形になっていると認識しています。

今後ビジネスの成長に伴い、マイクロサービス間の依存関係が複雑になり、アクセス元の形態が多様化になることを想定しています。そのため、アクセス制御時に「このリクエストを通すべきか拒否すべきか」を判断するロジック(つまり PDP としての実装)がさらに複雑になる可能性があると考えます。

マイクロサービスの実装負荷を下げるため、PDP の役割を一つのマイクロサービスにまとめる、中央集権式の認可の仕組みの導入を検討し始めています。例えばマイクロサービスがリクエストを受け取ったときに、自分でアクセス許可すべきかを判断するのではなく、トークンが含まれるリクエストをアクセス制御のルール(ReBAC / RBAC / ABAC)を管理するマイクロサービスに問い合わせることで、そのリクエストを許可すべきかを判断してくれると、各マイクロサービスの実装が楽になるかもしれません。

そして近年、このような中央集権式の Fine-Grained Authorization SaaS がすでに増えている印象で、オンプレで構築できるプロトコルや OSS(OpenFGA、SpiceDB 等)も登場しています。

また、最近 OpenID Foundation でも AuthZEN という Working Group を立ち上げており、似たような分野で仕様を検討し始めている模様です。
すでに発行された draft の仕様では、PEP と PDP の間の通信仕様を標準化にしようとしている動きがあるようで、今後これは OpenID Connect とどのようにつないでいくかが楽しみですので、しばらく WG の動向を注目していきたいと思います。 https://github.com/openid/authzen/blob/main/api/authorization-api-1_0.md

このようなシステムの応用事例はまだ少ないと思いますし、うまく運用できるようになるまでのコストもそれなりに高いと予想していますが、Ubie としては今後少しずつ検証していきたいと考えています。

GraphQL 対応

Ubie ではマイクロサービス間の通信を GraphQL へシフトする議論が始まっています。そのため、GraphQL で通信する際のアクセス制御の仕組みも検討し始めています。
まだちゃんとした成果物は出ていていないため、共有することができませんが、おそらくアクセス制御に利用するトークンに変わりがなく、トークンに含まれた情報をアプリ側が検証して Context にセットし、Resolver / Directive で Context を見て制限するロジックを実装していく形になるではないかと予想しています。

また、GraphQL と Zanzibar の組み合わせはどうなるかもちょっと考えていきたいと思います。こちらについては、何かしらの成果物がありましたらまた記事にしたいと考えています。

最後に

今回は、 Ubie のサービス間通信をよりセキュアにするための取り組みを紹介しました。
実は筆者は以前勤めていたマイクロサービスアーキテクチャを採用した会社にて、サービス間通信をセキュアにするため、認証済みの情報を JWT なトークンに詰め込んでマイクロサービス間で伝搬するような仕組みを構築した経験がありました。各マイクロサービスの API を保護するため、どのような情報を API に渡す必要があるかを理解し、必要な情報を集めて信頼性を担保した状態で API に渡していく仕組みを構築することは容易ではありませんでした。マイクロサービスアーキテクチャを選択した場合、必ずこのような課題にあたると思いますので、これからマイクロサービスアーキテクチャを採用する方の参考に、そして自分なりの整理も兼ねて、記事とさせていただきました。

Ubie としてはサービス間通信をセキュアにする仕組みの構築はまだ終わってないですし、すべてのマイクロサービスが導入したわけではありませんので、これからも各マイクロサービスへの導入支援しつつ、仕組み自体をよりセキュアで利用しやすいものに進化させたいと考えています。

また、私が所属しているチームでは、サービス間通信だけでなく、各種類のユーザーに対しての認証認可に関する様々な課題を抱えております。
Ubie では認証認可、およびインフラセキュリティまわりの課題を解決するエンジニアを絶賛募集していますので、もし興味がありましたら是非ご連絡ください!

https://recruit.ubie.life/

Discussion