> 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 Detections로 작성할 수 있습니다](/ko/detections/rules/writing-simple-detections.md). 디택션을 로컬에서 Simple Detections로 작성할지 Python 디택션으로 작성할지 확실하지 않다면 다음을 참조하세요 [Python 사용 vs. Simple 디택션 YAML](https://docs.panther.com/ko/detections/rules/pages/03a99462193d3cb6f09cb46a6d9fa32a7a6035d0#using-python-vs.-simple-detections-yaml) 섹션.

{% hint style="info" %}
새 Python 디택션을 작성하기 전에 다음이 있는지 확인하세요 [Panther-managed 디택션](/ko/detections/panther-managed.md) 귀하의 요구 사항을 충족하는지(또는 *거의* 충족하는지—Panther-managed 룰은 다음으로 조정할 수 있습니다 [인라인 필터](/ko/detections/rules/inline-filters.md)). Panther-managed 디택션을 활용하면 직접 작성하는 수고를 덜 수 있을 뿐만 아니라, 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 콘솔의 왼쪽 탐색 표시줄에서 다음을 클릭합니다: **디택션**.
2. 다음을 클릭합니다: **새로 만들기**.
3. 다음에서 **Python 룰** 타일에서 다음을 클릭합니다: **시작**.
4. 생성 페이지에서 룰을 구성하세요:
   * **이름**: 룰에 대한 설명적인 이름을 입력하세요.
   * **ID** (선택 사항)**:** 펜 아이콘을 클릭하고 룰의 고유 ID를 입력하세요.
   * 오른쪽 상단의 **활성화** 토글은 다음으로 설정됩니다 `켬` 기본값입니다. 룰을 비활성화하려면 토글을 다음으로 전환하세요 `끔`.
   * 다음의 **다음 소스에 대해** 섹션:
     * **로그 유형**: 이 룰을 적용할 로그 유형을 선택하세요.
   * 다음의 **탐지** 섹션:
     * 다음의 **룰 함수** 텍스트 편집기에서 Python `룰` 함수를 작성하여 디택션을 정의하세요.
       * 디택션 템플릿과 예시는 다음을 참조하세요 [panther\_analysis GitHub 저장소](https://github.com/panther-labs/panther-analysis/tree/master/templates).
   * 다음의 **알러트 생성** 섹션에서 다음을 설정하세요 **알러트 생성** `ON/OFF` 토글입니다. 이는 다음을 나타냅니다 [알러트](/ko/alerts.md) 일치 항목이 있을 때 생성할지, 아니면 단지 [신호](/ko/detections/signals.md). 이 토글을 다음으로 설정하면 `켬`:
     * **심각도**: 다음을 선택하세요 [심각도 수준](#alert-severity) 이 디택션으로 트리거된 알러트에 대해
     * 다음의 **선택 필드** 섹션, 선택적으로 다음 필드의 값을 제공합니다:
       * **설명**: 룰에 대한 추가 컨텍스트를 입력하세요.
       * **런북**: 이 룰과 관련된 절차 및 작업을 입력하세요.
         * 자세한 내용은 [알러트 런북](/ko/alerts/alert-runbooks.md).
         * 설명적인 런북을 제공하는 것이 권장됩니다, 왜냐하면 [Panther AI 알러트 분류](/ko/alerts.md#panther-ai-alert-triage) 그것을 고려할 것입니다.
       * **참조**: 이 룰과 관련된 추가 정보로 연결되는 외부 링크를 입력하세요.
       * **대상 재정의:** 심각도와 관계없이 이 디택션에 대한 알러트를 수신할 대상을 선택하세요. 대상은 룰 함수에서 동적으로 설정할 수도 있습니다. 다음을 참조하세요 [라우팅 순서 우선순위](/ko/alerts/destinations.md#routing-order-precedence) 라우팅 우선순위에 대해 자세히 알아보세요.
       * **중복 제거 기간** 그리고 **이벤트 임계값**: 룰 일치에 대한 중복 제거 기간과 임계값을 입력하세요. 중복 제거가 작동하는 방식을 알아보려면 다음을 참조하세요 [중복 제거](#deduplication).
       * **요약 속성**: 이 디택션에 의해 트리거되는 알러트에서 강조 표시할 속성을 입력하세요.
         * 중첩 필드를 요약 속성으로 사용하려면, Summary Attribute 필드에서 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`.)
       * 다음의 **프레임워크 매핑** 섹션:
         1. 다음을 클릭합니다: **새로 추가** 보고서를 입력하려면.
         2. 다음 필드에 값을 입력합니다:
            * **보고서 키**: 보고서와 관련된 키를 입력하세요.
            * **보고서 값**: 해당 보고서의 값을 입력하세요.
   * 다음의 **테스트** 섹션:
     * 다음의 **단위 테스트** 섹션에서 다음을 클릭합니다 **새로 추가** 에서 [테스트를 생성하세요](/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 또는 콘솔의 대량 업로더를 사용하는 경우 모두 포함).

로그/리소스 유형별로 룰을 폴더로 그룹화할 것을 권장합니다. 예: `suricata_룰` 또는 `aws_s3_정책`. 다음을 참조로 사용할 수 있습니다. [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시간
   DisplayName: 명세 형식을 확인하는 예시 룰
   Enabled: true
   파일 이름: my_new_룰.py
   RuleID: Type.Behavior.MoreContext
   Severity: High
   LogTypes:
     - LogType.GoesHere
   Reports:
     ReportName(CIS, MITRE ATT&CK 등):
       - 이 룰과 관련된 특정 보고서 섹션
   Tags:
     - Tags
     - Go
     - Here
   Description: >
     이 룰은 Panther CLI의 CLI 워크플로를 검증하기 위해 존재합니다.
   Runbook: >
     먼저 이 명세 형식을 작성한 사람이 누구인지 알아낸 다음, 피드백과 함께 알려주세요.
   Reference: https://www.a-clickable-link-to-more-info.com
   ```

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

</details>

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

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

<details>

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

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

         ```python
         def 룰(event):  
             return True
         ```
       * 디택션 템플릿과 예시는 다음을 참조하세요 [panther\_analysis GitHub 저장소](https://github.com/panther-labs/panther-analysis/tree/master/templates)
   * 다음의 **알러트 생성** 섹션에서 다음을 설정하세요 **알러트 생성** `ON/OFF` 토글입니다. 이는 다음을 나타냅니다 [알러트](/ko/alerts.md) 일치 항목이 있을 때 생성할지, 아니면 단지 [신호](/ko/detections/signals.md). 이 토글을 다음으로 설정하면 `켬`:
     * **심각도**: 다음을 선택하세요 [심각도 수준](#alert-severity) 이 디택션으로 트리거된 알러트에 대해
     * 다음의 **선택 필드** 섹션, 선택적으로 다음 필드의 값을 제공합니다:
       * **설명**: 룰에 대한 추가 컨텍스트를 입력하세요.
       * **런북**: 이 룰과 관련된 절차 및 작업을 입력하세요.
         * 자세한 내용은 [알러트 런북](/ko/alerts/alert-runbooks.md).
         * 설명적인 런북을 제공하는 것이 권장됩니다, 왜냐하면 [Panther AI 알러트 분류](/ko/alerts.md#panther-ai-alert-triage) 그것을 고려할 것입니다.
       * **참조**: 이 룰과 관련된 추가 정보로 연결되는 외부 링크를 입력하세요.
       * **대상 재정의:** 심각도와 관계없이 이 디택션에 대한 알러트를 수신할 대상을 선택하세요. 대상은 룰 함수에서 동적으로 설정할 수도 있습니다. 다음을 참조하세요 [라우팅 순서 우선순위](/ko/alerts/destinations.md#routing-order-precedence) 라우팅 우선순위에 대해 자세히 알아보세요.
       * **중복 제거 기간** 그리고 **이벤트 임계값**: 룰 일치에 대한 중복 제거 기간과 임계값을 입력하세요. 중복 제거가 작동하는 방식을 알아보려면 다음을 참조하세요 [중복 제거](#deduplication).
       * **요약 속성**: 이 디택션에 의해 트리거되는 알러트에서 강조 표시할 속성을 입력하세요.
         * 중첩 필드를 요약 속성으로 사용하려면, Summary Attribute 필드에서 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`.)
       * 다음의 **프레임워크 매핑** 섹션:
         1. 다음을 클릭합니다: **새로 추가** 보고서를 입력하려면.
         2. 다음 필드에 값을 입력합니다:
            * **보고서 키**: 보고서와 관련된 키를 입력하세요.
            * **보고서 값**: 해당 보고서의 값을 입력하세요.
   * 다음의 **테스트** 섹션:
     * 다음의 **단위 테스트** 섹션에서 다음을 클릭합니다 **새로 추가** 에서 [테스트를 생성하세요](/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 또는 콘솔의 대량 업로더를 사용하는 경우 모두 포함).

로그/리소스 유형별로 룰을 폴더로 그룹화할 것을 권장합니다. 예: `suricata_룰` 또는 `aws_s3_정책`. 다음을 참조로 사용할 수 있습니다. [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: 내 새 예약된 쿼리 이름
   Enabled: true
   Tags:
     - 선택 사항
     - Tags
   Description: >
     선택적 설명
   Query: 'SELECT * FROM panther_logs.aws_cloudtrail LIMIT 10'
   스케줄:
     # 참고: 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 룰(_):
       # 참고: 추가 로직을 여기에 넣을 수 있습니다
       return True
   ```
3. 메타데이터 파일을 만들고 다음 이름으로 저장하세요 `my_new_schedule_룰.yml`:

   ```yaml
   AnalysisType: scheduled_룰
   파일 이름: my_new_룰.py 
   룰ID: My.New.룰
   표시 이름: 더 친숙한 이름
   Enabled: true
   스케줄된 쿼리:
     - 새 스케줄된 쿼리 이름
   Tags:
     - 태그
   심각도: 중간
   Description: >
     선택적 설명
   Runbook: >
     선택 사항인 Runbook 
   참조: 선택 사항인 reference.link 
   Tests:
     -
       이름: 이름 
       기대 결과: true
       로그:
         {
           "JSON": "문자열"
         }
   ```

이 스케줄된 룰이 업로드되면, 각 파일은 스케줄된 쿼리를 룰과 연결하고, 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 디택션을 만들면 Python 텍스트 편집기만 제공되며(YAML 편집기는 제공되지 않습니다). 아래 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): # or 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 알러트_context(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_룰, 또는 정책
Enabled: 
파일 이름: 
CreatedBy:
룰ID: # 또는 정책ID:
LogTypes: 
Reports: 
Tags: 
Tests: 
ScheduledQueries: # 스케줄된 룰에만 적용됩니다
Suppressions: # 정책에만 적용됩니다
Create알러트: # 정책에는 적용되지 않습니다
</code></pre></li><li><p>알러트 키(정적)</p><pre class="language-yaml"><code class="lang-yaml">Severity:
Description:
DedupPeriodMinutes:
Threshold: 
DisplayName:
OutputIds:
참조:
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"): 
        return True 
    return 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), 다음 *첫 번째* 디택션과 일치하는 event가 이러한 알러트 함수의 매개변수로 사용됩니다.

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

<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>심각도</code></a></td><td>알러트의 긴급도 수준</td><td><p>YAML에서: <code>심각도</code> 키</p><hr><p>콘솔에서: <strong>심각도</strong> 필드</p></td><td><code>INFO</code>, <code>낮음</code>, <code>MEDIUM</code>, <code>HIGH</code>,<code>치명적</code>, 또는 <code>기본값</code></td></tr><tr><td><a href="#title"><code>제목</code></a></td><td>생성된 알러트 제목</td><td><p>YAML에서: <code>표시 이름</code> > <code>룰ID</code> 또는 <code>정책ID</code></p><hr><p>콘솔에서: <strong>이름</strong> 필드 > <strong>ID</strong> 필드</p></td><td><code>문자열</code></td></tr><tr><td><a href="#dedup"><code>dedup</code></a></td><td>관련된 이벤트를 그룹화하는 문자열이며, 최대 1000자로 제한됩니다</td><td><p>Python/YAML에서: <code>title()</code> > <code>표시 이름</code> > <code>룰ID</code> 또는 <code>정책ID</code></p><hr><p>콘솔에서: <code>title()</code> > <strong>이름</strong> 필드 > <strong>ID</strong> 필드</p></td><td><code>문자열</code></td></tr><tr><td><a href="#unique"><code>unique</code></a></td><td>고유 임계값 디택션을 위해 추적할 값</td><td>해당 없음 - 표준 이벤트 개수 임계값을 사용합니다</td><td><code>문자열</code></td></tr><tr><td><a href="#alert_context"><code>알러트_context</code></a></td><td>알러트 대상에 전달할 추가 컨텍스트</td><td></td><td><code>Dict[문자열: 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>문자열</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>문자열</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>문자열</code></td></tr><tr><td><a href="#destinations"><code>대상</code></a></td><td>알러트를 보낼 대상의 ID(들)</td><td><p>YAML에서: <code>출력 ID</code> 키</p><hr><p>콘솔에서: <strong>대상 재정의</strong> 필드</p></td><td><code>List[대상 이름/ID]</code></td></tr></tbody></table>

#### `심각도`

일부 상황에서는 알러트의 심각도 수준을 상향 또는 하향 조정해야 할 수 있습니다. 알러트의 심각도 수준은 다음에 매핑될 수 있습니다 `INFO`, `낮음`, `MEDIUM`, `HIGH`, `치명적`, 또는 `기본값`. 반환 `기본값` 정적으로 정의된 룰 심각도로 폴백합니다.

심각도 문자열은 대소문자를 구분하지 않으며, 예를 들어 다음을 반환할 수 있습니다. `치명적` 또는 `기본값`는 스타일 선호도에 따라 달라집니다.

아래 예시에서는 API 토큰이 생성되어 있으면 `HIGH` 심각도 알러트가 생성되고, 그렇지 않으면 `INFO` 레벨 알러트가 생성됩니다:

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

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

사용 예시 `기본값`:

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

#### `제목`

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

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

알러트 제목이 어떻게 설정되는지 자세히 알아보려면 [룰 및 예약된 룰](/ko/detections/rules.md#title-of-associated-alerts).

예:

```python
def title(event):
    # 제목에서 통합 데이터 모델 필드 사용
    log_type = event.get("p_log_type")
    title_str = (
        f"{log_type}: User [{event.udm('actor_user')}] has exceeded the failed logins threshold"
    )
    if log_type == "AWS.CloudTrail":
        title_str += f" in [{lookup_aws_account_name(event.get('recipientAccountId'))}]"
    return title_str
```

참조: [템플릿 룰](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")
```

참조: [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을 준수해야 합니다. JSON을 준수하지 않는 값의 예로는 Python의 `nan`, `inf`, 그리고 `-inf`.

예:

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

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

def 알러트_context(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()` Python 딕셔너리 안에서 매우 깊게 중첩된 키와 연결된 값을 반환하는 데 사용되며, 여기에는 임의 개수의 딕셔너리나 리스트가 포함될 수 있습니다. 여러 이벤트 필드와 일치하면 일치 항목의 배열이 반환되고, 하나만 일치하면 해당 일치 항목의 값이 반환됩니다.

{% 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()` 함수를 사용하면 다음에서 데이터를 동적으로 가져올 수 있습니다: [사용자 정의 Lookup Table](https://docs.panther.com/enrichment) 그리고 [Panther에서 관리하는 Enrichment 제공자](/ko/enrichment.md) 를 디택션에서 사용할 수 있습니다.  `lookup()` 함수는 들어오는 로그에 Lookup Table의 기본 키 열 값과 정확히 일치하는 항목이 없는 경우 유용할 수 있습니다. Python을 사용하여 이벤트 값을 수정한 다음 다음에 전달할 수 있습니다: `lookup()` 에 보강 데이터를 가져오도록.

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

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

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

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

이러한 방식으로 "자동" Enrichment를 사용하는 경우, 중첩된 Enrichment 데이터는 다음을 사용하여 접근하세요: [`deep_walk()`](#deep_walk) 대신.
{% endhint %}

사용 예시 `lookup()`:

```python
# user_roles라는 Lookup Table이 다음 항목을 가진다고 가정해 봅시다:
# 행 1: {"id": "your@email.com", "role": "admin"}
# 행 2: {"id": "vistor@email.com", "role": "guest"}

# 이 룰에서는 사용자가 관리자 역할이 아닐 경우 True를 반환하고자 합니다
# Lookup Table에서 역할을 가져오고 싶지만, 이벤트에는 
# Lookup Table의 기본 키(이메일 주소)가 포함되어 있지 않습니다
def 룰(event):
    lookup_table_name = "user_roles"
    # 이벤트에는 사용자 이름에 대한 접근 권한이 *있으므로*, 이를 통해
    # 이메일 주소를 생성할 수 있습니다
    user_name = event.get("username", "").lower()
    lookup_key = f"{user_name}@email.com" # lookup 키, 즉 "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:
        return True
        
    return False
```

#### 다음을 사용하는 디택션의 단위 테스트 `lookup()`

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

`_mocked_lookup_data_` 는 다음 예시와 같이 구성해야 합니다:

{% code title="event.lookup() 모의하기" %}

```json5
{
  "_mocked_lookup_data_": {
     "user_roles": { # 이 키는 Lookup Table의 이름입니다
         # 이 객체의 키는 Lookup Table 키여야 합니다
         # 이 객체의 값은 Lookup Table 데이터 객체여야 합니다
         "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 %}

{% 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 Enhancement Proposals [는 자료를 게시합니다](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")` 는 동일한 결과를 반환합니다.

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

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

중첩은 여러 계층으로 깊어질 수 있으므로, 스키마 구조를 이해하고 특정 디택션에 대해 주어진 필드에 접근하는 방법을 아는 것이 중요합니다.

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

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

아래 예시는 다음을 활용하므로 모범 사례입니다: `get()` 함수를 활용하는 것입니다. `get()` 필드를 찾으며, 필드가 없으면 다음을 반환합니다: `없음` 오류 대신, 이로 인해 디택션이 다음을 반환하게 됩니다: `거짓`.

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

아래 예시에서는 필드가 있으면 해당 필드의 값이 반환됩니다. 그렇지 않으면, `거짓` 이 반환됩니다:

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

{% hint style="warning" %}
**잘못된 사례 예시**\
아래 룰 정의는 코드가 필드 이름을 명시하고 있으므로 모범 사례가 아닙니다. 필드가 없으면 Python이 다음 오류를 발생시킵니다: `KeyError`:

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

{% endhint %}

### 전역 헬퍼 함수 사용하기

많은 디택션이 작성되면 패턴과 반복 코드가 나타나기 시작합니다. 이는 다음에 매우 적합한 사용 사례입니다: [전역 헬퍼 함수](/ko/detections/rules/python/globals.md), 모든 디택션에서 이 로직을 중앙집중적으로 제공하는 위치를 제공합니다.

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

이벤트 안에 깊게 중첩된 필드에 접근하려면 다음을 사용하세요: [`deep_get()`](#deep_get) 그리고 [`deep_walk()`](#deep_walk) 이벤트 객체에서 사용할 수 있는 함수들입니다. 이러한 함수들은 또한 [전역 헬퍼 함수](/ko/detections/rules/python/globals.md)하지만 편의를 위해서는 대신 이벤트 객체 버전을 사용하는 것이 권장됩니다.

예:

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

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

값을 확인하는 방법을 알아보세요 `유형` 두 가지 형식을 모두 사용하여 안전하게 `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() 전역 헬퍼 함수" %}
다음을 사용하여 이벤트 값을 확인하기 [`deep_get()` 전역 헬퍼 함수](/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:
        return False

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

참조:

* [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)

### **Universal Data Model 사용하기**

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

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

예:

```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)

### 여러 조건 사용

해당 `그리고` keyword는 논리 연산자이며 조건문을 결합하는 데 사용됩니다. 이벤트에서 여러 필드를 일치시키려면 종종 다음을 사용해야 합니다 `그리고` keyword. 사용할 때 `그리고`, 모든 문은 참이어야 합니다:\
`"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")
```

해당 `또는` keyword는 논리 연산자이며 조건문을 결합하는 데 사용됩니다. 사용할 때 `또는`, 두 문장 중 어느 하나가 참일 수 있습니다:\n"` 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에서 목록과 튜플보다 더 성능이 좋습니다(즉, 메모리 효율이 높습니다). 목록과 튜플은 set과 달리 포함 여부를 확인하려면 컬렉션의 각 항목을 하나씩 반복해야 합니다.

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

예:

```python
# Set - 성능 면에서 튜플과 목록보다 권장됨
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":
        return False
    # 프로그램이 위의 목록과 일치하는지 확인합니다
    return pattern_match_list(event.get("program", ""), USER_CREATE_PATTERNS)
```

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

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

정규 표현식을 사용하여 이벤트와 일치시키려면 - 하위 도메인, 파일 경로 또는 일반 문자열의 접두사/접미사를 일치시키려면 - regex를 사용할 수 있습니다. Python에서는 다음을 가져와서 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")
    # 마지막으로 앞서 만든 정규식 객체를 사용해 우리의 값과 비교합니다
    # 일치가 있으면, "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: 간단한 정규식 편집기 및 테스트 도구](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>분석 유형</code></strong></td><td>이 분석이 룰, 예약 룰, 정책 또는 전역인지 나타냅니다</td><td>룰: <code>룰</code><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>문자열</td></tr><tr><td><strong><code>룰ID</code></strong></td><td>이 룰의 고유 식별자</td><td>문자열<br>포함할 수 없음 <code>%</code></td></tr><tr><td><strong><code>LogTypes</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>치명적</code></td></tr><tr><td><strong><code>예약 쿼리</code></strong> (예약 룰에만 해당하는 필드)</td><td>이 룰을 적용할 예약 쿼리 이름 목록</td><td>문자열 목록</td></tr><tr><td><code>Create알러트</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>문자열</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>표시 이름</code></td><td>UI와 알러트에 표시할 친근한 이름입니다. 이 <code>룰ID</code> 이 필드가 설정되지 않으면 표시됩니다.</td><td>문자열</td></tr><tr><td><code>출력 ID</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 AI가 관련 알러트의 우선순위를 분류하기 위해 수행할 수 있는 작업.</td><td>문자열</td></tr><tr><td><code>SummaryAttributes</code></td><td>알러트가 요약해야 하는 필드 목록.</td><td>문자열 목록</td></tr><tr><td><code>임계값</code></td><td>알러트가 전송되기 전에 이 룰을 트리거해야 하는 이벤트 수.</td><td>정수</td></tr><tr><td><code>Tags</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>문자열</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>분석 유형</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>파이썬 정책 본문의 경로(파일 확장자 포함)</td><td>문자열</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>치명적</code></td></tr><tr><td><code>설명</code></td><td>정책에 대한 간단한 설명</td><td>문자열</td></tr><tr><td><code>표시 이름</code></td><td>UI와 알러트에 표시할 이름. 그 <code>정책ID</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 AI가 관련 알러트의 우선순위를 분류하기 위해 수행할 수 있는 작업.</td><td>문자열</td></tr><tr><td><code>억제</code></td><td>무시할 패턴, 예: <code>aws::s3::*</code></td><td>문자열 목록</td></tr><tr><td><code>Tags</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>문자열</td></tr></tbody></table>

## 디택션 문제 해결

Panther Knowledge Base를 방문하여 [디택션 관련 문서를 확인하세요](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:

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

The question should be specific, self-contained, and written in natural language.
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.
