メルカリShopsのスタッフアカウント機能の設計とリリース

こんにちは!ソウゾウの Software Engineer のtakatoshionoです。「メルカリShops [フライング] アドベントカレンダー2022」の13日目を担当します。

はじめに

この記事では今年の5月にリリースした「1つのショップを複数スタッフアカウントで運営する」機能について、どのように設計とリリースを行ったか紹介します。気がつけばもう半年以上も前の話となりますが、自分にとって印象に残っている開発であり、また今後も関連する開発が ありそうなので、この機会に振り返ってみたいと思います。

スタッフアカウント機能を利用すると、1つのショップを複数人で運営することができます。この機能の登場前はショップを開設したアカウントだけが利用でき、そのアカウントはメルカリアプリの利用者である必要がありました。しかしながら、注文数が多いショップでは一人ですべての運営を行うには限界があります。そこで、複数人でショップを運営できるようにするため、以下の機能を開発することになりました。

  1. ショップを開設したアカウント(オーナーアカウント)以外でも利用できる
  2. スタッフアカウントはメルカリアプリのアカウントを必要としない
  3. スタッフアカウントは役割(ロール)によってできること(権限)が決まる

これらを実現するための認証方法と、権限管理用の新しいマイクロサービスの導入について紹介します。

スタッフアカウントの作成と認証

スタッフアカウントの作成は既存のアカウントから招待メールを受け取ることから始まります。そして招待メールに記載されたURLからパスワードの登録と電話番号の認証を行うだけでかんたんに作成することができます。

メルカリShopsではメルカリを認証プロバイダとして利用することでアカウントの認証を行っています。しかし、スタッフアカウントはメルカリのアカウントを持たないため、他の方法で認証を行う必要があります。認証の仕組みを独自に作成して維持するのは大変な作業ですし、我々は既にGCP(Google Cloud Platform)を利用しているため、今回はGoogle Identity Platformを利用することにしました。

かんたんに認証フローのシーケンスを示すと以下のようになります。

スタッフアカウントの認証フロー

まずショップのオーナーがスタッフを招待します。招待されたスタッフがメール内のURLから登録ページに進み、Google IDPを使って認証を行います。その後、Google IDPのID Tokenを検証して問題がなければ、メルカリShopsのID Tokenを発行するという流れです。

権限管理の設計

スタッフアカウントには「管理者」と「担当者」の2つの役割があり、担当者は操作の権限が限定されています。これを実現するために役割と権限を管理するためのマイクロサービスを新規で作成することにしました。このマイクロサービスはIAM (Identity and Access Management) という名前です。このマイクロサービスの管理対象はスタッフアカウントに限定せず、メルカリShopsの全てのアカウントを対象にしています。このことでアカウントの種類、役割に関わらず統一的な方法で権限の管理をできるようにすることが目的です。図にすると以下のようになります。

権限管理の設計

この設計ではIAM Serviceが権限を管理するので、ショップのオーナーやスタッフの役割を作成するリクエストと、他のマイクロサービスから権限を取得するためのリクエストがあります。

APIはとてもシンプルで、以下のようなgRPCメソッドとして定義しています。

service IAMService {
  // CreateShopRoleBindingRequest creates the role binding of the account.
  rpc CreateShopRoleBinding(CreateShopRoleBindingRequest) returns (CreateShopRoleBindingResponse) {}

  // ListShopPermissionsRequest returns a list of permissions that the account has.
  rpc ListShopPermissions(ListShopPermissionsRequest) returns (ListShopPermissionsResponse) {}
}

message CreateShopRoleBindingRequest {
  string shop_id    = 1;
  Role role         = 2;
  string account_id = 3;
}

message ListShopPermissionsRequest {
  string shop_id = 1;
}

CreateShopRoleBindingはショップに対する役割(Role)をアカウントに付与するためのRPCです。ListShopPermissionsはアカウントがショップに対して持っている権限を取得するためのRPCです。取得する際にはgRPCのmetadataとしてID Tokenを受け取り、それを使って対象のアカウントを識別します。

代替案について

実は当初の設計ではIAM Serviceというものはありませんでした。スタッフを管理するサービスが権限も一緒に管理すればよいと考えていたからです。図にすると以下のようになります。

権限管理の設計 - 代替案

この設計では先に説明したIAM Serviceではなく、Staff Serviceが登場しています。このサービスでスタッフと権限、両方を管理しようという案です。

しかしこの設計は以下の2つの理由で採用されませんでした。

  • アクセス権限の管理には強い責務が伴うこと
  • その性質上、多くのマイクロサービスから依存されること

1つ目の理由としては、強い責務を持つマイクロサービスは分離しておくほうが良いだろうという判断です。2つ目の理由は循環参照と関係していて、多く依存されるということは自分自身がその依存元のサービスに対して直接的であれ、間接的であれ依存できないことを意味します。そのため分離しておくことにメリットがあると判断しました。

そして、権限の管理を分離したことで ”スタッフを管理するサービス” の責務が減ったため、これをShop Serviceに統合することで最初に述べた構成に落ち着きました。

リリースの方法

前述したとおり、アカウントの種類、役割に関わらず統一的な方法で権限の管理を行うことにしたため、スタッフアカウント機能をリリースするためには、まず既存のショップを持っているオーナーアカウントに対して権限の付与が必要となります。そのため開発の開始時点で、以下のような段階的なリリースを想定して進めました。

  1. ショップの新規作成時にオーナーアカウントの権限が作られるようにする
  2. 既存のオーナーアカウントに対して権限を作成しておく
  3. 各操作において権限のチェックが行われるようにする
  4. スタッフアカウントを作成できるようにする

今回の開発では権限のチェックというベースとなる部分と、スタッフアカウントの導入という、その上に乗る機能の開発を複数人で分担して行いましたが、最初にゴールまでのステップを想定することで、全員の認識を揃えながら進められたと感じています。

まとめ

この記事ではスタッフアカウント機能の設計とリリースについて紹介を行いました。

個人的な話になりますが、”IAM”のように基盤となるサービスを設計・開発する機会をもらえてとても勉強になりました。連載1日目のソウゾウのMove Fastを支える仕組みでも紹介したように、ソウゾウではこのような設計、開発に関する意思決定を個々のエンジニアが日々行っています。

自分の性格もあるかもしれませんが、大きな意思決定をするときは慎重になってしまいがちです。しかしながら、自分が考えた仕組みがうまく動いていたり、それが時間を経て他の開発者によってもっと良い状態に改善されたり、というのを見ていると、システムは時間とともに変化していくもの、と感じています。今後もMove Fastに意思決定していくというのを忘れないようにしたいと思います。

株式会社ソウゾウではメンバーを大募集中です。メルカリShopsの開発やソウゾウに興味を持った方がいればぜひご応募お待ちしています。詳しくは以下のページをご覧ください。
Software Engineer
Software Engineer, Site Reliability
Software Engineer (Internship) – Mercari Group (※新卒採用に応募するにはまずインターンへの参加をお願いしています。)
またカジュアルに話だけ聞いてみたい、といった方も大歓迎です。こちら の申し込みフォームよりぜひご連絡ください!

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加