GCP DLP の基本的な使い方
[履歴] [最終更新] (2021/05/19 23:41:20)
最近の投稿
注目の記事

概要

こちらのページで基本的な使い方を把握した GCP の Data Loss Prevention (DLP) サービスを用いると、文章や画像の中に含まれる、電話番号や氏名および住所といった、個人を特定し得る情報 Personally Identifiable Information (PII) の検出を行えます。更に追加の設定によって、検出した情報を消したり他の文字列で置き換えたり、ハッシュ化したり暗号化することもできます。DLP はその他の機能も備えていますが、ここでは上記の基本的な機能について使い方を記載します。

Inspection テンプレートの作成

PII の検出 Inspect を行うためのテンプレートを作成できます。Inspect API を実行する毎に、検出方法を設定することもできますが、テンプレートを作成しておきそれを Inspect API 実行時に指定することで、設定を毎回行う必要がなくなります。

Cloud Console の DLP UI を用いる場合は以下のようにします。

テンプレートを作成します。

Uploaded Image

「検査 (機密データの検索)」を選択します。

Uploaded Image

検出したい infoType を選択します。組み込みで用意されているものの一つ PERSON_NAME を選択してみます。

Uploaded Image

カスタム infoType を作成することもできます。ここでは簡単な「単語または語句」を選択してみます。

Uploaded Image

「日本語テスト」または「あいうえお」に合致する文章中の箇所を検知するための infoType として設定しました。

Uploaded Image

PERSON_NAME またはカスタムで作成した MY_INFO_TYPE_20210421_3 を検出するテンプレートが出来上がりました。

Uploaded Image

De-identification テンプレートの作成

PII を検出した箇所に対して、何らかの処理を行うためには de-identification API を利用します。

API の呼び出し時には inspectConfigdeidentifyConfig を指定します。

inspectConfig の代わりに inspectTemplateName を指定することができますが、同様に deidentifyConfig の代わりに deidentifyTemplateName を指定することもできます。

De-identification テンプレートの作成を DLP UI から行うためには以下のようにします。

匿名化 (機密データの削除) を選択します。

Uploaded Image

匿名化のための処理方法を設定します。ここでは「infoType 名での置換」を選択してみます。

Uploaded Image

「テスト」タブでテンプレートの動作確認を行えます。de-identification API を実行するためには inspectConfig または inspectTemplateName を指定する必要があり、DLP UI では、以下のテキストボックスで inspectTemplateName を指定します。

Uploaded Image

何も指定しない場合、DLP が既定で用意していると思われる inspectTemplatename が指定され、組み込みの infoType のみを全て検出するような挙動となります。以下の例のように「日本語テスト」および「あいうえお」が検出されなくなるのはそのためです。

Uploaded Image

API による de-identification 処理の実行

DLP UI における De-identification の「テスト」タブで行った処理を API Method: projects.content.deidentify で行うためには、以下のようにします。

dl-req.json

{
  "deidentifyConfig": {},
  "inspectConfig": {},
  "item": {
    "value": "日本語テスト。私の名前は鈴木太郎です。\nあいうえお、かきくけこ。"
  },
  "inspectTemplateName": "projects/my-project-20210328/locations/global/inspectTemplates/my-inspection-template-20210421-3",
  "deidentifyTemplateName": "projects/my-project-20210328/locations/global/deidentifyTemplates/my-deidentification-template-20210421-2"
}

実行例 (my-project-20210328 はお使いのプロジェクト ID に書き換えてください。)

curl -sS -XPOST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H 'Content-Type: applicaiton/json' \
  https://dlp.googleapis.com/v2/projects/my-project-20210328/content:deidentify \
  -d @dlp-req.json

{
  "item": {
    "value": "[MY_INFO_TYPE_20210421_3]。私の名前は[PERSON_NAME]です。\n[MY_INFO_TYPE_20210421_3]、かきくけこ。"
  },
  "overview": {
    "transformedBytes": "45",
    "transformationSummaries": [
      {
        "infoType": {
          "name": "MY_INFO_TYPE_20210421_3"
        },
        "transformation": {
          "replaceWithInfoTypeConfig": {}
        },
        "results": [
          {
            "count": "2",
            "code": "SUCCESS"
          }
        ],
        "transformedBytes": "33"
      },
      {
        "infoType": {
          "name": "PERSON_NAME"
        },
        "transformation": {
          "replaceWithInfoTypeConfig": {}
        },
        "results": [
          {
            "count": "1",
            "code": "SUCCESS"
          }
        ],
        "transformedBytes": "12"
      }
    ]
  }
}

