Cloud Data Loss Prevention の概要

1. 概要

Cloud Data Loss Prevention(DLP)は、機密情報を検出、分類、保護できるようにするためのフルマネージド サービスです。この Codelab では、Cloud DLP API の基本的な機能の一部を紹介し、API を使用してデータを保護するさまざまな方法を説明します。

演習内容

  • DLP を使用して文字列とファイルを調べ、情報タイプが一致しているかどうかを確認する
  • 匿名化手法について学び、DLP を使用してデータを匿名化する
  • フォーマット保持暗号化(FPE)を使用して匿名化されたデータを元に戻す方法について説明します
  • DLP を使用して文字列と画像から情報タイプを秘匿化する

必要なもの

  • 課金が設定されている Google Cloud プロジェクト。お持ちでない場合は、作成する必要があります。

2. 設定方法

この Codelab は、ローカルでのインストールや構成を行わずに、Google Cloud Platform 上で完全に実行できます。

Cloud Shell

この Codelab では、Cloud Shell を介してコマンドラインを使用して、さまざまなクラウド リソースとサービスをプロビジョニングして管理します。

コンパニオン プロジェクト リポジトリをダウンロードします。

git clone https://github.com/googleapis/nodejs-dlp

プロジェクト コードをダウンロードしたら、サンプル ディレクトリに移動し、必要な Node.js パッケージをインストールします。

cd samples && npm install

次の gcloud コマンドを使って、正しいプロジェクトを設定します。

gcloud config set project [PROJECT_ID]

API を有効にする

プロジェクトで有効にする必要がある API は次のとおりです。

  • Cloud Data Loss Prevention API - テキスト、画像、Google Cloud Platform ストレージ リポジトリ内のプライバシー センシティブなフラグメントの検出、リスク分析、匿名化のための手法が提供されます。
  • Cloud Key Management Service(KMS)API - Google Cloud KMS を使用すると、暗号鍵を管理し、それらの鍵を使用して暗号オペレーションを実行できます。

次の gcloud コマンドを使用して、必要な API を有効にします。

gcloud services enable dlp.googleapis.com cloudkms.googleapis.com \
--project ${GOOGLE_CLOUD_PROJECT}

3. 文字列とファイルを調べる

前の手順でダウンロードしたプロジェクトのサンプル ディレクトリには、Cloud DLP のさまざまな機能を利用する JavaScript ファイルがいくつか含まれています。inspect.js は、指定された文字列またはファイルを調べて機密情報の種類を検出します。

これをテストするには、string オプションと、機密情報が含まれている可能性のあるサンプル文字列を指定します。

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'My email address is jenny@somedomain.com and you can call me at 555-867-5309'

出力には、一致した情報タイプごとに検出結果が表示されます。これには以下が含まれます。

見積もり: テンプレートで指定されている

infoType: 文字列のその部分で検出された情報タイプ。考えられる情報タイプの完全なリストについては、こちらをご覧ください。デフォルトでは、inspect.jsCREDIT_CARD_NUMBERPHONE_NUMBEREMAIL_ADDRESS の情報タイプのみを検査します。

可能性: 結果は、一致の可能性に基づいて分類されます。可能性は VERY_UNLIKELYVERY_LIKELY の範囲で指定できます。

上記コマンド リクエストの調査結果は次のとおりです。

Findings:
        Quote: jenny@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY
        Quote: 555-867-5309
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY

同様に、ファイルで情報の種類を調べることができます。サンプル accounts.txt ファイルを確認します。

resources/accounts.txt

My credit card number is 1234 5678 9012 3456, and my CVV is 789.

inspect.js をもう一度実行します。今回はファイル オプションを指定します。

node inspect.js -c $GOOGLE_CLOUD_PROJECT file resources/accounts.txt

結果:

Findings:
        Quote: 5678 9012 3456
        Info type: CREDIT_CARD_NUMBER
        Likelihood: VERY_LIKELY

どちらの種類のクエリでも、可能性または情報タイプで結果を制限できます。次に例を示します。

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'Call 900-649-2568 or email me at anthony@somedomain.com' \
-m VERY_LIKELY

最小の可能性を VERY_LIKELY に指定すると、VERY_LIKELY 未満の一致は除外されます。

Findings:
        Quote: 900-649-2568
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY

制限なしの完全な結果は次のようになります。

Findings:
        Quote: 900-649-2568
        Info type: PHONE_NUMBER
        Likelihood: VERY_LIKELY
        Quote: anthony@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY

同様に、チェックする情報タイプを指定することもできます。

node inspect.js -c $GOOGLE_CLOUD_PROJECT \
string 'Call 900-649-2568 or email me at anthony@somedomain.com' \
-t EMAIL_ADDRESS

