HIPAA 対応プロジェクトの設定

このチュートリアルでは、Google Cloud Healthcare Data Protection Toolkit の手順について説明します。このツールキットは、Google Cloud Platform(GCP)リソースをデプロイして、米国の医療保険の相互運用性と説明責任に関する法律(HIPAA: Health Insurance Portability and Accountability Act)で定義されている保護対象保健情報(PHI)を含む医療データを保存、処理するための自動化フレームワークです。このチュートリアルは、HIPAA に準拠した GCP Cloud Healthcare アーキテクチャについての記事とともに読むように構成されています。

概要

このチュートリアルは、GCP の使用を開始し、データ ストレージ、分析、アプリケーション開発用に GCP インフラストラクチャを構成する方法のサンプルを必要としている医療機関を対象としています。このセットアップには、適切なアクセスの構成、監査ログの保持、不審なアクティビティのモニタリングなど、医療データのセキュリティおよびプライバシーに関する多数のおすすめの方法が含まれています。これらのおすすめの方法の詳細は、GCP HIPAA ホワイト ペーパーをご覧ください。

このチュートリアルでは、PHI の保存および処理が可能な各種の GCP サービスについて説明しますが、すべての GCP リソースタイプとユースケースが網羅されているわけではありません。網羅的に扱うのではなく、このチュートリアルでは、主にリソースタイプのサブセットを取り上げて説明します。Google の業務提携契約(BAA)に基づく HIPAA コンプライアンスをサポートする GCP サービスのリストについては、Google Cloud Platform での HIPAA コンプライアンスをご覧ください。また、セキュリティプライバシーコンプライアンスに関連する GCP のドキュメントを確認することもできます。

免責条項

  • このチュートリアルはリファレンス アーキテクチャを説明するものであり、HIPAA またはその他のデータ プライバシーに関連する法律を準拠するために実施する必要がある、適切な、管理上、技術上および物理的な安全保護対策に基づく法的アドバイスを提供するものではありません。
  • このチュートリアルが扱う範囲は、対象範囲内のリソースによって保存されるデータの保護とモニタリングに限定されます。このチュートリアルの実施によって、他の Google Cloud Platform ストレージ サービスで保存または処理される派生データアセットを自動的にカバーするものではありません。派生データアセットについては、同様の保護措置を別途講じる必要があります。
  • このチュートリアル内の実装は、公式の Google プロダクトではありません。リファレンス用としての実装を目的として作成されています。コードは、Apache License、Version 2.0 で利用可能なオープンソース プロジェクトである Google Cloud Healthcare Data Protection Toolkit に含まれています。このフレームワークを開始点として使用し、ユースケースに応じて構成できます。GCP を基盤として作成される環境とアプリケーションが、HIPAA の要件に従って正しく構成され、保護されていることを確認する責任はユーザーが負うものとします。
  • このチュートリアルでは GitHub のコードのスナップショットを紹介しています。このスナップショットは時間の経過とともに更新または変更される可能性があります。リファレンス実装には、このチュートリアルで扱うもの以外にも多くのリソースタイプ(Cloud SQL インスタンスや Kubernetes クラスタなど)が含まれている場合があります。最新の適用範囲については、README ファイルをご覧ください。

目標

このチュートリアルは、HIPAA に対応した GCP プロジェクトを設定する Infrastructure as Code(IaC)のリファレンス実装の提供を目的としています。この実装により、次のプロセスが自動化されます。

料金

GCP では、期間限定の無料トライアルと無期限の Always Free 無料枠がお客様に提供されます。これらは、このチュートリアルで使用するいくつかのサービスに適用されます。詳細については、GCP の無料枠ページをご覧ください。

この実装の実行中に蓄積されるデータ量またはログ数によっては、無料トライアルまたは無料枠の制限を超えることなく、実装を完了できる場合があります。料金計算ツールを使用すると、予想使用量に基づいて費用の見積もりを作成できます。

このチュートリアルを終了した後に作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

  1. オンボーディングのベスト プラクティス ガイドを確認します。
  2. GCP での HIPAA コンプライアンスを確認します。
  3. PHI に関連して GCP サービスを使用している場合は、GCP で BAA を実行します。
  4. 基本的な GCP セットアップが完了していることを確認します。
  5. ベスト プラクティスに従って、お客様の組織の Cloud Identity をセットアップします。
  6. GCP の組織管理者を追加します。
  7. 請求先アカウントを設定します。

