

# AWS Glue Studio 외부에서 민감한 데이터 감지 사용
<a name="aws-glue-api-sensitive-data-example"></a>

 AWS Glue Studio는 민감한 데이터 감지를 허용하지만 AWS Glue Studio 외부에서 민감한 데이터 감지 기능을 사용할 수도 있습니다.

 민감한 관리형 데이터 형식의 목록은 [관리형 데이터 형식](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 작업에서 2개의 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와 달리 이 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% 에 존재하며, 민감도가 “LOW”이면 개체를 탐지된 것으로 표시하도록 파라미터를 설정합니다 
+  키가 열 이름이고 값이 탐지된 개체 유형 목록인 맵을 반환합니다 
+  반환된 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를 호출하여 사용자 지정 엔터티를 만들 수 있습니다. 다음 예제에서는 요청 파라미터를 사용하여 `CreateCustomEntityType()` API에 사용자 지정 엔터티 유형 'EMPLOYE\_ID'를 정의합니다.

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

 그리고 나서 `EntityDetector()` API에 사용자 지정 엔터티 유형(EMPLOYEE\_ID)을 추가하여 새로운 사용자 지정 민감한 데이터 유형을 사용하도록 작업을 수정합니다.

```
  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에서 개체를 감지하는 데 사용됩니다. 원래 값과 PII 탐지 메타데이터가 있는 outputColumnName이라는 추가 열이 포함된 새 DataFrame을 반환합니다. 이 DynamicFrame이 AWS Glue 스크립트 내에서 반환된 후에 사용자 지정 마스킹을 수행하거나 세분화된 작업이 포함된 detect() API를 대신 사용할 수 있습니다.

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

 파라미터: 
+  **frame** - (유형:`DynamicFrame`) 처리할 데이터가 포함된 입력 DynamicFrame입니다.
+  **entityTypesToDetect** - (type:`[Seq[String]`) 탐지할 개체 유형 목록입니다. 관리 개체 유형 또는 사용자 지정 개체 유형일 수 있습니다.
+  **outputColumnName** - (유형: `String`, 기본값: "DetectedEntities") 탐지된 개체를 저장할 열의 이름입니다. 지정하지 않은 경우 기본 열 이름은 "DetectedEntities"입니다.
+  **detectionSensitivity** - (유형: `String`, 옵션: "LOW" or "HIGH", 기본: "LOW") 탐지 프로세스의 민감도를 지정합니다. 유효한 옵션은 "LOW" 또는 "HIGH"입니다. 제공되지 않은 경우 기본 민감도는 "LOW"으로 설정됩니다.

 `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에서 개체를 감지하는 데 사용됩니다. 원래 값이 마스킹된 민감한 데이터로 대체되고 PII 탐지 메타데이터가 있는 추가 `outputColumnName` 열이 포함된 새 DataFrame을 반환합니다.

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

 파라미터: 
+  **frame** - (유형: `DynamicFrame`): 처리할 데이터가 포함된 입력 DynamicFrame입니다.
+  **detectionParameters** - (유형: `JsonOptions`): 탐지 프로세스의 매개 변수를 지정하는 JSON 옵션입니다.
+  **outputColumnName** - (유형: `String`, 기본값: "DetectedEntities"): 탐지된 개체를 저장할 열의 이름입니다. 지정하지 않은 경우 기본 열 이름은 "DetectedEntities"입니다.
+  **detectionSensitivity** - (유형: `String`, 옵션: "LOW" or "HIGH", 기본: "LOW"): 탐지 프로세스의 민감도를 지정합니다. 유효한 옵션은 "LOW" 또는 "HIGH"입니다. 제공되지 않은 경우 기본 민감도는 "LOW"으로 설정됩니다.

<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** - (type:`Seq[String]`) 탐지할 개체 유형 목록입니다. 관리 개체 유형 또는 사용자 지정 개체 유형일 수 있습니다.
+  **sampleFraction** - (유형: `Double`, 기본값: 10%) PII 엔터티를 스캔할 때 샘플링할 데이터의 이름입니다.
+  **thresholdFraction**- (유형: `Double`, 기본값: 10%): 열을 PII 데이터로 식별하기 위해 충족되어야 하는 데이터의 비율입니다.
+  **detectionSensitivity** - (유형: `String`, 옵션: "LOW" or "HIGH", 기본: "LOW") 탐지 프로세스의 민감도를 지정합니다. 유효한 옵션은 "LOW" 또는 "HIGH"입니다. 제공되지 않은 경우 기본 민감도는 "LOW"으로 설정됩니다.