指定された情報タイプが見つかった場合にのみ返されます。

Findings:
        Quote: anthony@somedomain.com
        Info type: EMAIL_ADDRESS
        Likelihood: LIKELY

以下は、API を使用して入力を調べる非同期関数です。

inspect.js

async function inspectString(
  callingProjectId,
  string,
  minLikelihood,
  maxFindings,
  infoTypes,
  customInfoTypes,
  includeQuote
) {
...
}

上記のパラメータに指定された引数は、リクエスト オブジェクトの構築に使用されます。そのリクエストは inspectContent 関数に提供され、出力につながるレスポンスが取得されます。

inspect.js

  // Construct item to inspect
  const item = {value: string};

  // Construct request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    inspectConfig: {
      infoTypes: infoTypes,
      customInfoTypes: customInfoTypes,
      minLikelihood: minLikelihood,
      includeQuote: includeQuote,
      limits: {
        maxFindingsPerRequest: maxFindings,
      },
    },
    item: item,
  };
...
...
 const [response] = await dlp.inspectContent(request);

4. 匿名化

Cloud DLP では、機密データの検査と検出だけでなく、匿名化を行うこともできます。匿名化とは、個人を特定できる情報をデータから削除するプロセスです。この API は、情報の種類で定義された機密データを検出し、匿名化変換を使用してデータのマスキングや削除、難読化を行います。

deid.js は、さまざまな方法で匿名化を行います。最も簡単な匿名化方法は、マスクを使用することです。

node deid.js deidMask -c $GOOGLE_CLOUD_PROJECT \
"My order number is F12312399. Email me at anthony@somedomain.com"

マスクを使用すると、一致する情報タイプの文字が別の文字(デフォルトでは「*」)に置き換えられます。出力は次のようになります。

My order number is F12312399. Email me at *****************************

文字列内のメールアドレスは難読化されていますが、任意の注文番号はそのままです。(カスタムの情報タイプも使用可能ですが、この Codelab の範囲外です)。

DLP API を使用してマスクで匿名化する関数を見てみましょう。

deid.js

async function deidentifyWithMask(
  callingProjectId,
  string,
  maskingCharacter,
  numberToMask
) {
...
}

これらの引数もリクエスト オブジェクトを構築するために使用されます。ここでは deidentifyContent 関数に提供されます。

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              characterMaskConfig: {
                maskingCharacter: maskingCharacter,
                numberToMask: numberToMask,
              },
            },
          },
        ],
      },
    },
    item: item,
  };
... 
... 
const [response] = await dlp.deidentifyContent(request);

フォーマット保持暗号化で匿名化する

DLP API には、暗号鍵を使用して機密データの値を暗号化する機能もあります。

まず、Cloud KMS を使用してキーリングを作成します。

gcloud kms keyrings create dlp-keyring --location global

これで、データの暗号化に使用する鍵を作成できます。

gcloud kms keys create dlp-key \
--purpose='encryption' \
--location=global \
--keyring=dlp-keyring

DLP API は、作成した KMS 鍵で暗号化されたラップされた鍵を受け入れます。ラップされるランダムな文字列を生成できます。この情報は、後で再識別を行う際に必要になります。

export AES_KEY=`head -c16 < /dev/random | base64 -w 0`

これで、KMS 鍵を使用して文字列を暗号化できます。これにより、暗号化された文字列を暗号テキストとして含むバイナリ ファイルが生成されます。

echo -n $AES_KEY | gcloud kms encrypt \
--location global \
--keyring dlp-keyring  \
--key dlp-key \
--plaintext-file - \
--ciphertext-file ./ciphertext.bin 

deid.js を使用して、次のサンプル文字列の電話番号を暗号化して匿名化できます。

node deid.js deidFpe -c $GOOGLE_CLOUD_PROJECT \
"My client's cell is 9006492568" `base64 -w 0 ciphertext.bin` \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key \
-s PHONE_NUMBER

出力では、一致した情報タイプが暗号化された文字列に置き換えられ、-s フラグで示された情報タイプが先頭に付加された文字列が返されます。

My client's cell is PHONE_NUMBER(10):vSt55z79nR

文字列の匿名化に使用する関数を見てみましょう。

deid.js

async function deidentifyWithFpe(
  callingProjectId,
  string,
  alphabet,
  surrogateType,
  keyName,
  wrappedKey
) {
...
}

引数は cryptoReplaceFfxFpeConfig オブジェクトの構築に使用されます。

