Slide 1

Slide 1 text

Session Title メルコインにおけるシステム間の データ分離を実現するための通信 アーキテクチャ Kohei Noda Backend Architect / Fintech Architect

Slide 2

Slide 2 text

Kohei Noda / @pobo380 2014年に株式会社MIXIに入社後、クライアントエン ジニア・バックエンドエンジニア・エンジニアリングマ ネージャー等、様々のポジションでゲーム開発に従 事。その後、2022年4月にメルコインに入社しアーキ テクトとして仕事をしている。2023年1月からFintech Architect としてメルペイに合流。 株式会社メルペイ Fintech Architect (Backend)

Slide 3

Slide 3 text

今日話すこと メルコインにおけるシステム間のデータ分離とは 01 開発者体験を損なわずにデータ分離を実現するアーキテクチャ 02 まとめ 03

Slide 4

Slide 4 text

メルコインにおける システム間のデータ分離

Slide 5

Slide 5 text

メルコインにおけるデータ分離とは メルコイン ⇔ メルカリ/メルペイのシステム間で お客さまのデータを容易に紐づけられないようにする

Slide 6

Slide 6 text

システムの分離 従業員 従業員 メルコイン メルカリ/メルペイ お客さまデータ お客さまデータ

Slide 7

Slide 7 text

システムの分離 従業員 従業員 メルコイン メルカリ/メルペイ お客さまデータ お客さまデータ

Slide 8

Slide 8 text

システムの分離 従業員 インシデント発生 😭 メルカリ/メルペイ お客さまデータ 流出したメルコインのお客さまデー タ

Slide 9

Slide 9 text

ユーザーIDの分離 システム間で異なるお客さまのID (ユーザーID) を使うことで データの紐付けを防ぐ

Slide 10

Slide 10 text

ユーザーIDの分離 従業員 データが紐づけられない 😃 メルカリ/メルペイ お客さまデータ 流出したメルコインのお客さまデー タ

Slide 11

Slide 11 text

システムの連携はどうする? サービス サービス メルコイン メルカリ/メルペイ お客さまデータ お客さまデータ

Slide 12

Slide 12 text

システムの連携はどうする? サービス サービス メルコイン メルカリ/メルペイ お客さまデータ お客さまデータ IDを変換してから送受信

Slide 13

Slide 13 text

