クックパッドマートのドライバー向けWebサービスのアカウントの仕組み

買物プロダクト開発部の中村です。クックパッドマートという生鮮食品のECサービスでサーバーサイドエンジニアとして流通のシステム開発に携わっています。

この記事は、「クックパッドマートを支えるアカウントたち」連載6本目の記事で、ドライバー向けWebサービスのアカウントの仕組みについて紹介します。 シリーズの全貌については以下の記事を御覧ください。

クックパッドマートを支えるアカウントたち - クックパッド開発者ブログ

クックパッドマートでは実際に商品を購入するユーザーはもちろんのこと、商品を販売する販売者や、販売者からユーザーまで商品を運ぶドライバーなど様々な立場の人が関わってサービスが成り立っています。 それぞれの立場の人に向けて異なるシステムを開発して提供していますが、今回はその中でもドライバーが配送を行うために利用するサービスの概要とアカウントの取り扱い方について紹介します。

ドライバー向けのサービス

ドライバーは商品を届けるために、いつ、何を、どこから、どこに運ぶか知る必要があります。これらの情報をドライバーに提供するため専用のWebサービスを開発しています。商品が流通していく過程では複数の流通経路を辿っており、各流通経路で異なる運び方が必要になるため、それぞれ別のドライバーが担当し、Webサービスも流通経路毎に用意しています。
ドライバー向けのWebサービスについてはこちらの記事でより詳細に紹介しています。

特性と制限

前述のドライバー向けWebサービスの要件を満たすため、アカウントは次のような特性や制限があります。

全てのアカウントを管理

運送会社のドライバーに対して個別にアカウントを発行する必要があります。新しい担当ドライバーに対してアクセスする許可を与えたり、担当から外れたドライバーはアクセスできないようにしたりと細かく制御する必要があります。

流通経路別のアクセス権限をつける

流通経路別に別のサービスを提供しており、それぞれアクセスするドライバーが異なります。とはいえ、ドライバーによっては複数の流通経路を担当することもあったりします。そのため、どの流通経路のサービスにアクセスできるかという権限を設定できる必要があります。

運送会社別にアクセス権限をつける

配送は複数の運送会社の協力のもとで成り立っています。それぞれの運送会社の担当範囲以外にはアクセスできないよう制限をかける必要があります。

権限レベルをつける

アクセスする人にはドライバーの他にもいくつかの種類の人がいて、それぞれのアカウントは以下のような要件を満たす必要があります。

名称 説明 要件
ドライバー 商品を運ぶドライバー いつ、何を、どこから、どこに運ぶかという情報が必要
管理者 ドライバーを管理する運送会社の管理者 複数のドライバーの進捗管理などの管理者用の機能を使う権限が必要
クックパッドの配送管理者 クックパッド側の配送全体の管理者 全ての流通経路のサービス、全ての運送会社の情報にアクセス可能

IDaaSの選定

認証を自前で実装したくないので何らかIDaaSを使用したいと考え、Azure ADを採用しました。前述の特性や制限を満たす使い方ができるということの他に、Azure AD は元々社内の様々なサービスのSSOに利用されているため、

  • 社内の人間のアカウントがすでに存在する
  • 新たなIDaaSの契約が不要で作業工数やコスト面で有利

といったメリットがありました。

Azure AD

構成

ドライバーのアカウントはAzure AD内で以下のようなイメージで構成しています。

詳しく見ていきます。

グループ (Group)

運送会社の権限レベル別にグループを作成しています。つまり運送会社A,Bがある場合、以下の4つのグループを作成します。

  • 運送会社Aのドライバーグループ
  • 運送会社Aの管理者グループ
  • 運送会社Bのドライバーグループ
  • 運送会社Bの管理者グループ

管理単位 (Administrative Unit)