環境を初期化する

  1. shell で、Google Cloud Healthcare Data Protection Toolkit をダウンロードし、Python の依存関係をインストールします。

    pip install -r requirements.txt
    
  2. ツールと依存関係サービスをインストールします。

    • Bazel - オープンソースのビルドとテストのツール
    • pip - Python パッケージ用のパッケージ マネージャー
    • Cloud SDK - GCP でホストされているリソースとアプリケーションを管理するためのツールセット
    • Git - 分散バージョン管理システム
  3. 認証を設定します。

    gcloud auth login
    

デプロイ準備のチェックリスト

手順の開始前に、次の情報を書き留めておく必要があります。

GCP は、サポートされている G Suite ドメインまたは Cloud Identity ドメインの Google アカウントとグループ、パブリック Google グループを使用して、権限を制御します。GCP では、事前定義された役割の一連のグループを作成することがおすすめの方法です。これにより、プロジェクトを変更することなくグループ メンバーシップによって個々の権限を簡単に制御できます。

コンセプト ドキュメントに記載されているユーザー グループを作成するか、その存在を確認します。組織が G Suite のお客様である場合や、既存の GCP 組織のリソースのプロビジョニングにスクリプトの使用を予定している場合は、ユーザー グループについて管理者に問い合わせてください。管理者は Google 管理コンソールを使用してこの設定を行います。だれが管理者であるかを調べるには、Cloud Identity のヘルプを使用します。組織ユーザーは、Google Cloud Identity で設定されています。デフォルトでは、設定プロセスで admin として指定されたメール アカウントは Organization Admin に割り当てられます。このユーザーは、他の IAM 役割の作成と割り当てができます。データ転送、分析、セキュリティ監査に必要なさまざまなリソースへのアクセスは、IAM グループと関連付けられる役割によって制御されます。

さらに、デプロイ スクリプトを実行するユーザーは、セキュリティ プロジェクトをはじめとして、作成されるすべてのプロジェクトのオーナー グループに属している必要があります。デプロイが正常完了した後に、これらのグループからそのユーザーを削除できます。上の手順で作成した OWNERS_GROUP のメンバーとして現在使用しているユーザーを追加します。G Suite の管理コンソールにログインします。

また、商用アカウント以外でのテストを計画している場合は、Google グループを使用できます。

各 Google グループを作成します。その際に基本的なアクセス許可については次に示すセキュアな設定を使用します。

  • グループタイプ: メーリング リスト
  • トピックの表示: グループのすべてのメンバー(およびマネージャー)
  • 投稿: マネージャーとオーナーのみ
  • グループへの参加: 招待されたユーザーのみ

環境情報の収集とプロジェクト リソースの命名

構成ファイルは YAML 形式です。作成する各リソースとそのそれぞれのプロパティをリストします。多数のサンプル構成ファイルから選択できます。このファイルのリストは随時拡張されます。リモート監査ログ構成ファイルの使用をおすすめします。

overall セクションには、すべてのプロジェクトに適用される organizationbilling の詳細が格納されます。

  • audit_logs_project セクションで監査ログをホストするプロジェクトを定義します。
  • forseti セクションで Forseti リソースをホストするプロジェクトを定義します。
  • 必要なすべてのデータ ホスティング プロジェクトを projects の下にリストします。

GCP 環境の次の情報を収集し、ファイルを更新します。

パラメータ 値のサンプル
organization_id 12345678
billing_account 000000-000000-000000
location US、EU、Asia(BigQuery およびクラウド ストレージの場合)

デフォルト設定は、US、EU、Asia の境界内の複数リージョンのデータ ストレージです。
Ttl days audit_logs セクションのこのフィールドは、監査ログの保持時間を決定します。

365 などの値です。
project_id 3 つのプロジェクトに一意の名前を付けます。

  1. audit_logs_project
  2. Forseti
  3. データセット プロジェクト (projects.project_id)