内部用IDと外部用ID サービス サービス メルコイン メルカリ/メルペイ 内部用ID (UserID) 内部用ID (UserID) 外部用ID (PPID) 外部用ID (PPID) Mercari Engineering Portal: Applying OAuth 2.0 and OIDC to first-party services (https://engineering.mercari.com/en/blog/entry/20230130-applying-oauth-2-0-and-oidc-to-first-party-services/)

Slide 14

Slide 14 text

内部用IDと外部用ID サービス サービス メルコイン メルカリ/メルペイ Mercari/Merpay UserID Mercoin UserID Mercoin PPID Mercari/Merpay PPID Mercari Engineering Portal: Applying OAuth 2.0 and OIDC to first-party services (https://engineering.mercari.com/en/blog/entry/20230130-applying-oauth-2-0-and-oidc-to-first-party-services/)

Slide 15

Slide 15 text

ID変換のステップ 1. メルコインのサービス側で Mercoin UserID を Mercoin PPID に 変換してリクエストを送る。 2. メルカリ/メルペイのサービスでは、受け取った Mercoin PPID を Mercari UserID に変換して処理する。 3. 処理結果に含まれる Mercari UserID を Mercoin PPID に変換し てレスポンスを返す。 4. レスポンスを受け取ったメルコイン側のサービスは Mercoin PPID を Mercoin UserID に変換してから処理を行う。

Slide 16

Slide 16 text

ユーザーIDの分離によって生まれる複雑さ ID体系そのものが複雑でID変換のステップが多い ID変換を各サービスで実装するのはコストがとても大きい

Slide 17

Slide 17 text

ここまでのまとめ これらを同時に満たすアーキテクチャを作りたい システム間で 異なるユーザーIDを用いる 開発者体験を損なわない

Slide 18

Slide 18 text

開発者の体験を損なわずデー タ分離を実現する アーキテクチャ

Slide 19

Slide 19 text

目指す開発者体験 マイクロサービスの実装者がID変換を意識する必要がなく、内部のマ イクロサービスへの通信と同じように扱える ● 外部ID (PPID) の存在を意識せず、これまで通り内部ID (UserID) のみを扱う。 ● 外部ID への変換が必要になるシステム間通信の場合は、通信経路で自動的に変換され る。

Slide 20

Slide 20 text

方針 メルコインおよびメルカリ/メルペイでは ほとんどのマイクロサービス間の通信を Protocol Buffers で定義している ⬇ Protobuf メッセージに含まれるIDを 通信経路上で自動的に変換する

Slide 21

Slide 21 text

Protobuf メッセージに含まれるIDの変換 ● Protobuf のメッセージとID変換の向きを渡すと ○ メッセージの中に含まれるすべてのIDを変換して値を置き換える。 ● 「どのフィールドに値が含まれるか」は Custom Option を使って proto ファ イルの中でアノテーションを行う。 func (c *ProtoMessageConverter) ConvertPPIDsToUserIDs( ctx context.Context, message proto.Message ) error func (c *ProtoMessageConverter) ConvertUserIDsToPPIDs( ...

Slide 22

Slide 22 text

CustomOption によるアノテーション package microservice_a; message GetUserRequest { string user_id = 1 [ (user_id.conversion).enable = true ]; } message GetUserResponse { string user_id = 1 [ (user_id.conversion).enable = true ]; string name = 2; int32 age = 3; ... } ● IDを含むフィールドにアノテーションを行う。

Slide 23

Slide 23 text

Protobuf の Custom Option 定義 package user_id; message IDConversion { bool enable = 1; } extend google.protobuf.FieldOptions { IDConversion conversion = 60000; }

Slide 24

Slide 24 text

通信経路上での変換 Protobuf メッセージに含まれるIDの変換を経路上で行いたい ● Caller (呼び出し側) → gRPC Client Interceptor ● Callee (呼び出される側) → Gateway

Slide 25

Slide 25 text

通信の全体図

Slide 26

Slide 26 text

ID Provider ID Provider ● UserID と PPID のマッピングを持つサービス。 ○ UserID と PPID を相互変換するAPIを提供する。 ○ gRPC Interceptor と Gateway からこのAPIを利用する。

Slide 27

Slide 27 text

Caller のID変換 gRPC Client Interceptor ● gRPC Call 時に Request/Response を Modify するフィルタの ようなもの。 ○ gRPC Client の初期化時にセットアップする。 ● 以下の変換を行う ○ リクエスト送信 : Caller UserID → Caller PPID ○ レスポンス受信 : Caller PPID → Caller UserID

Slide 28

Slide 28 text

Callee のID変換 Gateway ● 外部からのリクエストの入り口となる既存サービス。 ○ いわゆる API Gateway の実装。 ○ 内部のマイクロサービスへルーティングを行う。 ● 以下の変換を行う。 ○ リクエスト受信 : Caller PPID → Callee UserID ○ レスポンス送信 : Callee UserID → Caller PPID

Slide 29

Slide 29 text

Callee のID変換 Gateway なぜ Callee MS ではなく Gateway でID変換を行うのか ● Caller PPID → Callee UserID への変換は各MSで行うのではな く、限られたコンポーネントで行いたい 。 ○ 任意の PPID を自身の UserID に変換できるため権限を 悪用されると、外部の PPIDを持った攻撃者による紐付けが 可能になる。 ● Callee に gRPC Server Interceptor を導入する手間がなくなる。

Slide 30

Slide 30 text

通信とID変換のフロー

Slide 31

Slide 31 text

得られた開発者体験 開発者が行うこと 1. Caller Microserive への gRPC Client Interceptor の導入 ○ 一度だけセットアップすればよい。 2. Protobuf メッセージへのアノテーションの記述 ○ 新規に通信を行う場合、既存の通信にIDフィールドを追加する場合に 記述する。 ID変換を意識することなく 内部通信と同じようにAPI呼び出しが可能

Slide 32

Slide 32 text

非同期通信のケース (Cloud Pub/Sub)

Slide 33

Slide 33 text

Publisher 側のID変換 PubSub Pusher 元々の責務 ● Cloud Pub/Sub の トピック からメッセージを Pull Subscription で 受け取り gRPC リクエストに変換する。 ○ Gateway を介さず直接マイクロサービスにリクエストを送 る。 ● Subscribe する Topic、Push 先などの設定は kubernetes の manifest として記述する。

Slide 34

Slide 34 text

Publisher 側のID変換 PubSub Pusher システム連携のための拡張 ● 受け取ったメッセージに含まれる IDを変換する。 ○ Publisher UserID → Subscriber PPID ■ 同期呼び出しの場合と違い、通信相手の PPID (Publisher PPID) に変換している。 ● Gateway に対してリクエストを送信する。 Mercari Engineering Portal: Applying OAuth 2.0 and OIDC to first-party services (https://engineering.mercari.com/en/blog/entry/20230130-applying-oauth-2-0-and-oidc-to-first-party-services/)

Slide 35

Slide 35 text

Subscriber 側のID変換 Gateway ● 同期的なAPI呼び出しとまったく同じ処理を行う。 ○ リクエスト受信 : Caller PPID → Callee UserID ○ レスポンス送信 : Callee UserID → Caller PPID Mercari Engineering Portal: Applying OAuth 2.0 and OIDC to first-party services (https://engineering.mercari.com/en/blog/entry/20230130-applying-oauth-2-0-and-oidc-to-first-party-services/)

Slide 36

Slide 36 text

得られた開発者体験 開発者が行うこと 1. PubSub Pusher の設定ファイルを記述する。 ○ ID変換とGatewayへのPushを有効にする。 ○ マイクロサービス側の実装は変更する必要がない。 ID変換を意識することなく PubSub を使った非同期通信が可能

Slide 37

Slide 37 text

まとめ

Slide 38

Slide 38 text

まとめ 1. システム間でユーザーIDを分離することで高いレベルのデータプラ イバシー保護を実現した。 2. 透過的にID変換を行うアーキテクチャを導入することで効率的に開 発ができるようにした。 ○ マイクロサービスの開発者は実装時にID変換を意識する必要 がない。 ○ Go, gRPC (protobuf) で統一された環境だから実現すること ができた。

Slide 39

Slide 39 text

gRPC Interceptor の実装が Go しかない 01 不具合調査時の Traceability 02 UserID 以外のデータによる紐付けをどのように防ぐか 03 残っている課題

Slide 40

Slide 40 text

No content