Advanced Services による BigQuery の行レベルのセキュリティ

たとえば、営業チーム向けのソリューションを作成しようとしているとします。営業チームは複数の地域に分割され、各地域にそれぞれの地域マネージャーがいます。BigQuery の販売データセットには、地域別および日付別の売上金額があります。

こうした場合は、地域マネージャーが単一のダッシュボードで自分の地域の販売データのみを表示できるというソリューションを作成するとよいでしょう。

要件

  • ダッシュボード閲覧ユーザーは Google アカウントでログインすること。
  • ユーザーのメールアドレスと、ユーザーがアクセスできるデータまたは行の間のマッピングが利用可能なこと。
  • サービス アカウントが、BigQuery データへのアクセスに使用されること。したがって、請求はダッシュボード提供ユーザーによって一元管理されます。

制限事項

  • ダッシュボードでは、最初の表示の際に各閲覧ユーザーから 1 回限りの認証が必要です。
  • 閲覧ユーザーはダッシュボードを編集したり、他のユーザーと共有したりすることはできません。
  • Workspace をご利用で、管理者が共有を無効にしている場合 ドライブのファイルを [リンクを知っている全員] に設定すると、 Gmail.com アカウントでソリューションを開発できます。

解決策

ソリューションを実装するには、以下のすべてのステップを完了します。

新しいコミュニティ コネクタを作成する

コミュニティ コネクタの仕組み(英語)を視聴し、コミュニティ コネクタのコードラボを完了します。コネクタ作成用のデベロッパー ツールを使うと、開発作業がより効率的かつ簡単になります。

コネクタコードを記述する

  1. getAuthType()NONE を返す必要があります。
  2. getConfig() は空の設定を返す必要があります。
    • (省略可)ダッシュボードの設定に特定の入力が必要な場合は、ここでユーザー入力をリクエストできます。
  3. getSchema() はクエリのスキーマを返す必要があります。
    • (省略可)スキーマの一部として、SQL クエリまたは計算フィールドを使用して、カスタム フィールドと計算を追加できます。
  4. getData() の実装は後のステップで行います。

マニフェストを更新する

マニフェスト リファレンスを参照し、次を含むすべての必要な情報でマニフェストを完成させます。

  1. dataStudio.forceViewersCredentialstrue に設定します。
  2. dataStudio.advancedServices.datatrue に設定します。
  3. oauthScopes には、https://www.googleapis.com/auth/userinfo.emailhttps://www.googleapis.com/auth/script.external_request を追加します。詳しくは、Apps Script 向け承認スコープをご覧ください。
    • (条件付き必須)コネクタで使用されるサービスに関連するすべてのスコープを追加します。

マニフェストは次のようになります。

{
  ...
  "dataStudio": {
    "forceViewersCredentials": true,
    "advancedServices": {
       "data": true
    },
    ...
  }
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/userinfo.email"
    ],
  ...
}

サービス アカウントを実装する

  1. Google Cloud プロジェクトでサービス アカウントを作成します。これが課金プロジェクトになります。
  2. このサービス アカウントには、Cloud プロジェクトでの BigQuery へのアクセス権限が必要です。
    • 必要な Identity and Access Management(IAM)の役割: BigQuery Data ViewerBigQuery Job User
  3. JSON ファイルをダウンロードして、サービス アカウント キーを取得します。コネクタ プロジェクトのスクリプト プロパティにキーを保存します。
  4. Apps Script プロジェクトに Apps Script 向け OAuth2 ライブラリを含めます。
  5. サービス アカウントに必要な OAuth2 コードを実装します。
    var SERVICE_ACCOUNT_CREDS = 'SERVICE_ACCOUNT_CREDS';
    var SERVICE_ACCOUNT_KEY = 'private_key';
    var SERVICE_ACCOUNT_EMAIL = 'client_email';
    var BILLING_PROJECT_ID = 'project_id';
    
    /**
     * Copy the entire credentials JSON file from creating a service account in GCP.
     */
    function getServiceAccountCreds() {
      return JSON.parse(scriptProperties.getProperty(SERVICE_ACCOUNT_CREDS));
    }
    
    function getOauthService() {
      var serviceAccountCreds = getServiceAccountCreds();
      var serviceAccountKey = serviceAccountCreds[SERVICE_ACCOUNT_KEY];
      var serviceAccountEmail = serviceAccountCreds[SERVICE_ACCOUNT_EMAIL];
    
      return OAuth2.createService('RowLevelSecurity')
        .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth')
        .setTokenUrl('https://accounts.google.com/o/oauth2/token')
        .setPrivateKey(serviceAccountKey)
        .setIssuer(serviceAccountEmail)
        .setPropertyStore(scriptProperties)
        .setCache(CacheService.getScriptCache())
        .setScope(['https://www.googleapis.com/auth/bigquery.readonly']);
    }
    

getData() を実装する

  1. BigQuery クエリを作成します。
    • メールを使用して、メールとデータ間のマッピングを検索します。
    • JOIN または WHERE 句を使用して、データをフィルタ処理します。
  2. 有効なユーザーのメールアドレスを取得します(ユーザー ID についての記事を参照)。
  3. Looker Studio の Advanced Services を使用してクエリ構成を返します。 取得します。
    • 作成されたクエリ、課金プロジェクト、サービス アカウント OAuth トークンを渡します。
    • (条件付き必須)コネクタ getConfig を介してユーザー入力を取得している場合、入力を BigQuery パラメータとして組み込む必要があります。

ダッシュボードを作成する

  1. コネクタのデプロイとバージョンの仕組みを理解します。
  2. コネクタの本番環境デプロイを作成します。
  3. 本番環境デプロイを使用して、データソースと新しいレポートを Looker Studio です
  4. レポートにすべてのテーブルとグラフを追加します。
  5. ダッシュボードをユーザーと共有する次のステップに進みます。

ユーザーがダッシュボードを利用できるようにする

  1. 選択したユーザーまたは「リンクを知っている全員」にコネクタ スクリプトを共有します。
  2. 選択したユーザーまたは「リンクを知っている全員」にダッシュボードを共有します。
  3. (省略可)URL Shortener サービスを使用して、ダッシュボード URL のショートリンクを作成します。短縮 URL をユーザーに共有します。これにより、ダッシュボードの URL を必要に応じて後で置き換えることができます。
  4. (省略可)レポートに Google アナリティクスを設定して、ダッシュボードの使用状況を測定します。

サンプルコード