stackdriver_alert_email [your admin email id]
owners_group hipaa-sample-project-owner@google.com
auditors_group hipaa-sample-project-auditor@google.com
data_readwrite_groups hipaa-sample-project-readwrite@google.com
data_readonly_groups hipaa-sample-project-readonly@google.com

このツールキットを使用すると、一貫した命名規則やリソースのラベル付けなどのおすすめの方法に準拠できます。プロジェクト名、Cloud Storage バケットと BigQuery データセット名、VPC 名を決定します。命名で推奨される方法については、次のドキュメントをご覧ください。

次を使用して必要な情報を収集します。これらの情報は、デプロイ構成ファイルに追加できます。命名規則の設定の際は、次に示す例を参考にしてください。

  • 会社名: Altostrat Company: altoco
  • ビジネス ユニット: 人事部: hr
  • アプリケーション コード: 給与システム: comp
  • リージョン コード: northamerica-northeast1: na-ne1、europe-west1: eu-we1
  • 環境コード: dev、test、uat、stage、prod
パラメータ 命名規則のサンプル
project_id プロジェクトの命名規則を決定します。

例:
{org-name}-{app/bu/purpose}-{environment}

altoco-edw-prod

audit_logs_project セクションで監査ログをホストするプロジェクトを定義します。

forseti セクションで Forseti リソースをホストするプロジェクトを定義します。