deid.js

  const cryptoReplaceFfxFpeConfig = {
    cryptoKey: {
      kmsWrapped: {
        wrappedKey: wrappedKey,
        cryptoKeyName: keyName,
      },
    },
    commonAlphabet: alphabet,
  };
  if (surrogateType) {
    cryptoReplaceFfxFpeConfig.surrogateInfoType = {
      name: surrogateType,
    };
  }

cryptoReplaceFfxFpeConfig オブジェクトは、deidentifyContent 関数を介して API へのリクエストで使用されます。

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: cryptoReplaceFfxFpeConfig,
            },
          },
        ],
      },
    },
    item: item,
  };

  try {
    // Run deidentification request
    const [response] = await dlp.deidentifyContent(request);

データを再識別する

データを再識別するために、DLP API は前の手順で作成した暗号文を使用します。

node deid.js reidFpe -c $GOOGLE_CLOUD_PROJECT \
"<YOUR_DEID_OUTPUT>" \
PHONE_NUMBER `base64 -w 0 ciphertext.bin`  \
projects/${GOOGLE_CLOUD_PROJECT}/locations/global/keyRings/dlp-keyring/cryptoKeys/dlp-key

出力は、編集やサロゲート型が示されていない元の文字列になります。

My client's cell is 9006492568

データの再識別に使用される関数は、データの匿名化に使用される関数と似ています。

deid.js

async function reidentifyWithFpe(
  callingProjectId,
  string,
  alphabet,
  surrogateType,
  keyName,
  wrappedKey
) {
...
}

ここでも、引数は API へのリクエストで使用されます。今回は reidentifyContent 関数へのリクエストです。

deid.js

  // Construct deidentification request
  const item = {value: string};
  const request = {
    parent: dlp.projectPath(callingProjectId),
    reidentifyConfig: {
      infoTypeTransformations: {
        transformations: [
          {
            primitiveTransformation: {
              cryptoReplaceFfxFpeConfig: {
                cryptoKey: {
                  kmsWrapped: {
                    wrappedKey: wrappedKey,
                    cryptoKeyName: keyName,
                  },
                },
                commonAlphabet: alphabet,
                surrogateInfoType: {
                  name: surrogateType,
                },
              },
            },
          },
        ],
      },
    },
    inspectConfig: {
      customInfoTypes: [
        {
          infoType: {
            name: surrogateType,
          },
          surrogateType: {},
        },
      ],
    },
    item: item,
  };

  try {
    // Run reidentification request
    const [response] = await dlp.reidentifyContent(request);

日付シフトで日付を匿名化する

状況によっては、日付は難読化が必要な機密データと見なされることがあります。日付シフトでは、期間の順序と期間を維持したまま、日付をランダムな増分でシフトできます。セット内の各日付は、そのエントリに固有の時間だけシフトされます。日付シフトによる匿名化を示すために、まず日付データを含むサンプル CSV ファイルを見てみましょう。

resources/dates.csv

name,birth_date,register_date,credit_card
Ann,01/01/1980,07/21/1996,4532908762519852
James,03/06/1988,04/09/2001,4301261899725540
Dan,08/14/1945,11/15/2011,4620761856015295
Laura,11/03/1992,01/04/2017,4564981067258901

このデータには、日付シフトを適用できる 2 つのフィールド(birth_dateregister_date)が含まれています。deid.js は、日付をシフトする日数をランダムに選択する範囲を定義するために、下限値と上限値を受け取ります。

node deid.js deidDateShift -c $GOOGLE_CLOUD_PROJECT resources/dates.csv datesShifted.csv 30 90 birth_date

datesShifted.csv というファイルが生成されます。このファイルでは、日付が 30 ~ 90 日の範囲でランダムにシフトされます。生成された出力の例を次に示します。

name,birth_date,register_date,credit_card
Ann,2/6/1980,7/21/1996,4532908762519852
James,5/18/1988,4/9/2001,4301261899725540
Dan,9/16/1945,11/15/2011,4620761856015295
Laura,12/16/1992,1/4/2017,4564981067258901

CSV ファイルのどの日付列をシフトするかを指定することもできます。birth_date フィールドと register_date フィールドは変更されません。

日付シフトで匿名化を処理する関数を見てみましょう。

deid.js

async function deidentifyWithDateShift(
  callingProjectId,
  inputCsvFile,
  outputCsvFile,
  dateFields,
  lowerBoundDays,
  upperBoundDays,
  contextFieldId,
  wrappedKey,
  keyName
) {
...
}

この関数は、FPE による匿名化と同様に、ラップされた鍵と鍵名を受け取ることができます。これにより、日付のシフトを再識別するための暗号鍵を指定できます。指定する引数によって dateShiftConfig オブジェクトが作成されます。

deid.js

  // Construct DateShiftConfig
  const dateShiftConfig = {
    lowerBoundDays: lowerBoundDays,
    upperBoundDays: upperBoundDays,
  };

  if (contextFieldId && keyName && wrappedKey) {
    dateShiftConfig.context = {name: contextFieldId};
    dateShiftConfig.cryptoKey = {
      kmsWrapped: {
        wrappedKey: wrappedKey,
        cryptoKeyName: keyName,
      },
    };
  } else if (contextFieldId || keyName || wrappedKey) {
    throw new Error(
      'You must set either ALL or NONE of {contextFieldId, keyName, wrappedKey}!'
    );
  }

  // Construct deidentification request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    deidentifyConfig: {
      recordTransformations: {
        fieldTransformations: [
          {
            fields: dateFields,
            primitiveTransformation: {
              dateShiftConfig: dateShiftConfig,
            },
          },
        ],
      },
    },
    item: tableItem,
  };

