API を使用して、Cloud Storage に保存されている機密データを匿名化する

{}

このページでは、Cloud Data Loss Prevention API を使用して、Cloud Storage に保存された機密データを匿名化する方法について説明します。

このオペレーションは、ビジネス プロセスで使用するファイルに個人情報(PII)などの機密データが含まれていないことを確認するのに役立ちます。Cloud Data Loss Prevention では、機密データについて Cloud Storage バケット内のファイルを検査し、それらのファイルの匿名化されたコピーを別のバケット内に作成できます。それから、匿名化されたコピーをビジネス プロセスで使用できます。

ストレージ内のデータを匿名化する際の事象の詳細については、ストレージ内の機密データの匿名化をご覧ください。

始める前に

このページは、次のことを前提としています。

このオペレーションに関する制限事項と考慮事項について参照してください。

ストレージの検査には OAuth スコープ https://www.googleapis.com/auth/cloud-platform が必要です。詳細については、DLP API に対する認証をご覧ください。

必要な IAM のロール

このオペレーションのすべてのリソースが同じプロジェクトにある場合、サービス エージェントに対する DLP API サービス エージェントのロール(roles/dlp.serviceAgent)で十分です。そのロールを使用すると、次のことができます。

  • 検査ジョブを作成する
  • 入力ディレクトリ内のファイルを読み取る
  • 匿名化されたファイルを出力ディレクトリに書き込む
  • 変換の詳細を BigQuery テーブルに書き込む

関連するリソースには、検査ジョブ、匿名化テンプレート、入力バケット、出力バケット、変換の詳細テーブルが含まれます。

リソースを別のプロジェクトに用意する必要がある場合は、プロジェクトのサービス エージェントに次のロールも付与してください。

  • 入力バケットまたはそれを含むプロジェクトに対するストレージ オブジェクト閲覧者のロール(roles/storage.objectViewer)。
  • 出力バケットまたはバケットを含むプロジェクトに対するストレージ オブジェクト作成者のロール(roles/storage.objectCreator)。
  • 変換の詳細テーブルまたはテーブルを含むプロジェクトに対する BigQuery データ編集者のロール(roles/bigquery.dataEditor)。

サービス エージェント(Google 管理のサービス アカウント)にロールを付与するには、単一のロールを付与をご覧ください。次のレベルでアクセスを制御することもできます。

API の概要

Cloud Storage に保存されているコンテンツを匿名化するには、指定した基準に従って機密データを探索する検査ジョブを構成します。それから、検査ジョブ内で匿名化手順を Deidentify アクションの形式で提供します。

バケット内のファイルのサブセットのみをスキャンする場合は、ジョブがスキャンするファイルを制限できます。匿名化のあるジョブでサポートされているオプションは、タイプ(FileType)と正規表現(FileSet)によるファイル フィルタリングです。

Deidentify アクションを有効にすると、Cloud DLP のデフォルトでは、スキャンに含まれるサポートされているファイル形式がすべて変換されます。ただし、サポートされているファイル形式のサブセットのみを変換するようにジョブを構成できます。

省略可: 匿名化テンプレートを作成する

発見の変換方法を制御する場合は、次のテンプレートを作成します。これらのテンプレートでは、構造化ファイル、非構造化ファイル、画像での発見を変換できます。

  • 匿名化テンプレート:非構造化ファイル(自由形式のテキスト ファイルなど)に使用されるデフォルトの DeidentifyTemplate。このタイプの DeidentifyTemplate には、構造化コンテンツでのみサポートされている RecordTransformations オブジェクトを含めることはできません。このテンプレートが存在しない場合、Cloud DLP は ReplaceWithInfoTypeConfig メソッドを使用して非構造化ファイルを変換します。

  • 構造化匿名化テンプレート: CSV ファイルなどの構造化ファイルに使用する DeidentifyTemplate。この DeidentifyTemplate には RecordTransformations を含めることができます。このテンプレートが存在しない場合は、作成したデフォルトの匿名化テンプレートが使用されます。存在しない場合、Cloud DLP は ReplaceWithInfoTypeConfig メソッドを使用して構造化ファイルを変換します。

  • 画像秘匿化テンプレート: 画像に使用される DeidentifyTemplate。このテンプレートには、ImageTransformations オブジェクトを含める必要があります。このテンプレートが存在しない場合、Cloud DLP は画像内のすべての発見をブラック ボックスで秘匿化します。

