> For the complete documentation index, see [llms.txt](https://docs.panther.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.panther.com/ko/detections/rules/python.md).

# Python 탐지 작성

## 개요

Panther Console 또는 로컬에서 다음 워크플로를 따라 직접 Python 디택션을 작성할 수 있습니다 [CLI 워크플로](/ko/panther/detections-repo/ci-cd.md). Python 디택션을 작성할 때는 [이러한 모범 사례를](#python-detection-writing-best-practices)참고하고, 또한 [일부 알러트 필드는 동적으로 설정할 수 있다는 점을 기억하세요](#alert-functions-in-python-detections). Python으로 작성된 룰은 [디택션 파생](/ko/detections/rules/derived.md).

대신 [노코드 디택션 빌더를](/ko/detections/rules/simple-detection-builder.md) Console에서 사용해 룰을 만들거나 [로컬에서 Simple 디택션으로 작성할 수 있습니다](/ko/detections/rules/writing-simple-detections.md). 디택션을 로컬에서 Simple 디택션으로 작성할지 Python 디택션으로 작성할지 확실하지 않다면 [Python과 Simple 디택션 YAML 사용하기](https://docs.panther.com/ko/detections/rules/pages/03a99462193d3cb6f09cb46a6d9fa32a7a6035d0#using-python-vs.-simple-detections-yaml) 섹션을 참조하세요.

{% hint style="info" %}
새 Python 디택션을 작성하기 전에 [Panther가 관리하는 디택션](/ko/detections/panther-managed.md) 이 필요한 요구 사항을 충족하는지 확인하세요(또는 *거의* 충족하는지 확인하세요—Panther가 관리하는 룰은 [인라인 필터](/ko/detections/rules/inline-filters.md)로 조정할 수 있습니다). Panther가 관리하는 디택션을 활용하면 직접 작성하는 수고를 덜 수 있을 뿐 아니라, Panther가 새 버전을 출시할 때 핵심 디택션 로직이 지속적으로 업데이트되는 혜택도 얻을 수 있습니다.
{% endhint %}

{% hint style="warning" %}
Panther의 디택션 내에서 외부 API 요청을 하는 것은 매우 권장되지 않습니다. 일반적으로 디택션은 매우 대규모로 처리되며, API 요청을 하면 수신 시스템에 과부하가 걸리고 룰이 [15초 실행 시간 제한](/ko/detections/rules.md#rule-errors-and-scheduled-rule-errors).
{% endhint %}

## Python에서 디택션을 만드는 방법

### Python에서 룰을 만드는 방법

Panther Console과 CLI 워크플로 모두에서 Python 룰을 작성할 수 있습니다.

<details>

<summary>Console에서 Python으로 룰 만들기</summary>

1. Panther Console의 왼쪽 탐색 모음에서 **디택션**.
2. 을 클릭하세요 **새로 만들기**.
3. 의 **Python 룰** 타일에서 **시작**.
4. 생성 페이지에서 룰을 구성하세요:
   * **이름**: 룰에 대한 설명적인 이름을 입력하세요.
   * **ID** (선택 사항)**:** 펜 아이콘을 클릭하고 룰의 고유 ID를 입력하세요.
   * 오른쪽 상단에서 **활성화** 토글이 기본적으로 `ON` 으로 설정됩니다. 룰을 비활성화하려면 토글을 `OFF`.
   * 로 전환하세요. "In the" **다음 소스에 대해** 섹션:
     * **로그 유형**: 이 룰이 적용될 로그 유형을 선택하세요.
   * 로 전환하세요. "In the" **탐지** 섹션:
     * 로 전환하세요. "In the" **룰 함수** 텍스트 편집기에서 Python `룰` 함수를 작성하여 디택션을 정의하세요.
       * 디택션 템플릿과 예시는 다음을 참조하세요. [panther\_analysis GitHub 저장소](https://github.com/panther-labs/panther-analysis/tree/master/templates).
   * 로 전환하세요. "In the" **알러트 생성** 섹션에서 다음을 설정하세요, **알러트 생성** `ON/OFF` 토글. 이는 [알러트](/ko/alerts.md) 가 일치 항목이 있을 때 생성되어야 하는지, 아니면 단순히 [시그널](/ko/detections/signals.md)로 설정했는지를 나타냅니다. `ON`:
     * **심각도**: [심각도 수준](#alert-severity) 을 선택하여 이 디택션으로 트리거되는 알러트에 적용하세요.
     * 로 전환하세요. "In the" **선택 필드** 섹션에서 다음 필드의 값을 선택적으로 입력하세요:
       * **설명**: 룰에 대한 추가 컨텍스트를 입력하세요.
       * **런북**: 이 룰과 관련된 절차 및 작업을 입력하세요.
         * 자세한 내용은 [알러트 런북](/ko/alerts/alert-runbooks.md).
         * 설명적인 런북을 제공하는 것이 권장됩니다. 왜냐하면 [Panther AI 알러트 분류](/ko/alerts.md#panther-ai-alert-triage) 에서 이를 고려하기 때문입니다.
       * **참조**: 이 룰에 대한 추가 정보를 포함한 외부 링크를 입력하세요.
       * **대상 재정의:** 심각도와 관계없이 이 디택션의 알러트를 수신할 대상을 선택하세요. 대상은 룰 함수에서 동적으로 설정할 수도 있습니다. 자세한 내용은 [라우팅 순서 우선순위](/ko/alerts/destinations.md#routing-order-precedence) 를 참조하여 라우팅 우선순위에 대해 자세히 알아보세요.
       * **중복 제거 기간** 및 **이벤트 임계값**: 룰 일치 항목에 대한 중복 제거 기간과 임계값을 입력하세요. 중복 제거가 어떻게 작동하는지 알아보려면 다음을 참조하세요. [중복 제거](#deduplication).
       * **요약 속성**: 이 디택션으로 트리거되는 알러트에서 강조 표시할 속성을 입력하세요.
         * 중첩 필드를 요약 속성으로 사용하려면, 요약 속성 필드에서 Snowflake 점 표기법을 사용하여 JSON 객체의 경로를 따라가세요:

           `<column>:<level1_element>.<level2_element>.<level3_element>`

           그러면 알러트의 참조된 객체에 대해 알러트 요약이 생성됩니다. [Snowflake에서 반정형 데이터를 탐색하는 방법에 대해 자세히 알아보세요.](https://docs.snowflake.com/en/user-guide/querying-semistructured.html#label-traversing-semistructured-data)
         * 알러트 요약에 대한 자세한 내용은 다음을 참조하세요 [알러트 할당 및 관리](/ko/alerts/alert-management.md).
       * **사용자 지정 태그**: 사용자 지정 태그를 입력하여 한눈에 룰을 이해하는 데 도움을 받으세요(예: `HIPAA`.)
       * 로 전환하세요. "In the" **프레임워크 매핑** 섹션:
         1. 을 클릭하세요 **새로 추가** 보고서를 입력하려면.
         2. 다음 필드에 값을 입력하세요:
            * **보고서 키**: 보고서와 관련된 키를 입력하세요.
            * **보고서 값**: 해당 보고서의 값을 입력하세요.
   * 로 전환하세요. "In the" **테스트** 섹션:
     * 로 전환하세요. "In the" **단위 테스트** 섹션에서 **새로 추가** 을 클릭하여 [테스트를 만들고](/ko/detections/testing.md) 이전 단계에서 정의한 룰에 대해.
5. 오른쪽 상단 모서리에서 **저장**.

룰을 만든 후에는 다음을 사용하여 수정할 수 있습니다 [인라인 필터](/ko/detections/rules/inline-filters.md).

</details>

<details>

<summary>CLI 워크플로에서 Python으로 룰 만들기</summary>

로컬에서 디텍션을 작성하는 경우(Panther Console 대신), GitHub 또는 GitLab과 같은 버전 관리 시스템에서 로컬 디텍션 파일을 관리하는 것을 권장합니다.

사용자 지정 디텍션 콘텐츠는 다음 중 하나를 만들어 시작하는 것을 권장합니다 [공개 포크](https://docs.panther.com/panther-developer-workflows/ci-cd/detections-repo/public-fork) 또는 [비공개 복제 저장소](https://docs.panther.com/panther-developer-workflows/ci-cd/detections-repo/private-cloned-repo) Panther의 [오픈소스 panther-analysis 저장소에서](https://github.com/panther-labs/panther-analysis).

**폴더 설정**

룰을 폴더로 그룹화하는 경우, 각 폴더 이름에는 반드시 `룰` 이 포함되어야 업로드 시(PAT 또는 Console의 대량 업로더를 사용하여) 찾을 수 있습니다.

로그/리소스 유형을 기준으로 룰을 폴더로 그룹화하는 것을 권장합니다. 예: `suricata_rules` 또는 `aws_s3_policies`. 다음을 참조로 사용할 수 있습니다. [panther-analysis](https://github.com/panther-labs/panther-analysis) 저장소를

**파일 설정**

각 룰과 예약 룰은 다음으로 구성됩니다:

* Python 파일(확장자가 `.py` 인 파일)로, 디텍션 로직이 포함되어 있습니다.
* YAML 명세 파일(확장자가 `.yml` 인 파일)로, 디텍션의 메타데이터 속성이 포함되어 있습니다.
  * 관례상 이 파일에는 Python 파일과 같은 이름을 붙입니다.

룰은 의심스러운 동작을 탐지하는 Python 함수입니다. 값을 반환하면 `True` 의심스러운 활동을 의미하며, 이는 알러트를 트리거합니다.

1. 룰을 작성하고 (원하는 폴더에) 다음 이름으로 저장하세요 `my_new_룰.py`:

   ```python
   def 룰(event):  
     return 'prod' in event.get('hostName')
   ```
2. 아래 템플릿을 사용하여 메타데이터 파일을 만드세요:

   ```yaml
   AnalysisType: 룰
   DedupPeriodMinutes: 60 # 1 hour
   DisplayName: 형식 확인용 예시 룰
   Enabled: true
   Filename: my_new_룰.py
   룰ID: Type.Behavior.MoreContext
   Severity: 높음
   LogTypes:
     - LogType.GoesHere
   Reports:
     보고서 이름(예: CIS, MITRE ATT&CK):
       - 이 룰과 관련된 특정 보고서 섹션
   태그:
     - 태그
     - Go
     - Here
   설명: >
     이 룰은 Panther CLI의 CLI 워크플로를 검증하기 위한 것입니다
   런북: >
     먼저 이 사양 형식을 작성한 사람이 누구인지 알아낸 다음, 피드백을 보내 알려주세요.
   참조: https://www.a-clickable-link-to-more-info.com
   ```

이 룰이 업로드되면, Panther Console에서 일반적으로 채우게 되는 각 필드가 자동으로 채워집니다. 참조하세요 [룰 사양 참조](#python-rule-specification-reference) 필수 및 선택 필드의 전체 목록을 확인하세요.

</details>

### Python에서 예약 룰을 만드는 방법

Panther Console과 CLI 워크플로 모두에서 Python 예약 룰을 작성할 수 있습니다.

<details>

<summary>Console에서 Python 예약 룰 만들기</summary>

1. Panther Console의 왼쪽 탐색 모음에서 **디택션**.
2. 을 클릭하세요 **새로 만들기**.
3. 의 **예약 룰** 타일에서 **시작**.
4. 생성 페이지에서 예약 룰을 구성하세요:
   * **이름**: 예약 룰에 대한 설명이 있는 이름을 입력하세요.
   * **ID** (선택 사항)**:** 연필 아이콘을 클릭하고 예약 룰의 고유 ID를 입력하세요.
   * 오른쪽 상단에서 **활성화** 토글이 기본적으로 `ON` 기본적으로. 예약 룰을 비활성화하려면 토글을 `OFF`.
   * 로 전환하세요. "In the" **다음 예약 쿼리에 대해** 섹션:
     * **예약 쿼리**: 하나 이상의 항목을 선택하세요 [예약 검색](/ko/search/scheduled-searches.md) 이 예약 룰이 적용되어야 하는
   * 로 전환하세요. "In the" **탐지** 섹션:
     * 로 전환하세요. "In the" **룰 함수** 텍스트 편집기에서 Python `룰` 함수를 작성하여 디택션을 정의하세요.
       * 관련된 [예약 쿼리](/ko/search/scheduled-searches.md), SQL에서 모든 필터링 로직을 이미 처리했다면, `룰` 함수는 단순히 반환하도록 구성할 수 있습니다 `true` 각 행마다:

         ```python
         def 룰(event):  
             True를 반환
         ```
       * 디택션 템플릿과 예시는 다음을 참조하세요. [panther\_analysis GitHub 저장소](https://github.com/panther-labs/panther-analysis/tree/master/templates)
   * 로 전환하세요. "In the" **알러트 생성** 섹션에서 다음을 설정하세요, **알러트 생성** `ON/OFF` 토글. 이는 [알러트](/ko/alerts.md) 가 일치 항목이 있을 때 생성되어야 하는지, 아니면 단순히 [시그널](/ko/detections/signals.md)로 설정했는지를 나타냅니다. `ON`:
     * **심각도**: [심각도 수준](#alert-severity) 을 선택하여 이 디택션으로 트리거되는 알러트에 적용하세요.
     * 로 전환하세요. "In the" **선택 필드** 섹션에서 다음 필드의 값을 선택적으로 입력하세요:
       * **설명**: 룰에 대한 추가 컨텍스트를 입력하세요.
       * **런북**: 이 룰과 관련된 절차 및 작업을 입력하세요.
         * 자세한 내용은 [알러트 런북](/ko/alerts/alert-runbooks.md).
         * 설명적인 런북을 제공하는 것이 권장됩니다. 왜냐하면 [Panther AI 알러트 분류](/ko/alerts.md#panther-ai-alert-triage) 에서 이를 고려하기 때문입니다.
       * **참조**: 이 룰에 대한 추가 정보를 포함한 외부 링크를 입력하세요.
       * **대상 재정의:** 심각도와 관계없이 이 디택션의 알러트를 수신할 대상을 선택하세요. 대상은 룰 함수에서 동적으로 설정할 수도 있습니다. 자세한 내용은 [라우팅 순서 우선순위](/ko/alerts/destinations.md#routing-order-precedence) 를 참조하여 라우팅 우선순위에 대해 자세히 알아보세요.
       * **중복 제거 기간** 및 **이벤트 임계값**: 룰 일치 항목에 대한 중복 제거 기간과 임계값을 입력하세요. 중복 제거가 어떻게 작동하는지 알아보려면 다음을 참조하세요. [중복 제거](#deduplication).
       * **요약 속성**: 이 디택션으로 트리거되는 알러트에서 강조 표시할 속성을 입력하세요.
         * 중첩 필드를 요약 속성으로 사용하려면, 요약 속성 필드에서 Snowflake 점 표기법을 사용하여 JSON 객체의 경로를 따라가세요:

           `<column>:<level1_element>.<level2_element>.<level3_element>`

           그러면 알러트의 참조된 객체에 대해 알러트 요약이 생성됩니다. [Snowflake에서 반정형 데이터를 탐색하는 방법에 대해 자세히 알아보세요.](https://docs.snowflake.com/en/user-guide/querying-semistructured.html#label-traversing-semistructured-data)
         * 알러트 요약에 대한 자세한 내용은 다음을 참조하세요 [알러트 할당 및 관리](/ko/alerts/alert-management.md).
       * **사용자 지정 태그**: 사용자 지정 태그를 입력하여 한눈에 룰을 이해하는 데 도움을 받으세요(예: `HIPAA`.)
       * 로 전환하세요. "In the" **프레임워크 매핑** 섹션:
         1. 을 클릭하세요 **새로 추가** 보고서를 입력하려면.
         2. 다음 필드에 값을 입력하세요:
            * **보고서 키**: 보고서와 관련된 키를 입력하세요.
            * **보고서 값**: 해당 보고서의 값을 입력하세요.
   * 로 전환하세요. "In the" **테스트** 섹션:
     * 로 전환하세요. "In the" **단위 테스트** 섹션에서 **새로 추가** 을 클릭하여 [테스트를 만들고](/ko/detections/testing.md) 이전 단계에서 정의한 룰에 대해.
5. 오른쪽 상단 모서리에서 **저장**.
   * 클릭하면 **저장**, 예약된 룰이 활성화됩니다. 연결된 SQL은 [예약 쿼리](/ko/search/scheduled-searches.md) (쿼리에 정의된 간격마다) 예약된 룰을 통해 실행됩니다(즉, 행이 반환된 경우).

룰을 만든 후에는 다음을 사용하여 수정할 수 있습니다 [인라인 필터](/ko/detections/rules/inline-filters.md).

</details>

<details>

<summary>CLI 워크플로에서 Python으로 예약된 룰 만들기</summary>

로컬에서 디텍션을 작성하는 경우(Panther Console 대신), GitHub 또는 GitLab과 같은 버전 관리 시스템에서 로컬 디텍션 파일을 관리하는 것을 권장합니다.

사용자 지정 디텍션 콘텐츠는 다음 중 하나를 만들어 시작하는 것을 권장합니다 [공개 포크](https://docs.panther.com/panther-developer-workflows/ci-cd/detections-repo/public-fork) 또는 [비공개 복제 저장소](https://docs.panther.com/panther-developer-workflows/ci-cd/detections-repo/private-cloned-repo) Panther의 [오픈소스 panther-analysis 저장소에서](https://github.com/panther-labs/panther-analysis).

**폴더 설정**

룰을 폴더로 그룹화하는 경우, 각 폴더 이름에는 문자열 `룰` 이 포함되어야 업로드 시(PAT 또는 Console의 대량 업로더를 사용하여) 찾을 수 있습니다.

로그/리소스 유형을 기준으로 룰을 폴더로 그룹화하는 것을 권장합니다. 예: `suricata_rules` 또는 `aws_s3_policies`. 다음을 참조로 사용할 수 있습니다. [panther-analysis](https://github.com/panther-labs/panther-analysis) 저장소를

**파일 설정**

각 예약된 룰은 다음으로 구성됩니다:

* Python 파일(확장자가 `.py` 인 파일)로, 디텍션 로직이 포함되어 있습니다.
* YAML 명세 파일(확장자가 `.yml` 인 파일)로, 디텍션의 메타데이터 속성이 포함되어 있습니다.
  * 관례상 이 파일에는 Python 파일과 같은 이름을 붙입니다.

예약된 룰을 사용하면 다음의 출력을 분석할 수 있습니다: [예약된 검색](/ko/search/scheduled-searches.md) 을 Python으로 분석할 때. 반환 값이 `True` 의심스러운 활동을 의미하며, 이는 알러트를 트리거합니다.

1. 쿼리를 작성하고 다음 이름으로 저장합니다: `my_new_scheduled_query.yml`:

   ```yaml
   AnalysisType: scheduled_query
   QueryName: My New Scheduled Query Name
   Enabled: true
   태그:
     - 선택 사항
     - 태그
   설명: >
     선택 가능한 설명
   Query: 'SELECT * FROM panther_logs.aws_cloudtrail LIMIT 10'
   Schedule:
     # 참고: CronExpression과 RateMinutes는 서로 배타적이며, 하나만
     # 구성하세요
     CronExpression: '0 * * * *'
     RateMinutes: 1
     TimeoutMinutes: 1
   ```
2. 룰을 작성하고 다음 이름으로 저장합니다: `my_new_룰.py`:

   ```python
   # 참고: 더 많은 옵션은 예제 룰을 참조하세요
   # https://github.com/panther-labs/panther-analysis/blob/master/templates/example_룰.py

   def 룰(_:):
       # 참고: 여기에 추가 로직을 넣을 수 있습니다
       True를 반환
   ```
3. 메타데이터 파일을 만들고 다음 이름으로 저장합니다: `my_new_schedule_룰.yml`:

   ```yaml
   AnalysisType: scheduled_룰
   Filename: my_new_룰.py 
   룰ID: My.New.룰
   DisplayName: 더 친숙한 이름
   Enabled: true
   ScheduledQueries:
     - 새 예약된 쿼리 이름
   태그:
     - 태그
   Severity: Medium
   설명: >
     선택 가능한 설명
   런북: >
     선택 가능한 Runbook 
   참조: 선택 가능한 reference.link 
   테스트:
     -
       Name: Name 
       ExpectedResult: true
       로그:
         {
           "JSON": "string"
         }
   ```

이 예약된 룰이 업로드되면 각 파일이 예약된 쿼리와 룰을 연결하고, Panther Console에서 일반적으로 채우는 필드가 자동으로 채워집니다. 다음을 참조하세요 [아래 룰 사양 참조](#python-rule-specification-reference) 필수 및 선택 필드의 전체 목록을 확인하세요.

</details>

### Python에서 정책을 만드는 방법

* 정책을 만드는 방법은 다음을 참조하세요: [Policies에서 정책을 작성하는 방법 안내](/ko/detections/policies.md#how-to-write-a-policy).

## Python 디택션 구문

로컬 Python 디택션은 Python 파일과 YAML 파일, 두 파일로 구성됩니다. Panther Console에서 Python 디택션을 만들 때는 YAML 편집기가 아니라 Python 텍스트 편집기만 있습니다. 아래 YAML 열에 나열된 키는 사용자 인터페이스의 필드에서 설정됩니다.

<table data-full-width="false"><thead><tr><th>Python 파일에는 다음이 포함될 수 있습니다:</th><th>YAML 파일에는 다음이 포함될 수 있습니다:</th></tr></thead><tbody><tr><td><ul><li><p>디택션 로직</p><pre class="language-python"><code class="lang-python">def 룰(event): # 또는 def policy(resource):
</code></pre></li><li><p>알러트 함수(동적)</p><pre class="language-python"><code class="lang-python">def severity(event):
def title(event):
def dedup(event):
def unique(event):
def destinations(event):
def runbook(event):
def reference(event):
def description(event):
def 알러트_컨텍스트(event):
</code></pre></li></ul></td><td><ul><li><p>필터 키</p><pre class="language-yaml"><code class="lang-yaml">InlineFilters: 
</code></pre></li><li><p>메타데이터 키</p><pre class="language-yaml"><code class="lang-yaml">AnalysisType: # 룰, scheduled_룰, 또는 policy
Enabled: 
FileName: 
CreatedBy:
룰ID: # 또는 PolicyId:
LogTypes: 
Reports: 
태그: 
테스트: 
ScheduledQueries: # 예약된 룰에만 적용
Suppressions: # 정책에만 적용
알러트 생성: # 정책에는 적용되지 않음
</code></pre></li><li><p>알러트 키(정적)</p><pre class="language-yaml"><code class="lang-yaml">Severity:
Description:
DedupPeriodMinutes:
Threshold: 
DisplayName:
OutputIds:
Reference:
Runbook:
SummaryAttributes: 
</code></pre></li></ul></td></tr></tbody></table>

### **기본 Python 룰 구조**

하나의 `룰()` 함수와 아래에 표시된 YAML 키만 Python 룰에 필요합니다. 그러나 추가 Python 알러트 함수로 알러트를 더 동적으로 만들 수 있습니다. 추가 YAML 키도 사용할 수 있습니다—다음을 참조하세요 [Python 룰 사양 참조](#python-rule-specification-reference).

<table><thead><tr><th>룰.py</th><th>룰.yml</th></tr></thead><tbody><tr><td><pre class="language-python"><code class="lang-python">def 룰(event): 
    if event.get("Something"): 
        True를 반환 
    False를 반환
</code></pre></td><td><pre class="language-yaml"><code class="lang-yaml">AnalysisType: 룰
Enabled: true
파일 이름: 룰.py
룰ID: my.룰
LogTypes: 
    - Some.Schema
심각도: INFO
</code></pre></td></tr></tbody></table>

더 많은 템플릿은 다음을 참조하세요: [GitHub의 panther-analysis 저장소](https://github.com/panther-labs/panther-analysis/tree/master/templates).

### `InlineFilters`

다음 사용 방법에 대해 자세히 알아보세요 `InlineFilters` Python 룰에서 [인라인 필터로 디택션 수정하기](/ko/detections/rules/inline-filters.md#creating-filters-in-the-developer-workflow).

### Python 디택션의 알러트 함수

Panther의 디택션 보조 함수는 분석 로직, 생성된 알러트 제목, 이벤트 그룹화, 알러트 라우팅, 메타데이터 재정의를 제어하는 Python 함수입니다. 룰은 사용자 지정할 수 있으며 표준 Python 라이브러리 또는 [전역 헬퍼](/ko/detections/rules/python/globals.md).

룰과 정책 모두에 적용되며, 아래 각 함수는 단일 인수인 `event` (룰) 또는 `resource` (정책)를 받습니다. 고급 사용자는 아래 정의된 함수 외부에서 함수, 변수 또는 클래스를 정의할 수 있습니다.

다음을 사용 중인 경우 [알러트 중복 제거](/ko/detections/rules.md#deduplication-of-alerts)를 사용하는 경우, *첫 번째* 디택션과 일치하는 이벤트가 이러한 알러트 함수의 매개변수로 사용됩니다.

아래의 각 알러트 함수는 선택 사항이지만, 알러트에 동적 컨텍스트를 추가할 수 있습니다.

<table data-full-width="false"><thead><tr><th width="182.2">알러트 함수</th><th width="307">설명</th><th width="417">기본값</th><th width="399">반환값</th></tr></thead><tbody><tr><td><a href="#severity"><code>severity</code></a></td><td>알러트의 긴급도 수준</td><td><p>YAML에서: <code>심각도</code> 키</p><hr><p>콘솔에서: <strong>심각도</strong> 필드</p></td><td><code>INFO</code>, <code>LOW</code>, <code>MEDIUM</code>, <code>HIGH</code>,<code>CRITICAL</code>또는 <code>DEFAULT</code></td></tr><tr><td><a href="#title"><code>title</code></a></td><td>생성된 알러트 제목</td><td><p>YAML에서: <code>DisplayName</code> > <code>룰ID</code> 또는 <code>정책ID</code></p><hr><p>콘솔에서: <strong>이름</strong> field > <strong>ID</strong> 필드</p></td><td><code>String</code></td></tr><tr><td><a href="#dedup"><code>dedup</code></a></td><td>관련 이벤트를 그룹화하는 문자열로, 1000자로 제한됩니다</td><td><p>Python/YAML에서: <code>title()</code> > <code>DisplayName</code> > <code>룰ID</code> 또는 <code>정책ID</code></p><hr><p>콘솔에서: <code>title()</code> > <strong>이름</strong> field > <strong>ID</strong> 필드</p></td><td><code>String</code></td></tr><tr><td><a href="#unique"><code>unique</code></a></td><td>고유 임계값 디택션을 위해 추적할 값</td><td>해당 없음 - 표준 이벤트 수 임계값을 사용합니다</td><td><code>String</code></td></tr><tr><td><a href="#alert_context"><code>알러트_context</code></a></td><td>알러트 대상(들)에 전달할 추가 컨텍스트</td><td></td><td><code>Dict[String: Any]</code></td></tr><tr><td><a href="#runbook"><code>런북</code></a></td><td>알러트가 생성된 후 따라야 할 지침 목록입니다. 설명이 충분한 런북을 제공하는 것이 권장됩니다. 이는 <a href="/pages/6e9f85a6a2f1c7f2fb9c3093e77d535eff45c9f4#panther-ai-alert-triage">Panther AI 알러트 분류</a> 에서 이를 고려하기 때문입니다.</td><td><p>YAML에서: <code>런북</code> 키</p><hr><p>콘솔에서: <strong>런북</strong> 필드</p></td><td><code>String</code></td></tr><tr><td><a href="#reference-and-description"><code>설명</code></a></td><td>이 룰이 존재하는 이유에 대한 설명</td><td><p>YAML에서: <code>설명</code> 키</p><hr><p>콘솔에서: <strong>설명</strong> 필드</p></td><td><code>String</code></td></tr><tr><td><a href="#reference-and-description"><code>reference</code></a></td><td>이 룰에 대한 내부 문서나 온라인 리소스로 연결되는 참조 URL</td><td><p>YAML에서: <code>참조</code> 키</p><hr><p>콘솔에서: <strong>참조</strong> 필드</p></td><td><code>String</code></td></tr><tr><td><a href="#destinations"><code>대상</code></a></td><td>알러트를 보낼 대상의 ID(들).</td><td><p>YAML에서: <code>OutputIds</code> 키</p><hr><p>콘솔에서: <strong>대상 재정의</strong> 필드</p></td><td><code>List[대상 이름/ID]</code></td></tr></tbody></table>

#### `severity`

일부 시나리오에서는 알러트의 심각도 수준을 올리거나 내릴 필요가 있을 수 있습니다. 알러트의 심각도 수준은 다음에 매핑될 수 있습니다 `INFO`, `LOW`, `MEDIUM`, `HIGH`, `CRITICAL`또는 `DEFAULT`. 반환 `DEFAULT` 정적으로 정의된 룰 심각도로 폴백합니다.

심각도 문자열은 대소문자를 구분하지 않으므로, 예를 들어 다음을 반환할 수 있습니다. `Critical` 또는 `default`스타일 선호도에 따라 다릅니다.

아래 예시에서 API 토큰이 생성된 경우, 하나의 `HIGH` 심각도 알러트가 생성됩니다—그렇지 않으면 하나의 `INFO` 레벨 알러트가 생성됩니다:

```python
def severity(event):
    if event.get('eventType') == 'system.api_token.create':
        return "HIGH"
    return "INFO"
```

Reference: [템플릿 룰](https://github.com/panther-labs/panther-analysis/blob/master/templates/example_rule.py#L33)

사용 예 `DEFAULT`:

```python
def severity(event):
    if event.get('eventType') == 'system.api_token.create':
        return "HIGH"
    return "DEFAULT"
```

#### `title`

함수는 `title()` 선택 사항이지만, 알러트에 추가 컨텍스트를 제공하기 위해 포함하는 것이 좋습니다.

아래 예시에서는 로그 유형, 사용자 이름, 그리고 정적 문자열이 알러트 대상(들)로 전송됩니다. 함수는 이벤트가 AWS.CloudTrail 로그 유형과 관련이 있는지 확인하고, 그렇다면 AWS 계정 이름을 반환합니다.

알러트 제목이 어떻게 설정되는지에 대해 자세히 알아보려면 다음을 참조하세요: [룰 및 예약된 룰](/ko/detections/rules.md#title-of-associated-alerts).

예시:

```python
def title(event):
    # title에서 통합 데이터 모델 필드 사용
    log_type = event.get("p_log_type")
    title_str = (
        f"{log_type}: 사용자 [{event.udm('actor_user')}]가 실패한 로그인 임계값을 초과했습니다"
    )
    if log_type == "AWS.CloudTrail":
        title_str += f" [{lookup_aws_account_name(event.get('recipientAccountId'))}] 내에서"
    return title_str
```

Reference: [템플릿 룰](https://github.com/panther-labs/panther-analysis/blob/master/templates/example_rule.py#L15)

#### `dedup`

중복 제거는 중복 알러트 수신을 방지하기 위해 관련 이벤트를 단일 알러트로 그룹화하는 프로세스입니다. 동일한 디택션을 트리거하고 중복 제거 문자열도 공유하는 이벤트는 중복 제거 기간 내에 하나의 알러트로 함께 그룹화됩니다. 다음은 `dedup` 함수는 중복 제거 문자열을 정의하는 한 가지 방법입니다. 길이는 1000자로 제한됩니다.

중복 제거에 대해 자세히 알아보려면 다음을 참조하세요: [룰 및 예약된 룰](/ko/detections/rules.md#deduplication).

예시:

```python
def dedup(event):
	user_identity = event.get("userIdentity", {})

	if user_identity.get("type") == "AssumedRole":
		return helper_strip_role_session_id(user_identity.get("arn", ""))

	return user_identity.get("arn")
```

Reference: [AWS S3 버킷 삭제 룰](https://github.com/panther-labs/panther-analysis/blob/4b6b79846fb4cb1596908fd31ce983c75a39baaa/aws_cloudtrail_rules/aws_s3_bucket_deleted.py)

#### `unique`

함수는 `unique()` 함수는 고유 값 임계값 디택션을 활성화하여, 룰이 총 이벤트 수가 아니라 고유 값 개수를 기준으로 알러트하도록 합니다. 이는 분산 공격, 데이터 유출, 관리 권한 오용 시나리오를 탐지하는 데 유용합니다.

여러 사용자에 걸친 로그인 무차별 대입을 탐지하는 예시:

```python
def 룰(event):
    return (
        event.get("eventType") == "user.session.start" and
        event.get("outcome", {}).get("result") == "FAILURE"
    )

def unique(event):
    # 추적할 고유 사용자 이름
    return event.get("actor", {}).get("alternateId", "unknown_user")
```

임계값이 5이면, 이 룰은 중복 제거 기간 내에 실패한 로그인 시도가 5개 이상의 고유 사용자 이름을 대상으로 할 때 알러트합니다.

함수는 `unique()` 함수는 항상 문자열을 반환해야 합니다. 여러 필드의 고유성을 확인하려면 필드를 연결하세요:

```python
def unique(event):
    user = event.get("username", "")
    ip = event.get("sourceIP", "")
    return f"{user}@{ip}"
```

추가 예시를 포함한 고유 값 임계값 디택션에 대해 자세히 알아보려면 다음을 참조하세요: [고유 값 임계값 디택션](#unique-value-threshold-detection).

#### **`대상`**

함수는 `destinations()` 함수는 룰에서 발생한 알러트를 어느 알러트 대상(들)로 보낼지 지정하는 방법입니다. 이는 다른 모든 알러트 대상 구성보다 우선합니다(즉, [시나리오 1](/ko/alerts/destinations.md#scenario-1-dynamically-defined-destination-s-on-the-detection) 다음의 [알러트 라우팅 시나리오](/ko/alerts/destinations.md#alert-routing-scenarios)).

함수는 `destinations()` 함수는 하나 이상의 알러트 대상 이름 또는 UUID 목록을 반환해야 합니다. 만약 다음이 반환한 목록이 `destinations()` 함수가 비어 있으면 (`[]`), 알러트는 어떤 대상에도 라우팅되지 않습니다.

예를 들어, 아래 룰은 여러 로그 유형과 연결되어 있습니다. 로그 유형이 `AWS.CloudTrail`, `destinations()` 다음으로 알러트를 라우팅합니다. `slack-security-alerts` 대상입니다. 로그 유형이 다음이 아닌 경우 `AWS.CloudTrail`외부 대상에는 알러트가 전송되지 않습니다—이는 `return []`.

```python
def destinations(event):
    if event.get("p_log_type") == "AWS.CloudTrail":
        return ["slack-security-alerts"] # 대상의 이름 또는 UUID
    # 알러트를 외부 대상으로 보내지 않음
    return []
```

다음에서 다른 예시를 확인하세요: [panther-analysis example\_룰](https://github.com/panther-labs/panther-analysis/blob/main/templates/example_rule.py#L66).

#### `알러트_context`

이 함수는 디택션이 사용자 이름, IP 주소, 성공/실패와 같은 이벤트 세부 정보를 추가 컨텍스트로 알러트 대상(들)에 전달할 수 있게 합니다.

알러트 컨텍스트 딕셔너리에 포함된 값은 JSON 호환이어야 합니다. 호환되지 않는 값의 예로는 Python의 `nan`, `inf`그리고 `-inf`.

예시:

아래 코드는 모든 이벤트 데이터를 알러트 컨텍스트로 반환합니다.

```python
def 룰(event):
    return (
        event.get("actionName") == "UPDATE_SAML_SETTINGS"
        and event.get("actionResult") == "SUCCEEDED"
    )

def 알러트_컨텍스트(event):
    return {
        "user": event.udm("actor_user"),
        "ip": event.udm("source_ip")
    }
```

#### `런북`

함수는 `런북` 함수 출력은 이 디택션으로 생성된 알러트를 분류하기 위한 실행 가능한 조사 단계를 제공해야 합니다.

언제 [Panther AI가 알러트를 분류할 때](/ko/alerts.md#panther-ai-alert-triage)그러면 런북을 읽고 자율적으로 실행합니다. 효과적인 런북 작성 방법에 대해 자세히 알아보려면 다음을 참조하세요: [알러트 런북](/ko/alerts/alert-runbooks.md).

예시:

```python
def runbook(event):
    user_arn = event.deep_get("userIdentity", "arn", default="this user")
    source_ip = event.deep_get("sourceIPAddress", default="this IP address")
    
    return f"""
    1. 알러트가 발생하기 전 24시간 동안 {user_arn}의 모든 API 호출을 찾습니다
    2. 소스 IP {source_ip}가 알려진 클라우드 제공업체 IP 범위 또는 VPN 엔드포인트와 연관되어 있는지 확인합니다
    3. 지난 7일 동안 {user_arn} 또는 {source_ip}에서 발생한 다른 알러트를 찾습니다
    """
```

#### `reference` 및 `설명`

함수는 `reference` 및 `설명` 함수는 알러트가 트리거된 이유와 관련 문제를 해결하는 방법에 대한 추가 컨텍스트를 제공할 수 있습니다.

아래 예시는 다음 내에서 동적으로 링크를 제공합니다. `reference` 알러트의 필드:

```python
def reference(event):
	log_type = event.get("p_log_type")
	if log_type == "OnePassword.SignInAttempt":
		return: f"<https://link/to/resource>"
	elif log_type == "Okta.SystemLog":
		return: f"<https://link/to/resource/2>"
	else: 
		return: f"<https://default/link>"
```

## 이벤트 객체 함수

Python 디택션에서, `룰()` 함수와 모든 [동적 알러트 함수는](#alert-functions-in-python-detections) 단일 인수인 다음을 받습니다: `event` 객체입니다. 이 이벤트 객체에는 이벤트 값을 간단히 추출할 수 있는 내장 함수가 있습니다.

### `get()`

{% code title="함수 시그니처" %}

```python
def get(self, key, default=None) -> Any:
```

{% endcode %}

다음을 사용하세요: `get()` 최상위 이벤트 필드에 접근합니다. 키를 찾을 수 없으면 반환될 기본값을 제공할 수 있습니다.

다음을 사용하여 최상위 필드에 접근하는 것도 가능합니다: [`deep_get()`](#deep_get) 및 [`deep_walk()`](#deep_walk). 다음에 대해 자세히 알아보세요: [아래에서 최상위 필드에 안전하게 접근하는 방법](#accessing-top-level-fields-safely).

예시:

{% code title="예시 이벤트" %}

```json
{
  "key": "value"
}
```

{% endcode %}

{% code title="get() 사용" %}

```python
def 룰(event):
    return event.get("key") == "value"

# 위 코드는 true를 반환합니다
```

{% endcode %}

### `deep_get()`

{% code title="함수 시그니처" %}

```python
def deep_get(self, *keys: str, default: Any = None) -> Any:
```

{% endcode %}

다음을 사용하세요: `deep_get()` Python 딕셔너리 내부에 중첩된 키를 반환합니다.

검색하려는 값이 리스트 안에 있으면 다음을 사용하세요: [`deep_walk()`](#deep_walk) 대신.

{% hint style="info" %}
이 함수는 [전역 헬퍼로도 제공됩니다](/ko/detections/rules/python/globals.md#deep_get)하지만 편의를 위해 이 이벤트 객체 함수를 사용하는 것이 권장됩니다.
{% endhint %}

예시:

다음 구조를 가진 이벤트가 주어졌을 때

{% code title="예시 이벤트" %}

```json
{
  "object": {
    "nested": {
       "key": "here"
      }
   }
 }
```

{% endcode %}

{% code title="deep\_get() 사용하기" %}

```python
def 룰(event):
    return event.deep_get("object", "nested", "key") == "here"
    
# 위 코드는 true를 반환합니다
```

{% endcode %}

### `deep_walk()`

{% code title="함수 시그니처" %}

```python
def deep_walk(
        self, *keys: str, default: Optional[str] = None, return_val: str = "all"
    ) -> Union[Optional[Any], Optional[List[Any]]]:
```

{% endcode %}

다음을 사용하세요: `deep_walk()` 파이썬 딕셔너리에서 깊이 중첩된 키와 연결된 값을 반환하기 위해 사용합니다. 여기에는 여러 개의 딕셔너리나 리스트가 포함될 수 있습니다. 여러 이벤트 필드와 일치하면 일치 항목의 배열이 반환되고, 하나만 일치하면 해당 일치 항목의 값이 반환됩니다.

{% hint style="info" %}
이 함수는 [전역 헬퍼로도 제공됩니다](/ko/detections/rules/python/globals.md#deep_walk)하지만 편의를 위해 이 이벤트 객체 함수를 사용하는 것이 권장됩니다.
{% endhint %}

예시:

{% code title="예시 이벤트" %}

```json
{
  "object": {
    "nested": {
       "list": [
          {
             "key": "first"
          },
          {
             "key": "second"
          }
         ]
      }
   }
 }
```

{% endcode %}

{% code title="deep\_walk() 사용하기" %}

```python
def 룰(event):
    return "first" in event.deep_walk("object", "nested", "list", "key", default=[])

# 위 코드는 true를 반환합니다
```

{% endcode %}

### `lookup()`

{% code title="함수 시그니처" %}

```python
def lookup(self, lookup_table_name: str, lookup_key: str) -> Any:
```

{% endcode %}

함수는 `lookup()` 이 함수는 다음의 데이터에 동적으로 접근할 수 있게 해줍니다 [사용자 지정 조회 테이블](https://docs.panther.com/enrichment) 및 [Panther에서 관리하는 Enrichment 공급자](/ko/enrichment.md) 탐지에서 사용할 수 있습니다. 이 `lookup()` 함수는 들어오는 로그에 조회 테이블의 기본 키 열 값과 정확히 일치하는 항목이 없는 경우 유용할 수 있습니다. Python을 사용해 이벤트 값을 수정한 뒤 다음에 전달할 수 있습니다 `lookup()` 보강 데이터를 가져오기 위해.

`lookup()` 두 개의 인수를 받습니다:

* 조회 테이블의 이름
  * 다음에 전달되는 조회 테이블 이름은 `lookup()` 에서 표시되는 그대로여야 합니다 **Enrichment 공급자** 또는 **조회 테이블** Panther 콘솔의 페이지에 표시됩니다. 이 이름은 검색 쿼리에 표시되는 방식과 문법적으로 다를 수 있습니다. 예를 들어, `My-Custom-LUT` 대신 `my_custom_lut`.
* 조회 테이블의 기본 키

제공된 키에 대해 조회 테이블에서 일치 항목이 발견되면 전체 조회 테이블 행이 Python 딕셔너리로 반환됩니다. 일치 항목이 없으면, `None` 이 반환됩니다.

{% hint style="info" %}
이 `lookup()` 이 함수는 "자동" 이벤트 보강과 다릅니다. 이는 Selector로 지정된 이벤트 필드의 값이 조회 테이블의 기본 키 열 값과 정확히 일치할 때 발생합니다. 이 경우 조회 테이블 데이터가 이벤트의 `p_enrichment` 필드에 추가됩니다. 자세한 내용은 [Custom Lookup Tables의 "로그와 조회 테이블 간 데이터는 어떻게 일치하나요?"](/ko/enrichment/custom.md#how-is-data-matched-between-logs-and-lookup-tables).

이 방식으로 "자동" 보강을 사용하는 경우, 중첩된 보강 데이터에 접근할 때 다음을 사용합니다 [`deep_walk()`](#deep_walk) 대신.
{% endhint %}

사용 예 `lookup()`:

```python
# user_roles라는 이름의 조회 테이블에 다음 항목이 있다고 가정해 보겠습니다:
# 1행: {"id": "your@email.com", "role": "admin"}
# 2행: {"id": "vistor@email.com", "role": "guest"}

# 이 룰에서는 사용자가 admin이 아닌 역할을 가지고 있으면 True를 반환하고자 합니다
# 조회 테이블에서 role을 가져오고 싶지만, 이벤트에는 
# 조회 테이블의 기본 키(이메일 주소)가 포함되어 있지 않습니다
def 룰(event):
    lookup_table_name = "user_roles"
    # 이벤트에는 username에 대한 접근 권한이 *있으며*, 이를 통해
    # 이메일 주소를 생성할 수 있습니다
    user_name = event.get("username", "").lower()
    lookup_key = f"{user_name}@email.com" # 조회 키, 즉 "Selector"를 동적으로 구성
    
    lookup_data = event.lookup(lookup_table_name, lookup_key)
    # 일치 항목이 있으면 `lookup_data`에는 전체 데이터 행이 포함됩니다
    # 그렇지 않으면 None을 반환합니다
    
    if (lookup_data and lookup_data.get("role") != "admin") or lookup_data is None:
        True를 반환
        
    False를 반환
```

#### 다음을 사용하는 탐지의 단위 테스트 `lookup()`

언제 [단위 테스트](/ko/detections/testing.md) 가 실행될 때, `lookup()` 실시간 데이터를 검색하지 않습니다. 조회 기능을 모방하려면 다음을 추가하세요: `_mocked_lookup_data_` 필드를 각 단위 테스트의 이벤트 페이로드에 추가하여 조회 테이블 데이터를 모킹합니다. 다음은 사용할 수 없습니다 [enrich test data 버튼 또는 CLI 명령](/ko/detections/testing.md#enrich-test-data) 와 함께 `lookup()`.

`_mocked_lookup_data_` 다음 예시와 같이 구성되어야 합니다:

{% code title="event.lookup() 모킹" %}

```json5
{
  "_mocked_lookup_data_": {
     "user_roles": { # 이 키는 조회 테이블의 이름입니다
         # 이 객체의 키는 조회 테이블 키여야 합니다
         # 이 객체의 값은 조회 테이블 데이터 객체여야 합니다
         "your@email.com": {"id": "your@email.com", "role": "admin"},
         "vistor@email.com": {"id": "vistor@email.com", "role": "guest"}
      }
   }
}
```

{% endcode %}

다음을 지정하지 않으면 `_mocked_lookup_data_` 단위 테스트에서 필드를 지정하지 않으면 다음 호출 시도는 `lookup()` 을 반환합니다 `None/null`.

### `udm()`

{% code title="함수 시그니처" %}

```python
def udm(self, *key: str, default: Any = None) -> Any:
```

{% endcode %}

함수는 `udm()` 이 함수는 주로 다음에 접근할 수 있도록 하기 위한 것입니다 [데이터 모델](/ko/detections/rules/python/data-models.md), 하지만 이벤트 필드에 접근하는 데에도 사용할 수 있습니다.

다음은 `udm()` 함수가 작동하는 방식입니다:

1. 이 함수는 먼저 다음이 있는지 확인합니다: [데이터 모델](/ko/detections/rules/python/data-models.md) 다음에 전달된 값에 대해 정의된 키 매핑이 있는지 `udm()`. 있으면 데이터 모델 값이 반환됩니다.
   * 다음이 있으면 [데이터 모델](/ko/detections/rules/python/data-models.md) 다음에 전달된 값에 대한 키가 정의되어 있으면 `udm()`, 함수는 해당 값을 반환하고 아래의 2단계로 진행하지 않습니다. 평가 중인 이벤트에 데이터 모델 매핑에 정의된 키 경로가 포함되어 있지 않더라도 이는 동일합니다. 이 경우, `null` 이 반환됩니다.
2. 다음이 없으면 [데이터 모델](/ko/detections/rules/python/data-models.md) 다음에 전달된 값에 대해 정의된 `udm()`, 함수는 그 이름의 이벤트 필드가 있는지 확인합니다. 있으면 해당 값이 반환됩니다.
   * 이 경우, `udm()` 는 중첩된 필드를 포함한 모든 이벤트 필드를 확인합니다. 그 동작은 다음과 유사합니다: [`deep_get()`](#deep_get).

{% hint style="info" %}
위에서 설명한 동작은 다음을 사용하는 것이 가능하다는 뜻입니다 `udm()` 이벤트 필드 값에 접근할 수 있는 경우는 또한 다음이 없을 때뿐입니다: [데이터 모델](/ko/detections/rules/python/data-models.md) 동일한 키로 정의된 매핑.
{% endhint %}

{% hint style="warning" %}
[데이터 모델은 예약된 룰과 함께 사용할 수 없습니다](/ko/detections/rules/python/data-models.md#overview). 호출하면 `udm()` 예약된 룰에서 실행해도 런타임에 데이터 모델에 접근하지 않습니다. 예약된 룰은 로그 유형 이벤트가 아니라 예약된 쿼리 출력으로 동작하기 때문입니다.
{% endhint %}

{% code title="udm 사용 예시" %}

```python
# 데이터 모델을 사용할 때의 예시 사용법 
def 룰(event):
  return event.udm('field_on_data_model')
  
# 기본값을 사용하여 데이터 모델을 사용할 때의 예시 사용법
def 룰(event):
  # default 매개변수는 경로 기반 매핑을 사용할 때만 적용됩니다
  # 데이터 모델에 대해. 데이터 모델이 함수에 매핑되어 있다면, 그 함수가 반환하는 값은 무엇이든
  # 적용됩니다
  return event.udm('field_on_data_model', default='')
  
```

{% endcode %}

#### 사용 예 `udm()` 값에 접근하려면 [데이터 모델](/ko/detections/rules/python/data-models.md) 값:

{% code title="데이터 모델 예시" %}

```yaml
매핑:
  - 이름: source_ip
    경로: nested.srcIp
```

{% endcode %}

{% code title="예시 이벤트" %}

```json
{
  "nested": {
    "srcIp": "127.0.0.1"
  }
}
```

{% endcode %}

{% code title="udm() 사용" %}

```python
def 룰(event):
    return event.udm("source_ip") == "127.0.0.1"

# 위 코드는 true를 반환합니다
```

{% endcode %}

## 고유 값 임계값 디택션

Panther는 고유 값 임계값 디택션을 지원하며, 이를 통해 룰은 전체 이벤트 수가 아니라 관찰된 고유 값의 개수에 따라 알러트를 발생시킬 수 있습니다(예: "10개 이상의 고유 IP 주소가 보이면 알러트"). 이는 다음과 같은 시나리오를 디택션하는 데 유용합니다:

* 서로 다른 IP 주소에서의 여러 로그인 시도
* 여러 사용자 이름을 대상으로 하는 무차별 대입 공격
* 여러 외부 도메인으로의 데이터 유출
* 여러 리소스에 영향을 주는 관리 작업

### 함수는 `unique()` 함수

고유 값 임계값 디택션을 활성화하려면 `unique()` Python 룰에서 고유 값으로 계산할 대상을 나타내는 문자열 값을 반환하는 함수를 정의하세요.

{% code title="함수 시그니처" %}

```python
def unique(event) -> str:
```

{% endcode %}

함수는 `unique()` 함수는 추적할 고유 값을 식별하는 문자열을 반환해야 합니다. 일반적인 예로는 IP 주소, 사용자 이름, 도메인 이름 또는 리소스 ID가 있습니다.

#### 예시: 여러 IP 로그인 디택션

```python
def 룰(event):
    # 이 로그인이 성공한 로그인 이벤트인지 확인
    return (
        event.get("eventName") == "ConsoleLogin" and
        event.deep_get("responseElements", "ConsoleLogin") == "Success"
    )

def unique(event):
    # 고유한 소스 IP 주소 추적
    return event.get("sourceIPAddress")

# threshold=5이면, 5개 이상의 고유 IP가
# 중복 제거 기간 내에 성공적으로 로그인했을 때
```

#### 예시: 다중 대상 무차별 대입 디택션

```python
def 룰(event):
    # 실패한 로그인 시도 확인
    return (
        event.get("eventType") == "user.session.start" and
        event.get("outcome", {}).get("result") == "FAILURE"
    )

def unique(event):
    # 공격받는 고유 대상 사용자 이름 추적
    return event.get("actor", {}).get("alternateId")

# threshold=10이면, 10명 이상의 서로 다른 사용자가
# 중복 제거 기간 내에 실패한 로그인 시도를 경험할 때
```

#### 예시: 데이터 유출 디택션

```python
def 룰(event):
    # 클라우드 스토리지에서의 파일 다운로드를 찾기
    return (
        event.get("eventName") == "GetObject" and
        event.get("responseElements", {}).get("x-amz-request-charged") != "requester"
    )

def unique(event):
    # 액세스되는 고유 파일 추적
    bucket = event.get("requestParameters", {}).get("bucketName", "")
    key = event.get("requestParameters", {}).get("key", "")
    return f"{bucket}/{key}"

# threshold=50이면, 50개 이상의 고유 파일이
# 중복 제거 기간 내에 다운로드될 때
```

### 고유 값 임계값 지정이 작동하는 방식

다음을 정의하면 `unique()` 함수:

1. **값 추출**: 일치하는 각 이벤트마다 Panther는 귀하의 `unique()` 함수를 호출해 추적할 고유 값을 추출합니다
2. **확률적 카운팅**: Panther는 메모리 효율적인 확률적 알고리즘을 사용해 관찰된 고유 값의 개수를 추정합니다
3. **임계값 확인**: 추정된 고유 개수가 설정한 임계값에 도달하면 알러트가 생성됩니다
4. **중복 제거**: 고유 개수는 룰의 중복 제거 기간에 따라 초기화됩니다

### 구성 요구 사항

고유 값 임계값 지정을 사용하려면:

* 다음을 정의하세요 `unique()` 문자열을 반환하는 함수
* 룰의 **임계값** 알러트를 트리거하는 데 필요한 최소 고유 값 수로 설정합니다(기본값: 1)
* 적절한 **중복 제거 기간** 를 사용 사례에 맞게 구성하세요(기본값: 1시간)

### 성능 고려 사항

* **정확도**: 고유 카운팅 알고리즘은 최대 1,000개의 고유 값까지 약 90%의 정확도를 제공합니다
* **메모리 효율성**: 고유 값의 수와 관계없이 알러트당 약 16KB의 저장 공간을 사용합니다
* **권장 제한**: 1,000개 미만의 고유 값 임계값에서 최상의 성능을 보입니다
* **연결**: 여러 필드의 고유성을 위해, 귀하의 `unique()` 함수: `return f"{ip}:{username}"`

### 하위 호환성

다음이 없는 룰은 `unique()` 함수는 계속 표준 이벤트 수 임계값 지정을 사용합니다. 기존 룰에 `unique()` 함수를 추가하거나 제거하면 알러트 동작이 변경됩니다.

## Python 모범 사례

Python 개선 제안 [리소스를 게시합니다](https://peps.python.org/pep-0008/) Python 코드를 깔끔하고 효과적으로 작성하고 스타일링하는 방법에 대해. 예를 들어, [autopep8](https://pypi.org/project/autopep8/) 작성한 디택션이 모두 일관된 스타일을 따르도록 자동으로 보장하는 데 사용할 수 있습니다.

### 사용 가능한 Python 라이브러리

다음 Python 라이브러리는 Panther에서 다음 외에도 사용할 수 있습니다 `boto3`, 제공: [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html):

<table data-header-hidden><thead><tr><th width="204">패키지</th><th width="174">버전</th><th width="186">설명</th><th>라이선스</th></tr></thead><tbody><tr><td>패키지</td><td>버전</td><td>설명</td><td>라이선스</td></tr><tr><td><code>jsonpath-ng</code></td><td><code>1.5.2</code></td><td>JSONPath 구현</td><td>Apache v2</td></tr><tr><td><code>policyuniverse</code></td><td><code>1.3.3.20210223</code></td><td>AWS ARN 및 정책 파싱</td><td>Apache v2</td></tr><tr><td><code>requests</code></td><td><code>2.23.0</code></td><td>간편한 HTTP 요청</td><td>Apache v2</td></tr></tbody></table>

## Python 디택션 작성 모범 사례

### 디택션에 대한 테스트 작성

새 디택션을 활성화하기 전에 [테스트를 작성하는 것이 권장됩니다 ](/ko/detections/testing.md)알러트가 생성되어야 하거나 생성되지 않아야 하는 시나리오를 정의하는 테스트를 작성하세요. 가장 좋은 방법은 신뢰성을 최대한 보장하기 위해 최소 하나의 양성 사례와 하나의 음성 사례를 포함하는 것입니다.

### 이벤트 필드의 대소문자 처리

이벤트 필드 조회는 대소문자를 구분하지 않습니다. `event.get("Event_Type")` 또는 `event.get("event_type")` 는 동일한 결과를 반환합니다.

### 최상위 필드와 중첩 필드 이해하기

최상위 필드는 중첩 데이터 구조의 상위 필드를 나타냅니다. 예를 들어, 레코드에는 다음과 같은 이름의 필드가 있을 수 있습니다 `user` 그 아래에 다음과 같은 다른 필드가 있습니다 `ip_address`. 이 경우, `user` 가 최상위 필드이고, `ip_address` 는 그 아래의 중첩 필드입니다.

중첩은 여러 계층 깊이로 발생할 수 있으므로, 스키마 구조를 이해하고 디택션에서 특정 필드에 어떻게 접근하는지 아는 것이 중요합니다.

### **최상위 필드에 안전하게 접근하기**

기본 룰은 이벤트의 필드 값을 일치시키며, 오류를 방지하는 모범 사례는 Python의 내장 [`get()`](#get) 함수를 활용하는 것입니다.

아래 예시는 다음을 활용하므로 모범 사례입니다 `get()` 함수를 활용하는 것입니다. `get()` 필드를 찾고, 필드가 존재하지 않으면 `None` 오류 대신 반환되며, 이로 인해 디택션이 `False`.

```python
def 룰(event):
    return event.get('field') == 'value'
```

아래 예시에서 필드가 존재하면 해당 필드의 값이 반환됩니다. 그렇지 않으면, `False` 가 반환됩니다:

```python
def 룰(event):
    if event.get('field')
        return event.get('field')
    False를 반환
```

{% hint style="warning" %}
**잘못된 예시**\
아래 룰 정의는 코드가 필드 이름을 명시적으로 사용하므로 잘못된 예시입니다. 필드가 존재하지 않으면 Python은 `KeyError`:

```python
def 룰(event):
    return event['field'] == 'value'
```

{% endhint %}

### Global Helper 함수 사용

많은 디택션이 작성되면 패턴과 반복되는 코드가 나타나기 시작합니다. 이는 다음에 아주 적합한 사용 사례입니다 [Global Helper 함수](/ko/detections/rules/python/globals.md), 이 로직이 모든 디택션 전반에서 존재할 수 있도록 중앙 집중식 위치를 제공합니다.

### 중첩 필드에 안전하게 접근하기

이벤트 내부의 깊숙이 중첩된 필드에 접근하려면 [`deep_get()`](#deep_get) 및 [`deep_walk()`](#deep_walk) 이벤트 객체에서 사용할 수 있는 함수를 사용하세요. 이러한 함수는 또한 [Global Helper 함수](/ko/detections/rules/python/globals.md), 형태로도 제공되지만, 편의를 위해 이벤트 객체 버전을 사용하는 것이 권장됩니다.

예시:

AWS CloudTrail 로그는 다음을 중첩합니다 `type` 콘솔에 접근하는 사용자의 `userIdentity`. 다음은 JSON CloudTrail 루트 활동 로그의 일부입니다:

```json
{ 	
       "eventVersion": "1.05",
       "userIdentity": { 	
               "type": "Root", 	
               "principalId": "1111", 	
               "arn": "arn:aws:iam::123456789012:root", 	
               "accountId": "123456789012", 		
               "userName": "root" 
               }, 	
        ... 
 }
```

다음의 값을 확인하는 방법을 보세요 `type` 두 형식의 `deep_get()`:

{% tabs %}
{% tab title="deep\_get() 이벤트 객체 함수를 사용하여 안전하게" %}
다음을 사용하여 이벤트 값을 확인하기 [이벤트 객체 `deep_get()` 함수](#deep_get):

```python
def 룰(event):
    return event.deep_get("userIdentity", "type") == "Root"
```

{% endtab %}

{% tab title="deep\_get() Global Helper 함수" %}
다음을 사용하여 이벤트 값을 확인하기 [`deep_get()` Global Helper 함수](/ko/detections/rules/python/globals.md#deep_get):

```python
from panther_base_helpers import deep_get

def 룰(event):
    return deep_get(event, "userIdentity", "type") == "Root"
```

{% endtab %}
{% endtabs %}

### **특정 값을 위한 필드 확인**

특정 이벤트가 발생했는지 알고 싶을 수 있습니다. 발생했다면 디택션이 알러트를 트리거해야 합니다. Panther는 모든 것을 정규화된 JSON으로 저장하므로, 지정한 기준과 필드 값을 비교할 수 있습니다.

예를 들어, Box 기술 지원에 Box 계정 접근 권한을 부여하는 작업을 디택션하려면 아래 Python을 사용해 다음에 해당하는 이벤트를 일치시킬 수 있습니다 `event_type` 같음 `ACCESS_GRANTED`:

```python
def 룰(event):
    return event.get("event_type") == "ACCESS_GRANTED"
```

필드가 `event_type` 이고 값이 다음과 같으면 `ACCESS_GRANTED` 그럼 룰 함수는 다음을 반환합니다 `true` 그리고 알러트가 생성됩니다.

### 정수 값에 대한 필드 확인

필드 값을 정수와 비교해야 할 수 있습니다. 이를 통해 이벤트에 대해 Python의 내장 비교 연산자를 사용할 수 있습니다.

예를 들어, HTTP 응답 상태 코드를 기반으로 알러트를 생성할 수 있습니다:

```python
# 'status_code'가 404와 같으면 True를 반환
def 룰(event):
    if event.get("status_code"):
        return event.get("status_code") == 404
    else:
        False를 반환

# 'status_code'가 400보다 크면 True를 반환
def 룰(event):
    if event.get("status_code"):
        return event.get("status_code") > 404
    else:
        False를 반환
```

Reference:

* [box\_access\_granted.py](https://github.com/panther-labs/panther-analysis/blob/cd220c87982011d4ad156c7daecd2857c358d154/rules/box_rules/box_access_granted.py)
* [Python 연산자](https://www.w3schools.com/python/python_operators.asp)

### **유니버설 데이터 모델 사용**

[데이터 모델](/ko/detections/rules/python/data-models.md) 모든 로그 유형에서 공통으로 사용할 통합 필드 집합을 구성할 수 있는 방법을 제공합니다. 기본적으로 Panther에는 여러 로그 유형에 대한 내장 데이터 모델이 포함되어 있습니다. 사용자 지정 데이터 모델은 Panther Console 또는 다음을 통해 추가할 수 있습니다 [Panther Analysis Tool](https://docs.panther.com/writing-detections/panther-analysis-tool#data-models).

[`event.udm()`](#udm) 는 Panther 환경에 기존 데이터 모델이 있는 로그 유형에서만 사용할 수 있습니다.

예시:

```python
import panther_event_type_helpers as event_type

def 룰(event):
    # 통합 데이터 모델 필드 ‘event_type’로 이벤트 필터링
    return event.udm("event_type") == event_type.FAILED_LOGIN
```

참고 자료:

* [데이터 모델 가이드](https://docs.panther.com/writing-detections/data-models)
* [데이터 모델](https://github.com/panther-labs/panther-analysis/tree/master/data_models)
* [IP별 무차별 대입 공격](https://github.com/panther-labs/panther-analysis/blob/cd220c87982011d4ad156c7daecd2857c358d154/indexes/standard.md)

### 여러 조건 사용하기

함수는 `및` 키워드는 논리 연산자이며 조건문을 결합하는 데 사용됩니다. 이벤트의 여러 필드를 일치시키려면 종종 `및` 키워드. 사용할 때 `및`, 모든 문장은 참이어야 합니다:\
`"string_a" == "this"`**`및`**`"string_b" == "that"`

예시:

AWS 콘솔에서 root 사용자 액세스 성공을 추적하려면 여러 필드를 살펴봐야 합니다:

```python
from panther_base_helpers import deep_get

def 룰(event):
    return (event.get("eventName") == "ConsoleLogin" and
            deep_get(event, "userIdentity", "type") == "Root" and
	    deep_get(event, "responseElements", "ConsoleLogin") == "Success")
```

함수는 `또는` 키워드는 논리 연산자이며 조건문을 결합하는 데 사용됩니다. 사용할 때 `또는`, 두 문장 중 어느 하나가 참일 수 있습니다:\
"` "string_a" == "this"`` `` `**`또는`**` `` ``"string_b" == "that" `

예시:

이 예시는 필드에 포트 80 **또는** 또는 포트 22가 포함되어 있는지 감지합니다:

```python
# 'port_number'가 80 또는 22이면 True를 반환
def 룰(event):
    return event.get("port_number") == 80 or event.get("port_number") == 22
```

### 리스트에서 값 검색하기

리스트(예: IP 주소나 사용자)를 기준으로 이벤트 값을 비교하는 것은 Python에서 빠릅니다. 일반적으로는 이벤트 값이 리스트에도 존재할 때 룰이 일치하지 않도록 로직을 설정하는 패턴이 자주 사용됩니다. 이는 환경에서 알려진 동작에 대한 오탐을 줄이는 데 도움이 될 수 있습니다.

이벤트 값이 어떤 컬렉션에 있는지 확인할 때는 Python set을 사용하는 것이 좋습니다. set은 Python에서 list와 tuple보다 더 효율적(즉, 메모리 효율적)입니다. list와 tuple은 set과 달리 포함 여부를 확인하기 위해 컬렉션의 각 항목을 하나씩 반복해야 합니다.

비교 대상인 set이 정적이라면, 함수 내부가 아니라 전역 수준에서 정의하는 것이 좋습니다. `룰()` 전역 변수는 Lambda 호출당 한 번만 초기화됩니다. 하나의 Lambda 호출이 여러 이벤트를 처리할 수 있으므로, 전역 변수는 일반적으로 매번 초기화하는 것보다 더 효율적입니다 `룰()` 가 호출됩니다.

예시:

```python
# Set - 성능 면에서 tuple과 list보다 권장됨
ALLOW_IP = {'192.0.0.1', '192.0.0.2', '192.0.0.3'}

def 룰(event):
    return event.get("ip_address") not in ALLOW_IP
```

아래 예시에서는 Panther 도우미 함수 `pattern_match_list`:

```python
from panther_base_helpers import pattern_match_list

USER_CREATE_PATTERNS = [
    "chage",   # 사용자 암호 만료
    "passwd",  # 사용자 암호 변경
    "user*",   # 사용자 생성, 수정, 삭제
]

def 룰(event):
    # 이벤트 필터링
    if event.get("event") != "session.command":
        False를 반환
    # 위 목록과 프로그램이 일치하는지 확인
    return pattern_match_list(event.get("program", ""), USER_CREATE_PATTERNS)
```

Reference: [Teleport 사용자 계정 생성](https://github.com/panther-labs/panther-analysis/blob/cd220c87982011d4ad156c7daecd2857c358d154/rules/gravitational_teleport_rules/teleport_create_user_accounts.py)

### 정규식으로 이벤트 일치시키기

정규 표현식을 사용하여 이벤트와 일치시키고 싶다면 - 하위 도메인, 파일 경로, 일반 문자열의 접두사/접미사와 일치시키기 위해 - regex를 사용할 수 있습니다. Python에서는 다음을 import하여 regex를 사용할 수 있습니다: `re` 라이브러리를 불러와 일치하는 값을 찾으면 됩니다.

아래 예시에서는 regex 패턴이 privilegeGranted 필드의 중첩 값에 대해 Administrator 또는 administrator와 일치합니다.

```python
import re
from panther_base_helpers import deep_get

# regex 패턴을 변수에 저장합니다
# 참고: 이는 이벤트마다 평가되는 룰 함수에 넣는 것보다 성능이 더 좋습니다
ADMIN_PATTERN = re.compile(r"[aA]dministrator")

def 룰(event):
    # deep_get 함수를 사용하여 "privilegeGranted" 필드 아래의 중첩 값을 가져올 수 있습니다
    value_to_search = deep_get(event, "debugContext", "debugData", "privilegeGranted")
    # 마지막으로 앞서 만든 regex 객체를 사용하여 값을 확인합니다
    # 일치하면 "True"가 반환됩니다 
    return (bool(ADMIN_PATTERN.search(value_to_search, default="")))
```

아래 예시에서는 Panther 도우미 함수 `pattern_match`:

```python
from panther_base_helpers import pattern_match

def 룰(event):
    return pattern_match(event.get("operation", ""), "REST.*.OBJECT")
```

참고 자료:

* [re.compile](https://docs.python.org/3/library/re.html#functions)
* [Pythex: 간단한 RegEx 편집기 및 테스트 도구](https://pythex.org/)
* [AWS S3 보안되지 않은 액세스](https://github.com/panther-labs/panther-analysis/blob/cd220c87982011d4ad156c7daecd2857c358d154/rules/aws_s3_rules/aws_s3_insecure_access.py)

## Python 룰 사양 참조

필수 필드는 **굵게 표시됩니다**.

<table data-header-hidden data-full-width="false"><thead><tr><th width="214.375">필드 이름</th><th width="455">설명</th><th width="302.5081967213115">예상 값</th></tr></thead><tbody><tr><td>필드 이름</td><td>설명</td><td>예상 값</td></tr><tr><td><strong><code>AnalysisType</code></strong></td><td>이 분석이 룰, scheduled_룰, policy, 또는 global인지 나타냅니다</td><td>룰: <code>룰</code><br>예약된 룰: <code>scheduled_룰</code></td></tr><tr><td><strong><code>활성화</code></strong></td><td>이 룰이 활성화되어 있는지 여부</td><td>불리언</td></tr><tr><td><strong><code>파일 이름</code></strong></td><td>파이썬 룰 본문에 대한 경로(파일 확장자 포함)</td><td>String</td></tr><tr><td><strong><code>룰ID</code></strong></td><td>룰의 고유 식별자</td><td>문자열<br>포함할 수 없음 <code>%</code></td></tr><tr><td><strong><code>로그 유형</code></strong></td><td>이 룰을 적용할 로그 목록</td><td>문자열 목록</td></tr><tr><td><strong><code>심각도</code></strong></td><td>이 룰의 심각도</td><td>다음 문자열 중 하나: <code>정보</code>, <code>낮음</code>, <code>보통</code>, <code>높음</code>또는 <code>Critical</code></td></tr><tr><td><strong><code>예약된 쿼리</code></strong> (Scheduled Rules 전용 필드)</td><td>이 룰을 적용할 Scheduled Query 이름 목록</td><td>문자열 목록</td></tr><tr><td><code>알러트 생성</code></td><td>이 룰이 생성해야 하는지 여부 <a href="/pages/28a2f0a91092222209c65334fa10beb60037d689#signals-vs.-rule-matches-vs.-alerts">룰 일치/알러트</a> 일치 시(기본값 true)</td><td>불리언</td></tr><tr><td><code>설명</code></td><td>룰에 대한 간단한 설명</td><td>String</td></tr><tr><td><code>중복 제거 기간(분)</code></td><td>알러트의 유사한 이벤트가 함께 그룹화되는 기간(분 단위)</td><td><code>15</code>,<code>30</code>,<code>60</code>,<code>180</code> (3시간),<code>720</code> (12시간), 또는 <code>1440</code> (24시간)</td></tr><tr><td><code>DisplayName</code></td><td>UI와 알러트에 표시할 친숙한 이름입니다. 이 <code>룰ID</code> 이 필드가 설정되지 않은 경우 표시됩니다.</td><td>String</td></tr><tr><td><code>OutputIds</code></td><td>정적 목적지 재정의. 이는 이 룰의 알러트가 어떻게 라우팅되는지 결정하는 데 사용되며, 심각도에 따른 기본 라우팅보다 우선합니다.</td><td>문자열 목록</td></tr><tr><td><code>참조</code></td><td>이 룰이 존재하는 이유이며, 보통 문서 링크입니다</td><td>String</td></tr><tr><td><code>리포트</code></td><td>이 룰이 해당 프레임워크에 대해 적용하는 값과 프레임워크 또는 리포트 이름의 매핑</td><td>문자열에서 문자열 목록으로의 맵</td></tr><tr><td><code>런북</code></td><td>애널리스트 또는 Panther AI가 관련 알러트를 분류하기 위해 수행할 수 있는 작업.</td><td>String</td></tr><tr><td><code>요약 속성</code></td><td>알러트가 요약해야 하는 필드 목록입니다.</td><td>문자열 목록</td></tr><tr><td><code>임계값</code></td><td>알러트가 전송되기 전에 이 룰을 트리거해야 하는 이벤트 수입니다.</td><td>정수</td></tr><tr><td><code>태그</code></td><td>이 룰을 분류하는 데 사용되는 태그</td><td>문자열 목록</td></tr><tr><td><code>테스트</code></td><td>이 룰의 단위 테스트입니다.</td><td>맵 목록</td></tr><tr><td><code>생성자</code></td><td>이 디택션의 작성자입니다. Panther 사용자 UUID, 이메일 주소 또는 임의의 텍스트 값으로 설정할 수 있습니다. 자세한 내용은 <a href="/pages/5f0ed921cfc97d649f3af6d2a4a6b7d06f7759cc#the-createdby-detection-field">함수는 <code>생성자</code> 디택션 필드</a>.</td><td>String</td></tr></tbody></table>

## Python 정책 사양 참조

필수 필드는 **굵게 표시됩니다**.

정책 사양 필드의 전체 목록:

<table data-header-hidden data-full-width="false"><thead><tr><th width="169.939208984375">필드 이름</th><th width="528.4545454545455">설명</th><th>예상 값</th></tr></thead><tbody><tr><td>필드 이름</td><td>설명</td><td>예상 값</td></tr><tr><td><strong><code>AnalysisType</code></strong></td><td>이 사양이 정책인지 룰인지 나타냅니다</td><td><code>정책</code></td></tr><tr><td><strong><code>활성화</code></strong></td><td>이 정책이 활성화되어 있는지 여부</td><td>불리언</td></tr><tr><td><strong><code>파일 이름</code></strong></td><td>Python 정책 본문의 경로(파일 확장자 포함)</td><td>String</td></tr><tr><td><strong><code>정책ID</code></strong></td><td>정책의 고유 식별자</td><td>문자열<br>포함할 수 없음 <code>%</code></td></tr><tr><td><strong><code>리소스 유형</code></strong></td><td>이 정책이 적용될 리소스 유형</td><td>문자열 목록</td></tr><tr><td><strong><code>심각도</code></strong></td><td>이 정책의 심각도</td><td>다음 문자열 중 하나: <code>정보</code>, <code>낮음</code>, <code>보통</code>, <code>높음</code>또는 <code>Critical</code></td></tr><tr><td><code>설명</code></td><td>정책에 대한 간단한 설명</td><td>String</td></tr><tr><td><code>DisplayName</code></td><td>UI와 알러트에 표시할 이름입니다. 해당 <code>정책ID</code> 이 필드가 설정되지 않은 경우 표시됩니다.</td><td>String</td></tr><tr><td><code>참조</code></td><td>이 정책이 존재하는 이유이며, 보통 문서 링크입니다</td><td>String</td></tr><tr><td><code>리포트</code></td><td>이 정책이 해당 프레임워크에 대해 적용하는 값과 프레임워크 또는 리포트 이름의 매핑</td><td>문자열에서 문자열 목록으로의 맵</td></tr><tr><td><code>런북</code></td><td>애널리스트 또는 Panther AI가 관련 알러트를 분류하기 위해 수행할 수 있는 작업.</td><td>String</td></tr><tr><td><code>억제</code></td><td>무시할 패턴, 예: <code>aws::s3::*</code></td><td>문자열 목록</td></tr><tr><td><code>태그</code></td><td>이 정책을 분류하는 데 사용되는 태그</td><td>문자열 목록</td></tr><tr><td><code>테스트</code></td><td>이 정책의 단위 테스트입니다.</td><td>맵 목록</td></tr><tr><td><code>생성자</code></td><td>이 디택션의 작성자입니다. Panther 사용자 UUID, 이메일 주소 또는 임의의 텍스트 값으로 설정할 수 있습니다. 자세한 내용은 <a href="/pages/5f0ed921cfc97d649f3af6d2a4a6b7d06f7759cc#the-createdby-detection-field">함수는 <code>생성자</code> 디택션 필드</a>.</td><td>String</td></tr></tbody></table>

## 디택션 문제 해결

Panther 지식 베이스를 방문하여 [디택션에 관한 문서를 확인하고](https://help.panther.com/Detections) 자주 묻는 질문에 답하고 일반적인 오류와 문제를 해결하는 데 도움이 되는


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.panther.com/ko/detections/rules/python.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