5. 文字列と画像を秘匿化する

機密情報を難読化するもう一つの方法は、秘匿化です。秘匿化では、一致したものが、一致すると特定された情報タイプに置き換えられます。redact.js は削除を示します。

node redact.js -c $GOOGLE_CLOUD_PROJECT \
string "Please refund the purchase to my credit card 4012888888881881" \
-t 'CREDIT_CARD_NUMBER'

出力では、サンプル クレジット カード番号が情報タイプ CREDIT_CARD_NUMBER に置き換えられます。

Please refund the purchase on my credit card [CREDIT_CARD_NUMBER]

これは、機密情報を非表示にしながら、削除される情報の種類を特定したい場合に便利です。DLP API では、テキストを含む画像の情報も同様に秘匿化できます。例として、次のサンプル画像を見てみましょう。

resources/test.png

bf3719cfeb5676ff.png

上の画像の電話番号とメールアドレスを秘匿化するには:

node redact.js -c $GOOGLE_CLOUD_PROJECT \
image resources/test.png ./redacted.png \
-t PHONE_NUMBER -t EMAIL_ADDRESS

指定したとおり、redacted.png という名前の新しい画像が生成され、リクエストされた情報が黒く塗りつぶされます。

ce023dd95cccc40f.png

文字列から機密情報を秘匿化するために使用される関数は次のとおりです。

redact.js

async function redactText(
  callingProjectId, 
  string,
  minLikelihood,
  infoTypes
) {
...}

deidentifyContent 関数に提供されるリクエストは次のとおりです。

redact.js

const request = {
    parent: dlp.projectPath(callingProjectId),
    item: {
      value: string,
    },
    deidentifyConfig: {
      infoTypeTransformations: {
        transformations: [replaceWithInfoTypeTransformation],
      },
    },
    inspectConfig: {
      minLikelihood: minLikelihood,
      infoTypes: infoTypes,
    },
  };

同様に、画像を秘匿化する関数は次のとおりです。

redact.js

async function redactImage(
  callingProjectId,
  filepath,
  minLikelihood,
  infoTypes,
  outputPath
) {
...}

redactImage 関数に提供されるリクエストは次のとおりです。

redact.js

// Construct image redaction request
  const request = {
    parent: dlp.projectPath(callingProjectId),
    byteItem: {
      type: fileTypeConstant,
      data: fileBytes,
    },
    inspectConfig: {
      minLikelihood: minLikelihood,
      infoTypes: infoTypes,
    },
    imageRedactionConfigs: imageRedactionConfigs,
  };

6. クリーンアップ

このチュートリアルでは、DLP API を使用してデータ内の機密情報をマスク、匿名化、秘匿化する方法について説明しました。作成したリソースをプロジェクトからクリーンアップします。

プロジェクトを削除する

GCP Console で、[Cloud Resource Manager] ページに移動します。

プロジェクト リストで、目的のプロジェクトを選択し、[削除] をクリックします。プロジェクト ID を入力するように求められます。入力して [シャットダウン] をクリックします。

別の方法として、gcloud を使用してプロジェクト全体を Cloud Shell から直接削除することもできます。

gcloud projects delete $GOOGLE_CLOUD_PROJECT

7. 完了

おめでとうございます。やりました!Cloud DLP は、機密データの検査、分類、匿名化のプラットフォームにアクセスできる強力なツールです。

学習した内容

  • Cloud DLP API を使用して文字列とファイルで複数の情報タイプを調べる方法について説明しました。
  • DLP API でマスクを使用して文字列を匿名化し、情報タイプに一致するデータを非表示にする方法について説明します。
  • DLP API を使用して、暗号鍵を使用してデータを匿名化してから再識別しました
  • DLP API を使用して、文字列と画像のデータを秘匿化しました。