詳しくは匿名化テンプレートの作成をご覧ください。

匿名化アクションを含む検査ジョブを作成する

DlpJob オブジェクトは、検査の対象、機密としてフラグを付けるデータの種類、検出結果の処理方法を指定します。Cloud Storage ディレクトリ内の機密データを匿名化するには、DlpJob で少なくとも次のものを定義する必要があります。

  • 検査する Cloud Storage ディレクトリを指定する StorageConfig オブジェクト。
  • InspectConfig オブジェクト。探索対象のデータのタイプと、機密データを発見するための追加の検査手順が含まれます。
  • 以下を含む Deidentify アクション。

    • TransformationConfig オブジェクト。構造化ファイルと非構造化ファイルのデータを匿名化するために作成した任意のテンプレートを指定します。画像の機密データを秘匿化するための構成を含めることもできます。

      TransformationConfig オブジェクトを含めない場合、Cloud DLP はテキスト内の機密データをその infoType に置き換えます。画像では、ブラック ボックスを使用して機密データを対象にします。

    • TransformationDetailsStorageConfig オブジェクト。Cloud DLP が各変換の詳細を保存する必要がある BigQuery テーブルを指定します。各変換の詳細には、説明、成功またはエラーコード、エラーの詳細、変換されたバイト数、変換されたコンテンツの場所、Cloud DLP が変換を行った検査ジョブの名前などがあります。このテーブルには、実際の匿名化されたコンテンツは保存されません。

    データが BigQuery テーブルに書き込まれると、課金と割り当て使用量は、宛先テーブルが含まれるプロジェクトに適用されます。

コピーしたコンテンツが匿名化されると、匿名化ジョブが終了します。ジョブには、指定した変換が適用された回数の概要が含まれます。これは、DlpJobprojects.dlpJobs.get メソッドを使用して取得できます。返される DlpJob には、DeidentifyDataSourceDetails オブジェクトと InspectDataSourceDetails オブジェクトの両方が含まれます。これらのオブジェクトには、それぞれ Deidentify アクションと検査ジョブの結果の両方が含まれます。

TransformationDetailsStorageConfig オブジェクトを DlpJob に含めると、変換の詳細に関するメタデータを含む BigQuery テーブルが作成されます。発生する変換ごとに、Cloud DLP は 1 行のメタデータをテーブルに書き込みます。テーブルの内容の詳細については、変換の詳細リファレンスをご覧ください。

サンプルコード

次の JSON の例では、Cloud Storage ディレクトリ内のファイルを匿名化する方法を示しています。

HTTP メソッドと URL

POST https://dlp.googleapis.com/v2/projects/PROJECT_ID/dlpJobs

JSON 入力

{
   "inspect_job": {
     "storage_config": {
       "cloud_storage_options": {
         "file_set": {
           "url": "INPUT_DIRECTORY"
         }
       }
     },
     "inspect_config": {
       "info_types": [
         {
           "name": "PERSON_NAME"
         }
       ]
     },
     "actions": {
       "deidentify": {
         "cloud_storage_output": "OUTPUT_DIRECTORY",
         "transformation_config": {
           "deidentify_template": "DEIDENTIFY_TEMPLATE_NAME",
           "structured_deidentify_template": "STRUCTURED_DEIDENTIFY_TEMPLATE_NAME",
           "image_redact_template": "IMAGE_REDACTION_TEMPLATE_NAME"
         },
         "transformation_details_storage_config": {
           "table": {
             "project_id": "TRANSFORMATION_DETAILS_PROJECT_ID",
             "dataset_id": "TRANSFORMATION_DETAILS_DATASET_ID",
             "table_id": "TRANSFORMATION_DETAILS_TABLE_ID"
           }
         },
         "fileTypesToTransform": ["IMAGE","CSV", "TEXT_FILE"]
       }
     }
   }
 }

