認証と承認

このセクションでは、Fleet Engine との統合に関する認証と認可のコンセプトについて説明します。

ラスト ワンマイルのフリート ソリューションが提供する機能は、Google Cloud コンソールで構成できます。Fleet Engine SDK では、適切なサービス アカウントによって署名された JSON Web Token(JWT)を使用する必要があります。

概要

Fleet Engine に対する認証と認可を行うお客様のバックエンドでは、標準のアプリケーションのデフォルト認証情報メカニズムを使用する必要があります。

Fleet Engine は、スマートフォンやブラウザなどの信頼性の低い環境からの呼び出しも受信します。信頼できる環境にのみ適しているサービス アカウントの秘密鍵を保護するため、お客様のバックエンドでは、Fleet Engine に固有の追加のクレームで署名された JSON Web Token(JWT)を生成し、それをスマートフォンなどの信頼できない環境に対して発行することが期待されます。

認証の設計原則

Fleet Engine の認証フローには、次の設計原則が組み込まれています。

  • IAM ロールは、プリンシパルに許可されるリソースに対する一連の権限を定義します。たとえば、管理者のロールでは、アプリケーションのデフォルト認証情報を使用してすべての操作を行うことができます。一方、信頼できないドライバ* のロールでは、車両の位置情報の更新のみを許可し、認証と認可に JWT を使用する必要があります。

  • 信頼できない環境の場合、JWT クレームにより、呼び出し元が操作できるエンティティがさらに制限されます。特定のタスクやデリバリー ビークルを指定できます。

  • 低信頼環境で実行するコードは、まず信頼できる環境で実行されているコードを呼び出して JWT を発行する必要があります。

  • Fleet Engine は、リソースの API 呼び出しに対して次のセキュリティ チェックを行います。

    1. 呼び出し元のプリンシパルには、リソースに対するアクションに対して適切な権限が(ロールの割り当てによって)付与されます。

    2. 管理者以外のロールの場合は、リクエストで渡された JWT クレームがリソースに必要な権限を提供します。

認証フロー

次のシーケンス図に、これらの認証フローの詳細を示します。

  1. フリート管理者がサービス アカウントを作成します。

  2. フリート管理者は、特定の IAM ロールをサービス アカウントに割り当てます。

  3. フリート管理者は、サービス アカウントとアプリケーションのデフォルト認証情報を使用してバックエンドを構成します。

  4. クライアント アプリが、顧客のバックエンドに JWT をリクエストします。リクエスト元は、ドライバアプリ、コンシューマアプリ、またはモニタリング アプリです。

  5. お客様のバックエンドが、それぞれのサービス アカウントに対して JWT に署名して発行します。クライアント アプリが JWT を受け取ります。

  6. クライアント アプリは、設定フェーズで割り当てられた IAM ロールに応じて、JWT を使用して Fleet Engine に接続し、データの読み取りや変更を行います。

認証シーケンスの図

Cloud プロジェクトの設定

クラウド プロジェクトを設定するには、まずプロジェクトを作成してから、サービス アカウントを作成します。

Google Cloud プロジェクトを作成するには:

  1. Google Cloud コンソールを使用して Google Cloud プロジェクトを作成する。
  2. API とサービス ダッシュボードを使用して、Local Rides and Deliveries API を有効にします。

サービス アカウントと IAM ロール

サービス アカウントは、ユーザーではなく、アプリケーションで使用される特別なアカウントです。通常、サービス アカウントは、ロールに応じて異なる一連の権限を付与する JWT を作成するために使用されます。不正使用の可能性を減らすために、必要最小限のロールセットを持つ複数のサービス アカウントを作成できます()。

ラスト ワンマイルのフリート ソリューションでは、次のロールを使用します。

ロール説明
Fleet Engine Delivery の信頼できるドライバ ユーザー

roles/fleetengine.deliveryTrustedDriver
配達車両とタスクを作成、更新する権限を付与します(配達車両の場所、タスクのステータスや結果の更新など)。このロールを持つサービス アカウントによって作成されたトークンは、通常、配信ドライバのモバイル デバイスまたはバックエンド サーバーから使用されます。
Fleet Engine Delivery の信頼されていないドライバ ユーザー

roles/fleetengine.deliveryUntrustedDriver
配達車両の位置情報を更新する権限を付与します。通常、このロールを持つサービス アカウントによって作成されたトークンは、配送ドライバーのモバイル デバイスで使用されます。
Fleet Engine Delivery コンシューマ ユーザー

roles/fleetengine.deliveryConsumer
トラッキング ID を使用してタスクを検索する権限と、タスク情報を読み取る権限(更新はしない)を付与します。通常、このロールを持つサービス アカウントによって作成されたトークンは、配信コンシューマのウェブブラウザで使用されます。
Fleet Engine Delivery 管理者

roles/fleetengine.deliveryAdmin
配信リソースの読み取り / 書き込み権限を付与します。このロールを持つプリンシパルは JWT を使用する必要はなく、代わりにアプリケーションのデフォルト認証情報を使用する必要があります。カスタム JWT クレームは無視されます。このロールは、信頼できる環境(お客様のバックエンド)に制限する必要があります。
Fleet Engine Delivery スーパー ユーザー **(非推奨)**

