> 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` 저장소](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 계정인 경우 알러트가 발생하지 않도록 하고 싶습니다
  * 그에 따라 이 로직을 반영하도록 테스트를 변경하고 싶습니다
* 심각도가 다음과 같기를 원합니다: `낮음` 로그인 대상 계정이 내부 non-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가 두 파일 중 어느 쪽이든 변경하면 업데이트를 가져올 때 머지 충돌이 발생할 가능성이 큽니다.

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

### 파생으로 이러한 수정 사항을 적용하는 방법

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

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

# 필터와 룰을 테스트하는 테스트
Tests:
  -
      이름: No MFA 로그인 - IAM 사용자
      기대 결과: true
      모의 객체:
        - objectName: check_account_age
          returnValue: "False"
      로그:
        {
          "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"
        }
  -
      이름: Dev 계정의 No MFA 로그인 - IAM 사용자
      ExpectedResult: false
      모의 객체:
        - objectName: check_account_age
          returnValue: "False"
      로그:
        {
          "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가 기본 디택션을 업데이트할 때마다, 즉 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.
