

# 在 AWS Glue Studio 外部使用敏感数据检测
<a name="aws-glue-api-sensitive-data-example"></a>

 AWS Glue Studio 允许您检测敏感数据，但是，您也可以在 AWS Glue Studio 外部使用敏感数据检测功能。

 有关托管的敏感数据类型的完整列表，请参阅 [Managed data types](https://docs.aws.amazon.com/glue/latest/dg/sensitive-data-managed-data-types.html)。

## 使用 AWS 托管 PII 类型检测敏感数据
<a name="sensitive-data-managed-pii-types"></a>

 AWS Glue 在 AWS Glue ETL 任务中提供两个 API。它们是 `detect()` 和 `classifyColumns()`。

```
  detect(frame: DynamicFrame, 
      entityTypesToDetect: Seq[String], 
      outputColumnName: String = "DetectedEntities",
      detectionSensitivity: String = "LOW"): DynamicFrame

 detect(frame: DynamicFrame, 
      detectionParameters: JsonOptions,
      outputColumnName: String = "DetectedEntities",
      detectionSensitivity: String = "LOW"): DynamicFrame
      
  classifyColumns(frame: DynamicFrame, 
      entityTypesToDetect: Seq[String], 
      sampleFraction: Double = 0.1, 
      thresholdFraction: Double = 0.1,
      detectionSensitivity: String = "LOW")
```

 您可以使用 `detect()` API 来识别 AWS 托管 PII 类型和自定义实体类型。将使用检测结果自动创建一个新列。`classifyColumns()` API 将返回一个映射，其中键是列名，值是检测到的实体类型列表。`SampleFraction` 表示扫描 PII 实体时要采样的一小部分数据，而 `ThresholdFraction` 表示为了将列标识为 PII 数据而必须满足的一小部分数据。

### 行级别检测
<a name="w2aac67c11c24c19b9c11"></a>

 在示例中，该任务使用 `detect()` 和 `classifyColumns()` API 执行以下操作：
+  从 Amazon S3 存储桶读取数据并将其转换为 dynamicFrame 
+  在 dynamicFrame 中检测“电子邮件”和“信用卡”的实例 
+  返回一个 dynamicFrame，其中包含原始值和一列，其中包含每行的检测结果 
+  将返回的 dynamicFrame 写入另一个 Amazon S3 路径 

```
  import com.amazonaws.services.glue.GlueContext
  import com.amazonaws.services.glue.MappingSpec
  import com.amazonaws.services.glue.errors.CallSite
  import com.amazonaws.services.glue.util.GlueArgParser
  import com.amazonaws.services.glue.util.Job
  import com.amazonaws.services.glue.util.JsonOptions
  import org.apache.spark.SparkContext
  import scala.collection.JavaConverters._
  import com.amazonaws.services.glue.ml.EntityDetector
  
  object GlueApp {
    def main(sysArgs: Array[String]) {
      val spark: SparkContext = new SparkContext()
      val glueContext: GlueContext = new GlueContext(spark)
      val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)
      Job.init(args("JOB_NAME"), glueContext, args.asJava)
      val frame= glueContext.getSourceWithFormat(formatOptions=JsonOptions("""{"quoteChar": "\"", "withHeader": true, "separator": ","}"""), connectionType="s3", format="csv", options=JsonOptions("""{"paths": ["s3://pathToSource"], "recurse": true}"""), transformationContext="AmazonS3_node1650160158526").getDynamicFrame()
  
      val frameWithDetectedPII = EntityDetector.detect(frame, Seq("EMAIL", "CREDIT_CARD"))
  
      glueContext.getSinkWithFormat(connectionType="s3", options=JsonOptions("""{"path": "s3://pathToOutput/", "partitionKeys": []}"""), transformationContext="someCtx", format="json").writeDynamicFrame(frameWithDetectedPII)
  
      Job.commit()
    }
  }
```

### 使用精细操作进行行级别检测
<a name="w2aac67c11c24c19b9c15"></a>

 示例中的作业将使用 `detect()` API 执行以下操作：
+  从 Amazon S3 存储桶读取数据并将其转换为 dynamicFrame 
+  检测 dynamicFrame 中的“USA\_PTIN”、“ BANK\_ACCOUNT”、“USA\_SSN”、“USA\_PASSPORT\_NUMBER”和“PHONE\_NUMBER”等敏感数据类型 
+  返回一个 dynamicFrame，其中包含修改后的遮蔽值以及一个包含每行的检测结果的列 
+  将返回的 dynamicFrame 写入另一个 Amazon S3 路径 

 与上述 `detect()` API 不同的是，这将使用精细操作来检测实体类型。有关更多信息，请参阅 [使用 `detect()` 方法所需的检测参数](#sensitive-data-detect-parameters-fine-grained-actions)。

```
import com.amazonaws.services.glue.GlueContext
import com.amazonaws.services.glue.MappingSpec
import com.amazonaws.services.glue.errors.CallSite
import com.amazonaws.services.glue.util.GlueArgParser
import com.amazonaws.services.glue.util.Job
import com.amazonaws.services.glue.util.JsonOptions
import org.apache.spark.SparkContext
import scala.collection.JavaConverters._
import com.amazonaws.services.glue.ml.EntityDetector

object GlueApp {
  def main(sysArgs: Array[String]) {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)
    Job.init(args("JOB_NAME"), glueContext, args.asJava)
    val frame = glueContext.getSourceWithFormat(formatOptions=JsonOptions("""{"quoteChar": "\"", "withHeader": true, "separator": ","}"""), connectionType="s3", format="csv", options=JsonOptions("""{"paths": ["s3://pathToSource"], "recurse": true}"""), transformationContext="AmazonS3_node_source").getDynamicFrame()

    val detectionParameters = JsonOptions(
      """
        {
          "USA_DRIVING_LICENSE": [{
            "action": "PARTIAL_REDACT",
            "sourceColumns": ["Driving License"],
            "actionOptions": {
              "matchPattern": "[0-9]",
              "redactChar": "*"
            }
          }],
          "BANK_ACCOUNT": [{
            "action": "DETECT",
            "sourceColumns": ["*"]
          }],
          "USA_SSN": [{
            "action": "SHA256_HASH",
            "sourceColumns": ["SSN"]
          }],
          "IP_ADDRESS": [{
            "action": "REDACT",
            "sourceColumns": ["IP Address"],
            "actionOptions": {"redactText": "*****"}
          }],
          "PHONE_NUMBER": [{
            "action": "PARTIAL_REDACT",
            "sourceColumns": ["Phone Number"],
            "actionOptions": {
              "numLeftCharsToExclude": 1,
              "numRightCharsToExclude": 0,
              "redactChar": "*"
            }
          }]
        }
      """
    )

    val frameWithDetectedPII = EntityDetector.detect(frame, detectionParameters, "DetectedEntities", "HIGH")

    glueContext.getSinkWithFormat(connectionType="s3", options=JsonOptions("""{"path": "s3://pathToOutput/", "partitionKeys": []}"""), transformationContext="AmazonS3_node_target", format="json").writeDynamicFrame(frameWithDetectedPII)

    Job.commit()
  }
}
```

### 列级别检测
<a name="w2aac67c11c24c19b9c19"></a>

 示例中的作业将使用 `classifyColumns()` API 执行以下操作：
+  从 Amazon S3 存储桶读取数据并将其转换为 dynamicFrame 
+  在 dynamicFrame 中检测“电子邮件”和“信用卡”的实例 
+  将参数设置为对列进行 100% 采样，如果实体位于 10% 的单元格中，并且敏感性为“低”，则将其标记为已检测 
+  返回一个以列名为键，以检测到的实体类型列表为值的映射 
+  将返回的 dynamicFrame 写入另一个 Amazon S3 路径 

```
import com.amazonaws.services.glue.GlueContext
import com.amazonaws.services.glue.MappingSpec
import com.amazonaws.services.glue.errors.CallSite
import com.amazonaws.services.glue.util.GlueArgParser
import com.amazonaws.services.glue.util.Job
import com.amazonaws.services.glue.util.JsonOptions
import org.apache.spark.SparkContext
import scala.collection.JavaConverters._
import com.amazonaws.services.glue.DynamicFrame
import com.amazonaws.services.glue.ml.EntityDetector

object GlueApp {
  def main(sysArgs: Array[String]) {
    val spark: SparkContext = new SparkContext()
    val glueContext: GlueContext = new GlueContext(spark)
    val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)
    Job.init(args("JOB_NAME"), glueContext, args.asJava)
    val frame = glueContext.getSourceWithFormat(formatOptions=JsonOptions("""{"quoteChar": "\"", "withHeader": true, "separator": ",", "optimizePerformance": false}"""), connectionType="s3", format="csv", options=JsonOptions("""{"paths": ["s3://pathToSource"], "recurse": true}"""), transformationContext="frame").getDynamicFrame()
    
    import glueContext.sparkSession.implicits._

    val detectedDataFrame = EntityDetector.classifyColumns(
        frame, 
        entityTypesToDetect = Seq("CREDIT_CARD", "PHONE_NUMBER"), 
        sampleFraction = 1.0, 
        thresholdFraction = 0.1,
        detectionSensitivity = "LOW"
    )
    val detectedDF = (detectedDataFrame).toSeq.toDF("columnName", "entityTypes")
    val DetectSensitiveData_node = DynamicFrame(detectedDF, glueContext)

    glueContext.getSinkWithFormat(connectionType="s3", options=JsonOptions("""{"path": "s3://pathToOutput", "partitionKeys": []}"""), transformationContext="someCtx", format="json").writeDynamicFrame(DetectSensitiveData_node)

    Job.commit()
  }
}
```

## 使用 AWS CustomEntityType PII 类型检测敏感数据
<a name="sensitive-data-custom-entity-PII-types"></a>

 您可以通过 AWS Studio 定义自定义实体。但是，要在 AWS Studio 外部使用此功能，必须先定义自定义实体类型，然后将定义的自定义实体类型添加到 `entityTypesToDetect` 列表。

 如果您的数据中有特定的敏感数据类型（例如“员工 ID”），则可以通过调用 `CreateCustomEntityType()` API 创建自定义实体。以下示例使用请求参数将自定义实体类型“EMPLOYEE\_ID”定义到 `CreateCustomEntityType()` API：

```
  { 
      "name": "EMPLOYEE_ID",
      "regexString": "\d{4}-\d{3}",
      "contextWords": ["employee"]
  }
```

 然后，通过将自定义实体类型 (EMPLOYEE\_ID) 添加到 `EntityDetector()` API，修改任务以使用新的自定义敏感数据类型：

```
  import com.amazonaws.services.glue.GlueContext
  import com.amazonaws.services.glue.MappingSpec
  import com.amazonaws.services.glue.errors.CallSite
  import com.amazonaws.services.glue.util.GlueArgParser
  import com.amazonaws.services.glue.util.Job
  import com.amazonaws.services.glue.util.JsonOptions
  import org.apache.spark.SparkContext
  import scala.collection.JavaConverters._
  import com.amazonaws.services.glue.ml.EntityDetector
  
  object GlueApp {
    def main(sysArgs: Array[String]) {
      val spark: SparkContext = new SparkContext()
      val glueContext: GlueContext = new GlueContext(spark)
      val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)
      Job.init(args("JOB_NAME"), glueContext, args.asJava)
      val frame= glueContext.getSourceWithFormat(formatOptions=JsonOptions("""{"quoteChar": "\"", "withHeader": true, "separator": ","}"""), connectionType="s3", format="csv", options=JsonOptions("""{"paths": ["s3://pathToSource"], "recurse": true}"""), transformationContext="AmazonS3_node1650160158526").getDynamicFrame()
  
      val frameWithDetectedPII = EntityDetector.detect(frame, Seq("EMAIL", "CREDIT_CARD", "EMPLOYEE_ID"))
  
      glueContext.getSinkWithFormat(connectionType="s3", options=JsonOptions("""{"path": "s3://pathToOutput/", "partitionKeys": []}"""), transformationContext="someCtx", format="json").writeDynamicFrame(frameWithDetectedPII)
  
      Job.commit()
    }
  }
```

**注意**  
 如果定义的自定义敏感数据类型与现有托管实体类型的名称相同，则自定义敏感数据类型将优先并覆盖该托管实体类型的逻辑。

## 使用 `detect()` 方法所需的检测参数
<a name="sensitive-data-detect-parameters-fine-grained-actions"></a>

 此方法用于检测 DynamicFrame 中的实体。此方法将返回一个新 DataFrame，其中包含原始值以及一个具有 PII 检测元数据的附加列 outputColumnName。返回此 DynamicFrame 后可以在 AWS Glue 脚本中进行自定义遮蔽，也可以改用使用精细操作 API 的 detect() 方法。

```
detect(frame: DynamicFrame, 
       entityTypesToDetect: Seq[String], 
       outputColumnName: String = "DetectedEntities",
       detectionSensitivity: String = "LOW"): DynamicFrame
```

 参数：
+  **frame** –（类型：`DynamicFrame`）包含要处理的数据的输入 DynamicFrame。
+  **entityTypesToDetect** –（类型：`[Seq[String]`）要检测的实体类型列表。可以是托管式实体类型，也可以是自定义实体类型。
+  **outputColumnName** –（类型：`String`，默认值：“DetectedEntities”）用于存储检测到的实体的列名。如果未提供此参数，则默认列名为“DetectedEntities”。
+  **detectionSensitivity** –（类型：`String`，选项：“低”或“高”，默认值：“低”）指定检测过程的灵敏度。有效选项为“低”或“高”。如果未提供此参数，则默认灵敏度设置为“低”。

 `outputColumnName` 设置：

 用于存储检测到的实体的列名。如果未提供此参数，则默认列名为“DetectedEntities”。对于输出列中的每一行，补充列都用以下键值对来包含了列名与检测到的实体元数据的映射：
+  **entityType** – 检测到的实体类型。
+  **start** – 检测到的实体在原始数据中的起始位置。
+  **end** – 检测到的实体在原始数据中的结束位置。
+  **actionUsed** – 对检测到的实体执行的操作（例如，“DETECT”、“REDACT”、“PARTIAL\_REDACT”、“SHA256\_HASH”）。

 示例：

```
{
   "DetectedEntities":{
      "SSN Col":[
         {
            "entityType":"USA_SSN",
            "actionUsed":"DETECT",
            "start":4,
            "end":15
         }
      ],
      "Random Data col":[
         {
            "entityType":"BANK_ACCOUNT",
            "actionUsed":"PARTIAL_REDACT",
            "start":4,
            "end":13
         },
         {
            "entityType":"IP_ADDRESS",
            "actionUsed":"REDACT",
            "start":4,
            "end":13
         }
      ]
   }
}
```

 **使用精细操作的 `detect()` 方法的检测参数** 

 此方法用于使用指定的参数来检测 DynamicFrame 中的实体。此方法将返回一个新 DataFrame，其中包含遮蔽敏感数据后的原始值以及一个具有 PII 检测元数据的附加列 `outputColumnName`。

```
detect(frame: DynamicFrame, 
       detectionParameters: JsonOptions,
       outputColumnName: String = "DetectedEntities",
       detectionSensitivity: String = "LOW"): DynamicFrame
```

 参数：
+  **frame** –（类型：`DynamicFrame`）：包含要处理的数据的输入 DynamicFrame。
+  **detectionParameters** –（类型：`JsonOptions`）：为检测进程指定参数的 JSON 选项。
+  **outputColumnName** –（类型：`String`，默认值：“DetectedEntities”）：用于存储检测到的实体的列名。如果未提供此参数，则默认列名为“DetectedEntities”。
+  **detectionSensitivity** –（类型：`String`，选项：“低”或“高”，默认值：“低”）：指定检测过程的灵敏度。有效选项为“低”或“高”。如果未提供此参数，则默认灵敏度设置为“低”。

<a name="detection-parameters-settings"></a> `detectionParameters` 设置 

 如果未包含任何设置，则将使用默认值。
+  **action** –（类型：`String`，选项：“DETECT”、“REDACT”、“PARTIAL\_REDACT”、“SHA256\_HASH”）指定要对实体执行的操作。必需。请注意，对于执行遮蔽的操作（除“DETECT”之外的所有操作），每列只能执行一个操作。这是一种用于遮蔽合并后实体的预防措施。
+  **sourceColumns** –（类型：`List[String]`，默认值：[“\*”]）要对实体执行检测的源列名列表。如果不存在，则默认为 [“\*”]。如果使用的列名无效，则将引发 `IllegalArgumentException`。
+  **sourceColumnsToExclude** –（类型：`List[String]`）要对实体执行检测的源列名列表。使用 `sourceColumns` 或 `sourceColumnsToExclude`。如果使用的列名无效，则将引发 `IllegalArgumentException`。
+  **actionOptions** – 基于指定操作的附加选项：
  +  对于“DETECT”和“SHA256\_HASH”，不允许使用任何选项。
  +  对于“REDACT”：
    + **redactText** –（键入：`String`，默认值：“\*\*\*\*\*”）用于替换检测到的实体的文本。
  +  对于“PARTIAL\_REDACT”：
    +  **redactChar** –（类型：`String`，默认值：“\*”）用于替换实体中每个检测到的字符的字符。
    +  **matchPattern** –（类型：`String`）用于部分编辑的正则表达式模式。不能与 numLeftCharsToExclude 或 `numRightCharsToExclude` 组合使用。
    +  **numLeftCharsToExclude** –（类型：`String, integer`）要排除的左侧字符数。不能与 matchPattern 组合使用，但可以与 `numRightCharsToExclude` 组合使用。
    +  **numRightCharsToExclude** –（类型：`String, integer`）要排除的右侧字符数。不能与 matchPattern 组合使用，但可以与 `numRightCharsToExclude` 组合使用。

 `outputColumnName` 设置 

 [参见 outputColumnName 设置](#sensitive-data-detect-parameters-fine-grained-actions) 

## `classifyColumns()` 方法的检测参数
<a name="detection-parameters-classifycolumns"></a>

 此方法用于检测 DynamicFrame 中的实体。这将返回一个以列名为键，以检测到的实体类型列表为值的映射。返回此映射后可以在 AWS Glue 脚本中进行自定义遮蔽。

```
classifyColumns(frame: DynamicFrame, 
                entityTypesToDetect: Seq[String], 
                sampleFraction: Double = 0.1, 
                thresholdFraction: Double = 0.1,
                detectionSensitivity: String = "LOW")
```

 参数：
+  **frame** –（类型：`DynamicFrame`）包含要处理的数据的输入 DynamicFrame。
+  **entityTypesToDetect** –（类型：`Seq[String]`）要检测的实体类型列表。可以是托管式实体类型，也可以是自定义实体类型。
+  **sampleFraction** –（类型：`Double`，默认值：10%）扫描 PII 实体时的数据采样率。
+  **thresholdFraction** –（类型：`Double`，默认值：10%）：要将列标识为 PII 数据时必须达到的数据占比。
+  **detectionSensitivity** –（类型：`String`，选项：“低”或“高”，默认值：“低”）指定检测过程的灵敏度。有效选项为“低”或“高”。如果未提供此参数，则默认灵敏度设置为“低”。