roles/fleetengine.deliverySuperUser
すべての配達車両とタスクの API に権限を付与します。このロールを持つサービス アカウントによって作成されたトークンは、通常、バックエンド サーバーから使用されます。
Fleet Engine Delivery フリート リーダー

roles/fleetengine.deliveryFleetReader
配達車両とタスクの読み取り権限と、トラッキング ID を使用してタスクを検索する権限を付与します。通常、このロールを持つサービス アカウントによって作成されたトークンは、配送業者のウェブブラウザで使用されます。

配達ドライバーに会社の IT が管理するデバイスを提供する組織は、Fleet Engine の信頼できるドライバー ユーザーロールによって提供される柔軟性を利用して、Fleet Engine の操作の一部またはすべてをモバイルアプリに統合できます。

お客様所有デバイス(Bring Your Own Device)ポリシーをサポートしている組織は、Fleet Engine の信頼できないドライバー ユーザーロールの安全性を確保する必要があります。また、Fleet Engine への車両位置情報の更新の送信にはモバイルアプリのみを使用する必要があります。他のすべてのインタラクションは、お客様のバックエンド サーバーから開始する必要があります。

Driver SDK と Consumer SDK は、これらの標準ロールを中心に構築されています。ただし、カスタムロールを作成して、任意の権限セットをバンドルすることもできます。必要な権限がない場合、Driver SDK と Consumer SDK にエラー メッセージが表示されます。そのため、カスタムロールではなく、上記の標準のロールセットを使用することを強くおすすめします。

サービス アカウントの作成

サービス アカウントは、Google Cloud コンソールの IAM & Admin > Service Accounts タブを使用して作成できます。[ロール] プルダウン リストから [Fleet Engine] を選択し、いずれかのロールをサービス アカウントに割り当てます。各ロールに関連付けられたアカウントを示すことをおすすめします。たとえば、サービス アカウントにわかりやすい名前を付けます。

利便性のため、信頼できないクライアント用に JWT を作成する必要がある場合は、サービス アカウント トークン作成者ロールにユーザーを追加すると、そのユーザーは gcloud コマンドライン ツールを使用してトークンを作成できます。

gcloud projects add-iam-policy-binding project-id \
       --member=user:my-user@example.com \
       --role=roles/iam.serviceAccountTokenCreator

ここで、my-user@example.com は gcloud での認証に使用するメールアドレス(gcloud auth list --format='value(account)')です。

Fleet Engine 認証ライブラリ

Fleet Engine は、JWT を使用して、信頼できない環境における Fleet Engine API へのアクセスを制限します。Fleet Engine Auth Library(GitHub で利用可能)を使用すると、Fleet Engine JWT の作成を簡素化し、安全に署名できます。

このライブラリには次のようなメリットがあります。

  • Fleet Engine トークンの作成プロセスを簡素化します。
  • 認証情報ファイルを使用する以外のトークン署名メカニズム(サービス アカウントの権限借用など)を提供します。

認可用の JSON Web Token(JWT)の作成

Fleet Engine 認証ライブラリを使用しない場合は、コードベース内で JWT を直接作成する必要があります。そのためには、JWT と Fleet Engine との関連性の両方について深く理解している必要があります。そのため、Fleet Engine 認証ライブラリを利用することを強くおすすめします。

Fleet Engine 内では、JWT が有効期間の短い認証を提供し、デバイスが承認された車両またはタスクのみを変更できるようにします。JWT にはヘッダーとクレーム セクションが含まれます。ヘッダー セクションには、使用する秘密鍵(サービス アカウントから取得)や暗号化アルゴリズムなどの情報が含まれています。クレーム セクションには、トークンの作成時間、トークンの有効期間、トークンがアクセス権を申請しているサービス、アクセス スコープを限定するためのその他の認証情報(配達車両 ID など)などの情報が含まれます。

JWT ヘッダー セクションには次のフィールドがあります。

項目説明
alg 使用するアルゴリズム。「RS256」。
typ トークンのタイプ。JWT。
kid サービス アカウントの秘密鍵 ID。この値は、サービス アカウント JSON ファイルの private_key_id フィールドで確認できます。適切なレベルの権限を持つサービス アカウントの鍵を使用してください。

JWT クレームのセクションには次のフィールドがあります。

