認証と承認

このセクションでは、Fleet Engine の実装に関する認証と認可のコンセプトについて説明します。Fleet Engine の関数呼び出しを保護するために必要な手順について詳しく説明します。

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

概要

Fleet Engine は、その認可メカニズムの一部として、信頼性の低い環境からの呼び出しに対するセキュリティを強化します。信頼性の低い環境には、スマートフォンやブラウザが含まれます。また、Fleet Engine は最小権限の原則を採用しています。この原則では、呼び出しには、タスクを完了するために必要な権限のみを付与する必要があります。

信頼性の低い環境からの関数呼び出しを保護するために、Google は完全に信頼できる環境であるバックエンド サーバーで、コードがトークンを作成するメカニズムを設計しました。各呼び出しにはセキュリティの詳細な説明が含まれます。これは、任意の環境からの呼び出しとともに渡す JWT に暗号化されます。

認証の設計原則

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

  • IAM ロールは、呼び出し元に許可されるアクティビティの範囲を定義します。たとえば、SuperUserのロールではすべての操作が許可されますが、SuperUserのロールでは、最小限の位置情報の更新しか実行できません。

  • IAM ロールはサービス アカウントに関連付けられます。

  • JWT クレームは、呼び出し元が操作できるエンティティをさらに制限します。これらは、特定のタスクまたはデリバリー ビークルです。

  • Fleet Engine に送信されるリクエストには、常に JWT が含まれます。

    • JWT はサービス アカウントに関連付けられているため、Fleet Engine に送信されるリクエストは、JWT に関連付けられたサービス アカウントに暗黙的に関連付けられます。
  • Fleet Engine に渡すことができる適切な JWT をリクエストするには、まず、低信頼環境で実行されているコードで、完全に信頼できる環境で実行されているコードを呼び出す必要があります。

  • Fleet Engine は次のセキュリティ チェックを実行します。

    1. サービス アカウントに関連付けられた IAM ロールにより、呼び出し元が API 呼び出しを発行するための正しい承認が提供されます。

    2. リクエストで渡された JWT クレームにより、呼び出し元がエンティティを操作するための正しい承認が提供されます。

認証フロー

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

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

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

  3. フリート管理者は、サービス アカウントを使用してバックエンドを構成します。

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

  5. Fleet Engine は、それぞれのサービス アカウントに対して 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.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 トークンの作成プロセスを簡素化します。
  • 認証情報ファイルを使用する以外のトークン署名メカニズム(サービス アカウントの権限借用など)を提供します。
  • 署名付きトークンを gRPC スタブまたは GAPIC クライアントから送信された送信リクエストに追加します。

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

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

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

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

項目説明
alg 使用するアルゴリズム。「RS256」。
typ トークンのタイプ。JWT。
子供 サービス アカウントの秘密鍵 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 - SearchTasksAPI を呼び出すときに使用します。クレームは、リクエストのトラッキング 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 です。

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