API 実行のためには、ここではサービスアカウントを利用しています。「DLP 管理者」ロールを付与しても動きますが、上記 API 実行のための最小の権限は以下のようになります。

Uploaded Image

API 実行時に発生し得るエラー

NTP デーモンが動いていない場合

Docker コンテナ内などで gcloud を利用していると、以下のようなエラーに遭遇することがあります。これは、NTP デーモンが動いておらず時刻がずれているときに発生します。

gcloud auth activate-service-account --key-file ./my-project-20210328-04084aee5ee7.json

ERROR: (gcloud.auth.activate-service-account) There was a problem refreshing your current auth tokens: ('invalid_grant: Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim.', '{"error":"invalid_grant","error_description":"Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your iat and exp values in the JWT claim."}')

CentOS7 の場合は以下のようにして NTP デーモンをインストールして対処できます。

sudo yum -y install ntp
sudo systemctl start ntpd.service

ユーザアカウントを用いている場合

サービスアカウントではなくユーザアカウントを用いている場合は、以下のようなエラーが出ます。

curl -sS -XPOST -H "Authorization: Bearer $(gcloud auth print-access-token)" -H 'Content-Type: applicaiton/json' https://dlp.googleapis.com/v2/projects/my-project-20210328/content:deidentify -d @dlp-req.json

{
  "error": {
    "code": 403,
    "message": "Cloud Data Loss Prevention (DLP) API has not been used in project 32555940559 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/dlp.googleapis.com/overview?project=32555940559 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
    "status": "PERMISSION_DENIED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.Help",
        "links": [
          {
            "description": "Google developers console API activation",
            "url": "https://console.developers.google.com/apis/api/dlp.googleapis.com/overview?project=32555940559"
          }
        ]
      },
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "SERVICE_DISABLED",
        "domain": "googleapis.com",
        "metadata": {
          "consumer": "projects/32555940559",
          "service": "dlp.googleapis.com"
        }
      }
    ]
  }
}

X-Goog-User-Project ヘッダを付与することで対処できます。

curl -sS -XPOST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H 'X-Goog-User-Project: my-project-20210328' \
  -H 'Content-Type: applicaiton/json' https://dlp.googleapis.com/v2/projects/my-project-20210328/content:deidentify \
  -d @dlp-req.json

補足: Application Default Credentials (ADC) について

上記エラーについて、インターネットで情報を調べていると Application Default Credentials (ADC) および gcloud auth application-default login に関する記述が見つかります。

gcloud auth application-default login は開発時などに用いることが想定された機能です。

サービスアカウントの key ファイルを使用する想定のアプリケーションがある場合に、ユーザアカウントの権限で同等のファイルを生成して、アプリケーションから利用させることができます。

gcloud auth application-default login

以下の認証ファイルが生成されます。

/home/vagrant/.config/gcloud/application_default_credentials.json

サービスアカウントの場合は以下のように環境変数を設定して、アプリケーションに場所を教える必要がありますが、gcloud auth application-default login の場合は環境変数の設定は不要です。

export GOOGLE_APPLICATION_CREDENTIALS=/path/to/my-project-20210328-04084aee5ee7.json

application_default_credentials.json によって access token を生成することもできます。

curl -sS -XPOST -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H 'X-Goog-User-Project: my-project-20210328' \
  -H 'Content-Type: applicaiton/json' \
  https://dlp.googleapis.com/v2/projects/my-project-20210328/content:deidentify \
  -d @dlp-req.json

格納される infoType について

DLP のカスタム infoType には、Inspection テンプレートに内在するものと、そうでないものがあります。

Inspection テンプレートの外で定義できるカスタム infoType は「格納される infoType」と記載されています。

Uploaded Image

「単語A」および「単語B」に合致する箇所を検知する infoType と設定してみます。

Uploaded Image

Inspect テンプレートに対して、種類を「格納される infoType」とすることで紐付けることができます。「格納される infoType」の名前と、カスタム infoType の名前は同じである必要はありません。

Uploaded Image

Inspect テンプレートを De-Identification テンプレートで指定することで、確かに期待通りに動いていることが確認できます。

Uploaded Image

De-Identification で「格納される infoType」を指定するには以下のようにします。組み込みの infoType についても同様の設定が可能です。

Uploaded Image

指定していない infoType については、Inspection テンプレートが検知可能であっても、De-Identification テンプレートでは処理対象外となります。

Uploaded Image