次のように置き換えます。

  • PROJECT_ID: 検査 ジョブを保存するプロジェクトの ID
  • INPUT_DIRECTORY: 検査する Cloud Storage ディレクトリ(たとえば、gs://input-bucket/folder1/folder1a)。URL が末尾のスラッシュで終わる場合、INPUT_DIRECTORY 内のいかなるサブディレクトリもスキャンされません。
  • OUTPUT_DIRECTORY: 匿名化されたファイルを保存する Cloud Storage ディレクトリ。このディレクトリは、INPUT_DIRECTORY と同じ Cloud Storage バケット内に存在してはなりません。
  • DEIDENTIFY_TEMPLATE_NAME: 構造化ファイルと非構造化ファイル用のデフォルトの匿名化テンプレートの完全なリソース名(作成した場合)。この値は、形式 projects/projectName/(locations/locationId)/deidentifyTemplates/templateName にする必要があります。
  • STRUCTURED_DEIDENTIFY_TEMPLATE_NAME: 構造化ファイル用の匿名化テンプレートの完全なリソース名(作成した場合)。この値は、形式 projects/projectName/(locations/locationId)/deidentifyTemplates/templateName にする必要があります。
  • IMAGE_REDACTION_TEMPLATE_NAME: 画像用の秘匿化テンプレートの完全なリソース名(作成した場合)。この値は、形式 projects/projectName/(locations/locationId)/deidentifyTemplates/templateName にする必要があります。
  • TRANSFORMATION_DETAILS_PROJECT_ID: 変換の詳細を保存するプロジェクトの ID。
  • TRANSFORMATION_DETAILS_DATASET_ID: 変換の詳細を保存する BigQuery データセットの ID。テーブル ID を指定しない場合は、自動的に作成されます。
  • TRANSFORMATION_DETAILS_TABLE_ID: 変換の詳細を保存する BigQuery テーブルの ID。

以前の JSON の例では、次の点に留意してください。

  • inspectJob: ジョブの構成オブジェクト(DlpJob)。このオブジェクトには、検査ステージと匿名化ステージの両方の構成が含まれます。
  • storageConfig: 検査するコンテンツの場所(StorageConfig)。この例では、Cloud Storage バケット CloudStorageOptions を指定します。
  • inspectConfig: 検査する機密データに関する情報(InspectConfig )。この例では、組み込みinfoTypePERSON_NAME に一致するコンテンツを検査します。
  • actions: ジョブの検査部分が完了した後にとるアクション(Action)。
  • deidentify: このアクションを指定すると、内部で指定された構成に従って、Cloud DLP は一致した機密データを匿名化します(Deidentify)。
  • cloud_storage_output: 検査する Cloud Storage ディレクトリの URL を指定します。
  • transformation_config: Cloud DLP が、構造化ファイル、非構造化ファイル、画像の機密データを匿名化する方法を指定します(TransformationConfig)。

    TransformationConfig オブジェクトを含めない場合、Cloud DLP はテキスト内の機密データをその infoType に置き換えます。画像では、ブラック ボックスを使用して機密データを対象にします。

  • transformation_details_storage_config: このジョブに対して実行する各変換に関するメタデータを Cloud DLP が保存する必要があることを指定します。また、Cloud DLP がメタデータを保存する必要があるテーブルのロケーションと名前を指定します(TransformationDetailsStorageConfig)。

  • fileTypesToTransform: 匿名化オペレーションをリストするファイル形式のみに制限します。このフィールドを設定しない場合、検査オペレーションに含まれたサポート対象のすべてのファイル形式も匿名化オペレーションに含まれます。この例では、サポート対象のすべてのファイル形式を検査するように DlpJob を構成している場合でも、Cloud DLP は画像、CSV、テキスト ファイルのみを匿名化します。

検査ジョブを作成する

検査ジョブ(DlpJob)を作成するには、projects.dlpJobs.create リクエストを送信します。cURL を使用してリクエストを送信するには、前の例を JSON ファイルとして保存し、次のコマンドを実行します。

curl -s \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "X-Goog-User-Project: PROJECT_ID" \
https://dlp.googleapis.com/v2/projects/PROJECT_ID/dlpJobs \
-d @PATH_TO_JSON_FILE

次のように置き換えます。

  • PROJECT_ID: DlpJob を保存したプロジェクトの ID。
  • PATH_TO_JSON_FILE: リクエスト本文を含む JSON ファイルへのパス。

Cloud DLP は、新しく作成された DlpJob の識別子、そのステータス、設定した検査構成のスナップショットを返します。

{
  "name": "projects/PROJECT_ID/dlpJobs/JOB_ID",
  "type": "INSPECT_JOB",
  "state": "PENDING",
  ...
}

検査ジョブの結果を取得する

DlpJob の結果を取得するには、projects.dlpJobs.get リクエストを送信します。

curl -s \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "X-Goog-User-Project: PROJECT_ID" \
https://dlp.googleapis.com/v2/projects/PROJECT_ID/dlpJobs/JOB_ID

次のように置き換えます。

  • PROJECT_ID: DlpJob を保存したプロジェクトの ID。
  • JOB_ID: DlpJob を作成した際に返されたジョブの ID。

オペレーションが完了すると、次のようなレスポンスを受け取ります。

{
  "name": "projects/PROJECT_ID/dlpJobs/JOB_ID",
  "type": "INSPECT_JOB",
  "state": "DONE",
  "inspectDetails": {
    "requestedOptions": {
      "snapshotInspectTemplate": {},
      "jobConfig": {
        "storageConfig": {
          "cloudStorageOptions": {
            "fileSet": {
              "url": "INPUT_DIRECTORY"
            }
          }
        },
        "inspectConfig": {
          "infoTypes": [
            {
              "name": "PERSON_NAME"
            }
          ],
          "limits": {}
        },
        "actions": [
          {
            "deidentify": {
              "transformationDetailsStorageConfig": {
                "table": {
                  "projectId": "TRANSFORMATION_DETAILS_PROJECT_ID",
                  "datasetId": "TRANSFORMATION_DETAILS_DATASET_ID",
                  "tableId": "TRANSFORMATION_DETAILS_TABLE_ID"
                }
              },
              "transformationConfig": {
                "deidentifyTemplate": "DEIDENTIFY_TEMPLATE_NAME",
                "structuredDeidentifyTemplate": "STRUCTURED_DEIDENTIFY_TEMPLATE_NAME",
                "imageRedactTemplate": "IMAGE_REDACTION_TEMPLATE_NAME"
              },
              "fileTypesToTransform": [
                "IMAGE",
                "CSV",
                "TEXT_FILE"
              ],
              "cloudStorageOutput": "OUTPUT_DIRECTORY"
            }
          }
        ]
      }
    },
    "result": {
      "processedBytes": "25242",
      "totalEstimatedBytes": "25242",
      "infoTypeStats": [
        {
          "infoType": {
            "name": "PERSON_NAME"
          },
          "count": "114"
        }
      ]
    }
  },
  "createTime": "2022-06-09T23:00:53.380Z",
  "startTime": "2022-06-09T23:01:27.986383Z",
  "endTime": "2022-06-09T23:02:00.443536Z",
  "actionDetails": [
    {
      "deidentifyDetails": {
        "requestedOptions": {
          "snapshotDeidentifyTemplate": {
            "name": "DEIDENTIFY_TEMPLATE_NAME",
            "createTime": "2022-06-09T17:46:34.208923Z",
            "updateTime": "2022-06-09T17:46:34.208923Z",
            "deidentifyConfig": {
              "infoTypeTransformations": {
                "transformations": [
                  {
                    "primitiveTransformation": {
                      "characterMaskConfig": {
                        "maskingCharacter": "*",
                        "numberToMask": 25
                      }
                    }
                  }
                ]
              }
            },
            "locationId": "global"
          },
          "snapshotStructuredDeidentifyTemplate": {
            "name": "STRUCTURED_DEIDENTIFY_TEMPLATE_NAME",
            "createTime": "2022-06-09T20:51:12.411456Z",
            "updateTime": "2022-06-09T21:07:53.633149Z",
            "deidentifyConfig": {
              "recordTransformations": {
                "fieldTransformations": [
                  {
                    "fields": [
                      {
                        "name": "Name"
                      }
                    ],
                    "primitiveTransformation": {
                      "replaceConfig": {
                        "newValue": {
                          "stringValue": "[redacted]"
                        }
                      }
                    }
                  }
                ]
              }
            },
            "locationId": "global"
          },
          "snapshotImageRedactTemplate": {
            "name": "IMAGE_REDACTION_TEMPLATE_NAME",
            "createTime": "2022-06-09T20:52:25.453564Z",
            "updateTime": "2022-06-09T20:52:25.453564Z",
            "deidentifyConfig": {},
            "locationId": "global"
          }
        },
        "deidentifyStats": {
          "transformedBytes": "3972",
          "transformationCount": "110"
        }
      }
    }
  ],
  "locationId": "global"
}

次のステップ