> 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/derived/using-derived-detections-to-avoid-merge-conflicts.md).

# 병합 충돌을 피하기 위해 파생 디택션 사용

## 배경

사용해야 하는 가장 설득력 있는 이유 중 하나는 [파생 디택션](/ko/detections/rules/derived.md), CLI 워크플로를 사용하여 Panther 디택션 콘텐츠를 관리하는 팀이라면, 자체 팀만 관리하고 업데이트하는 것이 아닌 디택션도 사용하고 커스터마이즈할 수 있으면서, 같은 디택션이 외부 팀에 의해 업데이트될 때 발생할 수 있는 병합 충돌 문제를 피할 수 있다는 점입니다.

이러한 상황은 Panther의 Threat Research 팀이 생성하고 배포한 디택션을 다음을 통해 사용할 때 발생할 수 있습니다: [`panther-analysis` repository](https://github.com/panther-labs/panther-analysis), 즉 [Panther가 관리하는 탐지](/ko/detections/panther-managed.md). 병합 충돌은 다음의 포크를 유지하려고 할 때 발생할 수 있습니다: `panther-analysis` 여기서 당신은 Panther가 관리하는 디택션을 커스터마이즈했지만, 포크를 업스트림 저장소와 동기화하여 Panther의 콘텐츠 변경 사항도 최신 상태로 유지하고 싶습니다.

이 경우 파생이 유용합니다. Panther가 수정하는 파일과 완전히 분리된 파일을 편집하여 Panther가 관리하는 디택션을 커스터마이즈할 수 있기 때문입니다. 즉, 나중에 병합 충돌을 일으키지 않고 Panther로부터 콘텐츠 업데이트를 받을 수 있습니다.

## 파생이 유용한 시나리오 살펴보기

아래 시나리오에서 사용자는 Panther가 관리하는 디택션을 수정하려고 합니다. 디택션 파생 없이, 그리고 디택션 파생을 사용했을 때 업데이트가 어떻게 이루어지는지 확인해 보세요.

### 시나리오

다음과 같이 사용하고 싶다고 가정해 보겠습니다: `AWS.Console.LoginWithoutMFA` Panther가 관리하는 디택션(다음을 참조하세요: [여기 Python 파일](https://github.com/panther-labs/panther-analysis/blob/main/rules/aws_cloudtrail_rules/aws_console_login_without_mfa.py) 및 [여기 YAML 파일](https://github.com/panther-labs/panther-analysis/blob/main/rules/aws_cloudtrail_rules/aws_console_login_without_mfa.yml)), 하지만 당신은 *또한* 다음과 같은 수정도 하고 싶습니다:

* 로그인 대상 계정이 dev 계정이면 알러트하고 싶지 않습니다
  * 이에 따라 이 로직을 반영하도록 테스트를 변경하고 싶습니다
* 심각도를 다음과 같이 하고 싶습니다: `낮음` 로그인 대상 계정이 내부 비-dev 계정이면 `높음` 그 외의 경우
* 런북을 변경하고 싶습니다

### 파생 없이 이러한 수정을 하는 방법

파생을 사용하지 않으면, CLI 워크플로에서 다음과 같이 변경합니다:

* 다음을 수정하세요: `aws_console_login_without_mfa.py` 파일을 다음과 같이:

  * 다음을 변경하세요: `룰()` 함수에 다음과 유사한 로직을 포함합니다:

  ```python
  def 룰(event):
  		# dev 계정이면 디택션을 조기 종료하는 사용자 지정 로직
  		dev_accounts = [
  				"123456789001",
  				"123456789002"
  		]
  		if event.get("recipientAccountId") in dev_accounts:
  				return False
  ....
  ```

  * 다음을 추가하세요 [`severity()`](/ko/detections/rules/python.md#severity) 다음과 유사한 함수:

  ```python
  def severity(event):
  		internal_non_dev_accounts = [
  				"123456789003",
  				"123456789004"
  		]
  		if event.get("recipientAccountId") in internal_non_dev_accounts:
  				return "LOW"
  		return "HIGH"
  ```
* 다음을 수정하세요: `aws_console_login_without_mfa.yml` 파일을 다음과 같이:
  * 다음을 교체하세요: `테스트` 섹션을 새 테스트 시리즈로 교체하세요. 여기에는 dev 계정 ID를 포함하는 로그용 테스트 하나와, 그렇지 않은 로그용 테스트 하나가 포함됩니다
  * 다음 값으로 업데이트하세요: `런북` 사용자 지정 런북 링크

이러한 변경을 마친 후에는 룰이 조직의 요구에 맞게 커스터마이즈됩니다. 그러나 이제부터 Panther가 어느 파일이든 변경하면, 업데이트를 가져올 때 병합 충돌이 발생할 가능성이 높습니다.

아래에서 동일한 커스터마이즈를 적용하면서 병합 충돌을 피하기 위해 파생을 사용하는 방법을 확인하세요.

### 파생을 사용하여 이러한 수정을 하는 방법

파생 워크플로에서는 기본적으로 Base 디택션의 모든 측면을 상속하는 파생 디택션을 먼저 생성합니다:

```yaml
# aws_console_login_without_mfa_account_filter.yml
AnalysisType: 룰
BaseDetection: AWS.Console.LoginWithoutMFA
RuleID: AWS.Console.LoginWithoutMFA.Account.Filter
```

그다음 다음부터 오버라이드를 추가하기 시작합니다: `런북`:

```yaml
# aws_console_login_without_mfa_account_filter.yml
...
# 사용자 지정 런북
런북: <https://runbooks.security.corp/secops/AWS/ConsoleLoginWithoutMFA>
```

추가 [`InlineFilters`](/ko/detections/rules/inline-filters.md) AWS 계정이 dev 계정이면 룰이 실행되지 않아야 함을 나타내기 위해:

```yaml
# aws_console_login_without_mfa_account_filter.yml
...
# dev 계정 이벤트 필터링 
InlineFilters:
    - All:
        - KeyPath: recipientAccountId
          Condition: IsNotIn
          값:
            - '123456789002'
            - '123456789001'
```

추가 [`DynamicSeverities`](/ko/detections/rules/writing-simple-detections.md#dynamicseverities) 계정이 staging 계정이면 심각도를 조정하기 위해:

```yaml
# aws_console_login_without_mfa_account_filter.yml
...
# staging 계정이면 심각도를 LOW로 설정
DynamicSeverities:
  - ChangeTo: LOW
    Conditions:
      - KeyPath: recipientAccountId
        조건: IsIn
        값:
          - '123456789003'
          - '123456789004'
```

마지막으로, 직접 만든 `테스트` 세트를 추가하여 추가한 디택션과 필터를 테스트할 수 있도록 합니다. 아래는 앞서 언급한 모든 오버라이드를 추가한 후의 완전한 파생 디택션입니다:

```yaml
# aws_console_login_without_mfa_account_filter.yml
AnalysisType: 룰
BaseDetection: AWS.Console.LoginWithoutMFA
RuleID: AWS.Console.LoginWithoutMFA.Account.Filter

# 사용자 지정 런북
런북: <https://runbooks.security.corp/secops/AWS/ConsoleLoginWithoutMFA>

# dev 계정 이벤트 필터링 
InlineFilters:
  - All:
    - KeyPath: recipientAccountId
      Condition: IsNotIn
      값:
        - '123456789001'
        - '123456789002'

# staging 계정이면 심각도를 LOW로 설정
DynamicSeverities:
  - ChangeTo: LOW
    Conditions:
      - KeyPath: recipientAccountId
        조건: IsIn
        값:
          - '123456789003'
          - '123456789004'

# 필터와 룰을 테스트하는 테스트
테스트:
  -
      Name: MFA 없는 로그인 - IAM 사용자
      예상 결과: true
      Mocks:
        - objectName: check_account_age
          returnValue: "False"
      Log:
        {
          "eventVersion": "1.05",
          "userIdentity": {
            "type": "IAMUser",
            "principalId": "1111",
            "arn": "arn:aws:iam::123456789012:user/tester",
            "accountId": "123456789012",
            "userName": "tester"
          },
          "eventTime": "2019-01-01T00:00:00Z",
          "eventSource": "signin.amazonaws.com",
          "eventName": "ConsoleLogin",
          "awsRegion": "us-east-1",
          "sourceIPAddress": "111.111.111.111",
          "userAgent": "Mozilla",
          "requestParameters": null,
          "responseElements": {
            "ConsoleLogin": "Success"
          },
          "additionalEventData": {
            "LoginTo": "<https://console.aws.amazon.com/console/>",
            "MobileVersion": "No",
            "MFAUsed": "No"
          },
          "eventID": "1",
          "eventType": "AwsConsoleSignIn",
          "recipientAccountId": "123456789012"
        }
  -
      Name: Dev 계정에서 MFA 없는 로그인 - IAM 사용자
      ExpectedResult: false
      Mocks:
        - objectName: check_account_age
          returnValue: "False"
      Log:
        {
          "eventVersion": "1.05",
          "userIdentity": {
            "type": "IAMUser",
            "principalId": "1111",
            "arn": "arn:aws:iam::123456789012:user/tester",
            "accountId": "123456789012",
            "userName": "tester"
          },
          "eventTime": "2019-01-01T00:00:00Z",
          "eventSource": "signin.amazonaws.com",
          "eventName": "ConsoleLogin",
          "awsRegion": "us-east-1",
          "sourceIPAddress": "111.111.111.111",
          "userAgent": "Mozilla",
          "requestParameters": null,
          "responseElements": {
            "ConsoleLogin": "Success"
          },
          "additionalEventData": {
            "LoginTo": "<https://console.aws.amazon.com/console/>",
            "MobileVersion": "No",
            "MFAUsed": "No"
          },
          "eventID": "1",
          "eventType": "AwsConsoleSignIn",
          "recipientAccountId": "123456789002"
        }
```

파생 디택션에 모든 오버라이드를 추가했으므로, 이를 Panther에 업로드하여 다른 디택션과 마찬가지로 사용할 수 있습니다.

Panther가 Base 디택션을 업데이트할 때마다—즉 Panther가 다음 중 어느 하나를 수정하면 `aws_console_login_without_mfa.py` 또는 `aws_console_login_without_mfa.yml` 파일—파생 디택션에서 오버라이드를 추가한 필드에 대한 변경이 아닌 경우, 파생 디택션을 수동으로 업데이트하지 않아도 변경 사항을 상속하게 됩니다. 가장 중요한 점은 병합 충돌을 겪지 않는다는 것입니다.


---

# 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/derived/using-derived-detections-to-avoid-merge-conflicts.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.