Inspection テンプレートを指定しない場合は、DLP の既定の Inspection テンプレートが利用されることは前述のとおりです。その場合、既定の Inspection テンプレートは、「格納される infoType」を知らないため、以下のようなエラーとなります。

Uploaded Image

infoType による検知を特定の条件で除外したい場合

Inspection テンプレートにおける「検査ルールセット」を infoType に対して設定することで、特定の条件における検知を抑制することができます。

以下の例では「PERSON_NAME」infoType において「鈴木一郎」と「山田花子」を除外する設定となっています。

Uploaded Image

De-Identification テンプレートで確認すると、確かに期待通りに動いていることが分かります。

Uploaded Image

暗号化および復号処理

De-identification 処理のうち、Deterministic encryption using AES-SIV (CryptoDeterministicConfig) と Format preserving encryption (CryptoReplaceFfxFpeConfig) は、暗号化した結果を復号できます。

対称鍵の作成

暗号化および復号処理するためには、DLP の De-Identification テンプレートに対称鍵を登録します。例えば、以下のようにして対称鍵を生成します。

128/192/256 bit (16/24/32 byte) size のキーを指定する必要があります。

python で 16バイトのキーを生成するためには以下のようにできます。ASCII 1 byte を 16 文字分です。

python -c "f = open('mykey.bin', 'wb'); f.write('1234567812345678')"

サイズ確認 2byte x 8

$ od mykey.bin
0000000 031061 032063 033065 034067 031061 032063 033065 034067
0000020

openssl コマンドでも乱数から生成できます。

openssl rand 16 > mykey2.bin

$ od mykey2.bin
0000000 172051 155300 161372 167002 036714 116604 034746 143713
0000020

KMS キーの作成

上記の対称鍵を安全に GCP 上に保管するために、GCP KMS によって暗号化します。

KMS のキーは「キーリング」という鍵束の中に作成します。鍵束は以下のように作成します。

Uploaded Image

鍵束の中に鍵を作成します。

Uploaded Image

外部で作成した鍵をインポートすることもできますが、ここでは GCP 内で新規に対称鍵を生成することにします。簡単のため、鍵のローテーションも設定しません。

Uploaded Image

De-Identification テンプレートへの対称鍵の登録

作成した KMS 鍵を用いて、DLP 内で利用したい対称鍵を暗号化します。

gcloud kms encrypt --location=global \
  --keyring=my-keyring-20210423 \
  --key=my-key-20210423 \
  --plaintext-file=mykey2.bin \
  --ciphertext-file=mykey2-kms-wrapped.bin

DLP に鍵を登録するためには、base64 でエンコードする必要があります。

cat mykey2-kms-wrapped.bin | base64 -w0 && echo

先程作成した KMS 鍵のリソース名もコピーしておきます。

Uploaded Image

De-Identification テンプレートの「変換ルール」のうち、復号処理をサポートしている Deterministic encryption using AES-SIV (CryptoDeterministicConfig) を利用することにします。「仮名化 (暗号確定的トークン)」に該当します。

KMS キーのリソース名と、base64 エンコーディングした、KMS キーで暗号化 (ラップ) された対称鍵の二つを登録します。

更に「サロゲート infoType」というものも指定します。

Uploaded Image

正しく設定できていれば、以下のように変換されます。

Uploaded Image

復号できることの検証

API によって de-identification テンプレートを実行してみます。

dlp-req.json

{
  "deidentifyConfig": {
  },
  "inspectConfig": {
  },
  "item": {
    "value": "私の名前は田中一郎です。"
  },
  "inspectTemplateName": "projects/my-project-20210328/locations/global/inspectTemplates/my-inspection-template-20210421-3",
  "deidentifyTemplateName": "projects/my-project-20210328/locations/global/deidentifyTemplates/my-deidentification-template-20210421-2"
}

実行例

curl -sS -XPOST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H 'X-Goog-User-Project: my-project-20210328' \
  -H 'Content-Type: applicaiton/json' \
  https://dlp.googleapis.com/v2/projects/my-project-20210328/content:deidentify \
  -d @dlp-req.json

出力例

