認証と承認

このセクションでは、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. クライアント アプリは、JWT を使用して Fleet Engine に接続し、設定フェーズで割り当てられた IAM ロールに応じてデータの読み取りまたは変更を行います。

認証シーケンス図

Cloud プロジェクトの設定

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

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

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

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

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

Last Mile Fleet Solution では、次のロールを使用します。

ロール説明
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 Auth ライブラリ

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

このライブラリには次のような利点があります。

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

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

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

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

JWT クレーム

ラスト ワンマイル フリート ソリューションはプライベート クレームを使用する。プライベート クレームを使用すると、承認されたクライアントのみが独自のデータにアクセスできるようになります。たとえば、バックエンドが配達ドライバーのモバイル デバイス用の JSON Web Token を発行する場合、そのトークンには、ドライバーの配達車両 ID の値を含む deliveryvehicleid クレームが含まれている必要があります。ドライバーのロールによっては、トークンによって特定の配達車両 ID のみが有効化され、他の任意の車両 ID へのアクセスは有効になりません。

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

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

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

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 です。

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