Azure AD のグループへのアカウントの追加・削除といった操作は社内のコーポレートエンジニアリング部門の管理者しか許されていません。
しかし、ドライバーの追加・削除はそれなりの頻度で発生するので、別部署の権限を持つ管理者の負荷が高くなりますし、ドライバーがサービスを使い始めるまでのリードタイムが長くなってしまいます。 そこで流通チーム内で自由にドライバーの追加・削除が行えるよう、Azure AD の管理単位 (Administrative Unit) を使用しています。管理単位はユーザーやグループの管理権限を他のユーザーに委任することができる機能で、ドライバー向けサービス用の管理単位を作成し、運送会社のグループを管理単位の対象として登録しています。
そして流通チームに管理単位のグループ編集権限を渡してもらうことで、流通チームだけでドライバーの追加・削除ができる運用体制を実現しています。

アプリ (App)

ドライバー向けサービス用のアプリを定義しています。アプリへは運送会社のグループと社内管理者(Admin)ユーザーを登録しています。
1つのアプリで全てのドライバー向けサービスの権限を扱っており、細かい権限管理は後述のアプリロールを使って実現しています。

アプリロール (Role)

アプリロールは、グループやユーザーにアプリへのアクセス許可を与える設定です。アプリロールにvalueを設定し、valueをドライバー向けサービス側でチェックすることでアクセス制御しています。valueには 対象のサービス, 運送会社, 権限レベルの情報を持たせており、 対象のサービス/運送会社/権限レベル という形で表現しています。
例えばサービスX(service-x)にアクセスできる運送会社A(company-a)ドライバー(driver)ロールの場合は以下のようになります。

service-x/company-a/driver

また、複数のドライバー向けサービスを単一アプリで扱っているので、理想としてはドライバー向けサービス別にロールを用意し、グループに許可したいサービスのロールを複数付与したくなります。
しかし残念ながら、ユーザーやグループには単一のアプリロールしか設定することができません。そこで、運送会社グループと権限レベル別にロールを用意し、各ロールのvalueには複数のドライバー向けサービスの情報を入力、ドライバー向けサービス側でvalueをパースして権限チェックするようにしています。
先ほどのロールにサービスY(service-y)のアクセス権限も加えると以下のようになります。

service-x/company-a/driver,service-y/company-a/driver

ここでサービスXに運送会社AのドライバーがアクセスするとAzure ADから以下のような情報が渡ってきます。

{
  "provider": "driver_service",
  "info": {
    "name": "Takuya Nakamura"
  },
  "extra": {
    "raw_info": {
      "name": "Takuya Nakamura",
      "roles": [
        "service-x/company-a/driver,service-y/company-a/driver"
      ],
    }
  }
}

サービスX側ではこの情報の roles を確認します。

service-x/company-a/driver,service-y/company-a/driver

ここには複数のサービスのロールが含まれているので、パースしてサービスX自身に該当するロールを抽出します。

service-x/company-a/driver

さらにこれをパースし、サービス, 運送会社, 権限レベルに分割します。

service-x # サービス
company-a # 運送会社
driver # 権限レベル

これでサービスX(service-x)に運送会社A(company-a)のドライバー(driver)としてアクセスできることがわかりました。 この情報を元にリクエストに対する認可処理を行い、別の運送会社の情報にアクセスできないようにしたり、管理者権限が必要な操作をドライバーが行えないようにしたりしています。

まとめ

ドライバー向けWebサービスのアカウントについて紹介してきました。改めてまとめると、ドライバー向けアカウントの特性や制約を満たすことができるIdPとしてAzure ADを選択、認可はAzure AD上でサービス用のアプリと運送会社のグループを作成してグループにアプリロールを付加、サービス側でアプリロールに含まれる値をチェックすることで実現しています。
日々流通の形が進化することに伴い、ドライバー向けサービスも日々進化したり新たに生まれるといった変化が起こっていますが、Azure ADを使ったアカウント管理をすることで柔軟に対応できる体制を実現できています。 もし少しでも興味がある方がいらっしゃいましたら是非ご連絡ください。

アカウント連載の記事一覧