{
  "item": {
    "value": "私の名前はMY_SURROGATE(40):AYdLkcHd0L5YXbvQK2dLb0zIm8iuEwWNxyPCYXI=です。"
  },
  "overview": {
    "transformedBytes": "12",
    "transformationSummaries": [
      {
        "infoType": {
          "name": "PERSON_NAME"
        },
        "transformation": {
          "cryptoDeterministicConfig": {
            "cryptoKey": {
              "kmsWrapped": {
                "wrappedKey": "CiQAPSZCCAD9MULuOWYswkN7tdUEDt7Waxm2Ab+rb4IXtcztMG4SOQAOuO8KqOFhhNhV3M4hmNVVB7OfjqYufpE0gDxiUQQrJMwd+dqcc3o84RP3TehcF76iU7xLwBFTCg==",
                "cryptoKeyName": "projects/my-project-20210328/locations/global/keyRings/my-keyring-20210423/cryptoKeys/my-key-20210423"
              }
            },
            "surrogateInfoType": {
              "name": "MY_SURROGATE"
            }
          }
        },
        "results": [
          {
            "count": "1",
            "code": "SUCCESS"
          }
        ],
        "transformedBytes": "12"
      }
    ]
  }
}

これを復号するためには、以下のようにします。

dlp-req2.json

{
  "reidentifyConfig": {
  },
  "inspectConfig": {
    "customInfoTypes": [
      {
        "infoType": { "name": "MY_SURROGATE" },
        "surrogate_type": {}
      }
    ]
  },
  "item": {
    "value": "私の名前はMY_SURROGATE(40):AYdLkcHd0L5YXbvQK2dLb0zIm8iuEwWNxyPCYXI=です。"
  },
  "reidentifyTemplateName": "projects/my-project-20210328/locations/global/deidentifyTemplates/my-deidentification-template-20210421-2"
}

実行例

curl -sS -XPOST -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H 'X-Goog-User-Project: my-project-20210328' \
  -H 'Content-Type: applicaiton/json' \
  https://dlp.googleapis.com/v2/projects/my-project-20210328/content:reidentify \
  -d @dlp-req2.json

確かに復号できたことが確認できます。

{
  "item": {
    "value": "私の名前は田中一郎です。"
  },
  "overview": {
    "transformedBytes": "57",
    "transformationSummaries": [
      {
        "infoType": {
          "name": "MY_SURROGATE"
        },
        "transformation": {
          "cryptoDeterministicConfig": {
            "cryptoKey": {
              "kmsWrapped": {
                "wrappedKey": "CiQAPSZCCAD9MULuOWYswkN7tdUEDt7Waxm2Ab+rb4IXtcztMG4SOQAOuO8KqOFhhNhV3M4hmNVVB7OfjqYufpE0gDxiUQQrJMwd+dqcc3o84RP3TehcF76iU7xLwBFTCg==",
                "cryptoKeyName": "projects/my-project-20210328/locations/global/keyRings/my-keyring-20210423/cryptoKeys/my-key-20210423"
              }
            },
            "surrogateInfoType": {
              "name": "MY_SURROGATE"
            }
          }
        },
        "results": [
          {
            "count": "1",
            "code": "SUCCESS"
          }
        ],
        "transformedBytes": "57"
      }
    ]
  }
}

REST API ではなく python SDK を用いた例はこちらのページに記載があります。

dlp-req2.json で指定した customInfoTypes のリファレンスはこちらです。

Re-Identification API のリファレンスはこちらです。

De-Identification API と非常に良く似ていますが、inspectConfigcustomInfoTypes として「サロゲート infoType」を指定する必要があることに注意します。検知できないと Re-Identification 処理できないためです。

DLP の API をインターネットを経由せずに実行する設定

DLP API dlp.googleapis.com は VPC-SC の内部に閉じ込めることができます

*.googleapis.com へのアクセスを restricted.googleapis.com に向けるような DNS 設定を行うことで、VPC-SC の内部に存在する GCP サービスへのアクセスをインターネットを介さずに行うことができます

Cloud VPN や Cloud Interconnect を用いて VPC-SC 内の VPC をオンプレのネットワークと接続することで、オンプレのサーバからインターネットを介さずに DLP を含む GCP サービスにアクセスすることもできます。参考ドキュメント: Private Google Access with VPC Service Controls

関連ページ
    概要 Dataflow は Apache Beam のマネージドサービスです。大規模データの分散処理が可能になります。簡単な使い方を記載します。 Dataflow テンプレートを用いる場合 GCP が提供するデータ処理のテンプレートを利用すると、Apache Beam の使い方を把握していなくても Dataflow を利用できます。
    VPC-SC に閉じ込められた GCP サービスへの AWS からのアクセス VPC-SC に閉じ込めた GCP サービスに、AWS VPC 内の VM から直接アクセスするためには、以下の設定が必要になります。 AWS 内の DNS にて *.googleapis.com を restricted.googleapis.com