必要なすべてのデータ ホスティング プロジェクトを projects の下にリストします。
{storage_name} バケット名 例: {org-name hash}-{source}-{type}-{bu/region}-{seq#}

08uy6-cerner-inpatient-east-1

組織名のハッシュを使用して、セキュリティを強化します。
BigQuery データセット名 例: {org-name}_{bu/region}_{app/module}

altoco_east_edw
VPC 名 例:
{org-name}-{bu/region}-{environment}-{seq#}

altoco-east-prod-vpc-1

スクリプトを理解する

Google Cloud Healthcare Data Protection Toolkit では、大まかには、Cloud Foundation Toolkit テンプレートとカスタム ロジックを適宜使用して、リソースのプロビジョニング、おすすめの方法に従った IAM とロギングの設定、Forseti のモニタリングの有効化が行われます。

ヘルパー スクリプト

メインのヘルパー スクリプト apply.go は、YAML 構成ファイルから構成を読み取り、構成ファイルにリストされているプロジェクトを作成または変更します。このスクリプトによって、監査ログ プロジェクトと Forseti プロジェクトが作成されます。次に、このスクリプトは、projects にリストされている各プロジェクトにデータ ホスティング プロジェクトを作成します。このスクリプトでは、以下が実行されます。

  • プロジェクトの作成(プロジェクトがまだ存在しない場合)。
  • プロジェクトでの課金の有効化。
  • Deployment Manager API を有効にし、Deployment Manager サービス アカウントにオーナーとストレージ管理者の一時的なアクセス権限を付与。
  • 2 つのデプロイメントの作成。
    • data-protect-tookit-resources: このデプロイメントには、プロジェクトに存在するすべてのリソースが含まれます。
    • data-protect-toolkit-audit-${PROJECT_ID}: このデプロイメントには、データ プロジェクトのすべての監査リソースが含まれます。リモート監査ログ プロジェクトが指定されている場合、このデプロイメントはリモート プロジェクトで作成されます。それ以外の場合、このデプロイメントはデータ プロジェクト内で作成され、監査ログをローカルでホストします。
  • Forseti モニタリング リソースの作成。
  • ワークスペースを作成または選択するよう求めるメッセージの表示。この操作は、Stackdriver Monitoring を使用して行う必要があります。詳細については、Stackdriver ガイドをご覧ください。
  • セキュリティ ルールのモニタリングに使用される Stackdriver アラートの作成。

ヘルパー スクリプト rule_generator.go は、YAML 構成ファイルとメインのヘルパー スクリプト apply.go によって生成された追加の生成フィールドから構成を読み取り、Forseti ルールを生成して、ローカル ディレクトリまたは Cloud Storage バケットに書き込みます。

スクリプトを実行する

Data Protection Toolkit では、構成ファイルを使用して単一のデプロイメントに必要なすべてのリソースを記述します。構成ファイルは YAML 形式です。作成する各リソースとそのそれぞれのプロパティをリストします。

  1. ルートフォルダにサンプルの構成ファイルをコピーします。

  2. ./healthcare/deploy フォルダで作業していることを確認してください。

    cp ./samples/project_with_remote_audit_logs.yaml .
    nano project_with_remote_audit_logs.yaml
    
  3. 構成ファイルの適切な場所で以前に収集したパラメータを更新します。

メインのヘルパー スクリプト apply.go のパラメータは、次のように定義されます。

--config_path
デプロイ構成への相対パスまたは絶対パス。
--projects
デプロイ構成のプロジェクト ID のコンマ区切りリスト。このパラメータをスキップして、デプロイ構成にリストされているすべてのプロジェクトを指定することもできます。このスクリプトは、新しいプロジェクトを作成し、既存のプロジェクトを更新します。
--output_path
プロジェクト番号や Forseti サービス アカウントなど、デプロイ スクリプトによってデプロイ プロセス中に生成されるフィールド出力先のパス。
--dry_run
ドライランの指定に使用。--dry_run を省略した場合は、標準実行が指定されます。

ヘルパー スクリプト rule_generator.go のパラメータは、次のように定義されます。

--config_path
デプロイ構成への相対パスまたは絶対パス。
--generated_fields_path
プロジェクト番号や Forseti サービス アカウントなど、デプロイ スクリプトによってデプロイ プロセス中に生成されるフィールド出力先のパス。
--output_path
ルール生成スクリプトがルールファイルを出力する先のパス。ローカル ディレクトリまたは Cloud Storage バケットを設定できます。設定がない場合は、Forseti サーバー バケットに直接書き込まれます。

ドライラン モード

ドライランを実行すると、指定されたデプロイ構成でそのスクリプトによって実行される内容がすべて確認できますが、実際には実行されません。デプロイが実際に実行されたときに期待どおりに実行されるかどうかを確認できます。

bazel run cmd/apply:apply -- \
    --config_path=[CONFIG_FILE] \
    --projects=[PROJECTS] \
    --output_path=[OUTPUT_FILE] \
    --dry_run

プロジェクト作成モード

ドライラン実行でコマンドを確認しデプロイを実行する準備ができたら、--dry_run パラメータを指定しないでスクリプトを実行します。

bazel run cmd/apply:apply -- \
    --config_path=[CONFIG_FILE] \
    --projects=[PROJECTS] \
    --output_path=[OUTPUT_FILE]

更新モード

既存のプロジェクトにリソースを追加する場合や、既存の設定を変更する場合は、--projects フラグで以前にデプロイされたプロジェクトを指定します。

bazel run cmd/apply:apply -- \
    --config_path=[CONFIG_FILE] \
    --projects=[PROJECTS] \
    --output_path=[OUTPUT_FILE]

ルール生成

メイン スクリプトを使用して Forseti プロジェクトをデプロイ済みの場合、ルール生成スクリプトを実行してルールを生成およびアップロードできます。デフォルトでは、ルールは Forseti サーバー バケットにアップロードされます。独自の Forseti ルールセットを作成する場合は、この手順をスキップします。

bazel run cmd/rule_generator:rule_generator -- \
    --config_path=[CONFIG_FILE] \
    --generated_fields_path=[OUTPUT_FILE]

結果の確認

ヘルパー スクリプトを使用すれば、多数のコマンドをカプセル化できます。このセクションでは、スクリプトを正常に実行した後に期待される GCP Console における結果について説明します。

GCP Console

次のように、GCP Console でプロジェクトを利用できます。

GCP Console に表示されているプロジェクト

Cloud IAM コンソール

IAM コンソールには、プロジェクトごとにプロジェクトのオーナーとして OWNERS_GROUP、プロジェクトのセキュリティ審査担当者として AUDITORS_GROUP がそれぞれ表示されます。

Console のプロジェクトに対する権限

上の図では、OWNERS_GROUPAUDITORS_GROUP のメンバーだけが表示されていました。しかし、多くの場合、プロジェクトで有効にしている API に基づいて、プロジェクト レベルのアクセス権があるサービス アカウントもいくつか表示されます。最も一般的なサービス アカウントは次のとおりです。

-   <code><var>project_number</var>@cloudservices.gserviceaccount.com</code>
    is a
    [Google-managed service account](/iam/docs/service-accounts#google-managed_service_accounts){: track-type="tutorial" track-name="internalLink" track-metadata-position="body" }
    used by Google API service agents such as the Deployment Manager API.
-   <code><var>project_number</var>-compute@developer.gserviceaccount.com</code>
    is a
    [user-managed service account](/iam/docs/service-accounts#user-managed_service_accounts){: track-type="tutorial" track-name="internalLink" track-metadata-position="body" }
    used by the Compute Engine API.
-   <code>service-<var>project_number</var>@containerregistry.iam.gserviceaccount.com</code>
    is the
    [Container Registry service account](/container-registry/docs/overview#container_registry_service_account){: track-type="tutorial" track-name="internalLink" track-metadata-position="body" }.

ストレージ ブラウザ

ストレージ ブラウザには、ログを保存するために新しく作成されたバケットが表示されます。バケット名、ストレージ クラス、およびロケーションはすべて、デプロイ構成に従います。この例は、ローカルログ配置を示しています。リモートログ配置では、バケットとデータは異なるプロジェクトに存在し、すべてのデータ プロジェクトのログがローカルログ モードにありながらも統合されます。各プロジェクトには独自のログバケットが存在します。

ローカルログ モードですべてのデータ プロジェクトのログを統合する

ライフサイクル

ログバケットではライフサイクルが有効になっています。ライフサイクル ポリシーを表示して、オブジェクトのデプロイ構成の ttl_days で指定されている値より古いオブジェクトに削除アクションが指定されていることを確認します。

ライフサイクル ポリシーの表示

  • cloud-storage-analytics@google.com の権限とは別に、残りの権限は指定どおりに設定されます。cloud-storage-analytics@google.com がバケットへの書き込みアクセスを必要とする理由を理解するには、ログのドキュメントをご覧ください。

    書き込み権限を持つグループ

  • ストレージ ブラウザには、データを保存するために新しく作成されたバケットが表示されます。バケットの名前デフォルトのストレージ クラス、およびロケーションはデプロイ構成の仕様と一致します。

    新しく作成されたバケット

  • 各データバケット内のオブジェクトはバージョン管理されます。次のコマンドを実行して確認します。ここで、bucket_name はバケットの名前に置き換えてください。

    gsutil versioning get gs://bucket_name
    
  • データバケットのアクセスログおよびストレージログがキャプチャされてログバケットに保存されていること、およびデータバケットが作成されたときにロギングが開始されたことを確認します。次のコマンドを実行して確認します。

    gsutil logging get gs://bucket_name
    
  • 各バケットの権限は、仕様に従って設定されます。

    バケットへの書き込み権限を持つグループ

管理コンソール

管理コンソールで、すべてのサービスのデータ アクセスログがオンになっています。

管理コンソールのデータアクセス ログ

API Console

API Console で、BigQuery API が有効になっていることを確認します。

API Console で BigQuery API を有効にする

BigQuery コンソール

BigQuery コンソールで、Stackdriver がクラウド監査ログをシンクするデータセットが表示されていることを確認します。また、[説明]、[データセット ID]、[データのロケーション] の値が、以前に表示されたデプロイ構成とロギング エクスポート シンクの指定と一致していることも確認してください。

Cloud 監査ログのシンク先であるデータセットを BigQuery コンソールで表示する

データセットへのアクセスがユーザーの指定どおりに設定されていることを確認します。

また、Stackdriver のログを BigQuery にストリーミングするサービス アカウントに、データセットに対する編集権限が付与されていることを確認します。

BigQuery データ権限

データを格納するために新しく作成されたデータセットが表示されていること、および [説明]、[データセット ID]、[データのロケーション] の各値ならびに各データセットのラベルがデプロイ構成の指定と一致していることを確認します。

BigQuery コンソールで新しく作成されたデータセットを表示する

データセットへのアクセスが指定どおりに設定されていることを確認します。プロジェクトで有効にしている API によっては、継承による権限を持つ他のサービス アカウントが表示される可能性があります。

データを保存するための BigQuery のデータ権限

Cloud Pub/Sub コンソール

Cloud Pub/Sub コンソールに新しく作成されたトピックが表示され、トピック名、サブスクリプションのリスト、各サブスクリプションの詳細([配信タイプ] や [確認応答期限] など)がデプロイ構成の指定と一致していることを確認します。

トピックに対するアクセス権がデプロイ構成と一致していることも確認します。たとえば、次のスクリーンショットは、トピックのオーナーシップを継承している OWNERS_GROUP や、トピックの編集者の役割を持つ READ_WRITE_GROUP を示しています。プロジェクトで有効にしている API によっては、継承による権限を持つ他のサービス アカウントが表示される可能性があります。

Cloud Pub/Sub コンソールで新しく作成されたトピックを表示する

ロギング コンソール

ロギング コンソールで、新しいエクスポート シンクが表示されていることを確認します。[出力先] と [書き込み ID] の値を書き留めて、次の手順の BigQuery コンソールに表示されるものと比較します。

新しいエクスポート シンクを表示するロギング コンソール

ログベースの指標が監査ログ内の不審なアクティビティのインシデントをカウントするように設定されていることを確認します。

不審なアクティビティのインシデントをカウントするように設定されたログベースの指標を Stackdriver Logging コンソールで表示する

Stackdriver Alerting コンソール

Stackdriver Monitoring に、対応するログベースの指標のアラート ポリシーが含まれていることを確認します。

  1. Google Cloud Platform Console で、[モニタリング] に移動します。

    Stackdriver Monitoring

  2. [Alerting] メニューで、[Policies overview] を選択します。

対応するログベースの指標に基づいてトリガーされるアラート ポリシーを Stackdriver Alerting コンソールで表示する

クエリログ

BigQuery にストリーミングされた監査ログに対して次の SQL クエリを使用すると、不審なアクティビティの種類ごとにログ履歴を時系列順に整理できます。BigQuery エディタで、あるいは BigQuery コマンドライン インターフェースを介して、このクエリを開始点として使用し、要件を満たすように作成したクエリを定義します。

```sql
SELECT timestamp,
       resource.labels.project_id                              AS project,
       protopayload_auditlog.authenticationinfo.principalemail AS offender,
       'IAM Policy Tampering'                                  AS offenseType
FROM   `hipaa-sample-project.cloudlogs.cloudaudit_googleapis_com_activity_*`
WHERE  resource.type = "project"
       AND protopayload_auditlog.servicename =
           "cloudresourcemanager.googleapis.com"
       AND protopayload_auditlog.methodname = "setiampolicy"
UNION DISTINCT
SELECT timestamp,
       resource.labels.project_id                              AS project,
       protopayload_auditlog.authenticationinfo.principalemail AS offender,
       'Bucket Permission Tampering'                           AS offenseType
FROM   `hipaa-sample-project.cloudlogs.cloudaudit_googleapis_com_activity_*`
WHERE  resource.type = "gcs_bucket"
       AND protopayload_auditlog.servicename = "storage.googleapis.com"
       AND ( protopayload_auditlog.methodname = "storage.setiampermissions"
              OR protopayload_auditlog.methodname = "storage.objects.update" )
UNION DISTINCT
SELECT timestamp,
       resource.labels.project_id                              AS project,
       protopayload_auditlog.authenticationinfo.principalemail AS offender,
       'Unexpected Bucket Access'                              AS offenseType
FROM   `hipaa-sample-project.cloudlogs.cloudaudit_googleapis_com_data_access_*`
WHERE  resource.type = 'gcs_bucket'
       AND ( protopayload_auditlog.resourcename LIKE
             '%hipaa-sample-project-logs'
              OR protopayload_auditlog.resourcename LIKE
                 '%hipaa-sample-project-bio-medical-data' )
       AND protopayload_auditlog.authenticationinfo.principalemail NOT IN(
           'user1@google.com', 'user2@google.com' )
```

次の画像は、BigQuery コマンドライン インターフェースを使用してクエリを実行したときの結果の例を示しています。

BigQuery コマンドライン インターフェースを使用してクエリを実行した際のサンプル結果

クリーンアップ

  1. GCP Console で [リソースの管理] ページに移動します。

    [リソースの管理] ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