項目説明
iss サービス アカウントのメールアドレス。
sub サービス アカウントのメールアドレス。
aud サービス アカウントの SERVICE_NAME(この場合は https://fleetengine.googleapis.com/)
iat トークンが作成されたときのタイムスタンプ。1970 年 1 月 1 日 00:00:00 UTC からの経過秒数で指定します。スキューのために 10 分間待ちます。タイムスタンプが過去にさかのぼって、または未来の日付になっている場合、サーバーがエラーを報告する可能性があります。
exp トークンが期限切れになるタイムスタンプ。1970 年 1 月 1 日 00:00:00 UTC からの経過秒数で指定します。タイムスタンプが 1 時間以上先である場合、リクエストは失敗します。
authorization ユースケースに応じて、deliveryvehicleid、trackingid、taskid、taskids を含めることができます。

JWT トークンの作成とは、そのトークンに署名することです。JWT の作成と署名の手順とコードサンプルについては、OAuth を使用しないサービス アカウントの認証をご覧ください。その後、作成されたトークンを gRPC 呼び出し、または Fleet Engine へのアクセスに使用するその他のメソッドに適用できます。

JWT クレーム

ラスト ワンマイルのフリート ソリューションでは非公開の申し立てが使用されます。プライベート クレームを使用すると、承認されたクライアントのみが自身のデータにアクセスできます。たとえば、バックエンドが配達ドライバーのモバイル デバイス用に JSON ウェブトークンを発行する場合、そのトークンには、ドライバーの配達車両 ID の値を含む deliveryvehicleid クレームが含まれている必要があります。次に、ドライバーのロールに応じて、トークンは特定の配信車両 ID に対してのみアクセスを有効にし、他の任意の車両 ID は許可しません。

ラスト ワンマイルのフリート ソリューションでは、次のプライベート クレームを使用します。

  • deliveryvehicleid - 配達車両ごとの API を呼び出す場合に使用します。
  • taskid - タスクごとの API を呼び出すときに使用します。
  • taskids - BatchCreateTasksAPI を呼び出すときに使用します。このクレームは配列形式である必要があり、配列にはリクエストの完了に必要なすべてのタスク ID が含まれている必要があります。delivervehicleid クレーム、trackingid クレーム、taskid クレームは含めないでください。
  • trackingid - GetTaskTrackingInfoAPI を呼び出すときに使用します。クレームは、リクエストのトラッキング ID と一致する必要があります。delivervehicleid クレーム、taskid クレーム、taskids クレームは含めないでください。

バックエンド サーバーから API を呼び出す場合は、トークンに適切なクレームが含まれている必要がありますが、deliveryvehicleidtaskidtrackingid クレームにはアスタリスクの特別な値(*)を使用できます。アスタリスク(「*」)は taskids クレームでも使用できますが、配列内の唯一の要素にする必要があります。

OAuth 2.0 アクセス トークンを使用するのではなく、JSON をトークン署名なしとして直接作成して署名する場合は、Identity Developer ドキュメントの OAuth を使用しないサービス アカウントの認証の手順をご覧ください。

トークンを gRPC 呼び出しに関連付けるメカニズムは、呼び出しに使用される言語とフレームワークによって異なります。HTTP 呼び出しにトークンを指定するメカニズムは、個々の配送追跡またはフリート パフォーマンスのユースケースの承認メモに記載されているように、値がトークンである署名なしトークンを含む Authorization ヘッダーを含めることです。

次の例は、バックエンド サーバーからのタスクごとのオペレーションのトークンを示しています。

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "taskid": "*"
       }
    }

次の例は、バックエンド サーバーからのタスクの一括作成オペレーションのトークンを示しています。

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "taskids": ["*"]
       }
    }

次の例は、バックエンド サーバーからの配達車両ごとのオペレーションのトークンを示しています。

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_provider_service_account"
    }
    .
    {
      "iss": "provider@yourgcpproject.iam.gserviceaccount.com",
      "sub": "provider@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "deliveryvehicleid": "*"
       }
    }

次の例は、エンドユーザーのお客様用のトークンを示しています。

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_delivery_consumer_service_account"
    }
    .
    {
      "iss": "consumer@yourgcpproject.iam.gserviceaccount.com",
      "sub": "consumer@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "trackingid": "shipment_12345"
       }
    }

次の例は、ドライバアプリのトークンを示しています。

    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "private_key_id_of_delivery_driver_service_account"
    }
    .
    {
      "iss": "driver@yourgcpproject.iam.gserviceaccount.com",
      "sub": "driver@yourgcpproject.iam.gserviceaccount.com",
      "aud": "https://fleetengine.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600,
      "authorization": {
         "deliveryvehicleid": "driver_12345"
       }
    }
  • ヘッダーの kid フィールドに、サービス アカウントの秘密鍵 ID を指定します。この値は、サービス アカウント JSON ファイルの private_key_id フィールドにあります。
  • iss フィールドと sub フィールドに、サービス アカウントのメールアドレスを指定します。この値は、サービス アカウント JSON ファイルの client_email フィールドにあります。
  • aud フィールドに https://SERVICE_NAME/ を指定します。
  • iat フィールドには、トークンが作成されたときのタイムスタンプを 1970 年 1 月 1 日 00:00:00 UTC からの経過秒数で指定します。スキューには 10 分間かかります。タイムスタンプが過去または未来から遠すぎると、サーバーがエラーを報告する可能性があります。
  • exp フィールドには、トークンが期限切れになるタイムスタンプを 1970 年 1 月 1 日 00:00:00 UTC からの経過秒数で指定します。推奨値は iat + 3,600 です。

モバイル デバイスまたはエンドユーザーに渡すトークンに署名する場合は、配信ドライバまたはコンシューマのロールの認証情報ファイルを使用してください。そうしないと、モバイル デバイスやエンドユーザーは、アクセスすべきでない情報を変更または表示できるようになります。