Sec 섹션 분석기 개발

분석기는 CI 파이프라인 컨텍스트 내에서 실행되는 Docker 이미지로 제공됩니다. 본 안내서에서는 분석기 간의 개발 및 테스트 관행에 대해 설명합니다.

공유 모듈

공통 동작 및 인터페이스를 위해 분석기 전체에서 공유되는 여러 개의 Go 모듈이 있습니다:

  • command Go 패키지는 CLI 인터페이스를 구현합니다.
  • common 프로젝트는 로깅, 인증서 처리, 디렉터리 검색 기능을 위한 여러 공유 모듈을 제공합니다.
  • report Go 패키지의 ReportFinding 구조체는 JSON 보고서를 마샬링합니다.
  • template 프로젝트는 새로운 분석기를 구성합니다.

분석기 사용 방법

분석기는 Docker 이미지로 제공됩니다. 예를 들어, Semgrep Docker 이미지를 실행하여 작업 디렉터리를 스캔하려면:

  1. 스캔하려는 소스 코드가 있는 디렉터리로 cd합니다.
  2. docker login registry.gitlab.com을 실행하고 사용자 이름 및 적어도 read_registry 범위를 가진 개인 또는 프로젝트 엑세스 토큰을 제공합니다.
  3. Docker 이미지를 실행합니다:

    docker run \
        --interactive --tty --rm \
        --volume "$PWD":/tmp/app \
        --env CI_PROJECT_DIR=/tmp/app \
        -w /tmp/app \
        registry.gitlab.com/gitlab-org/security-products/analyzers/semgrep:latest /analyzer run
    
  4. Docker 컨테이너는 분석기 범주에 해당하는 보고서 파일을 생성하여 프로젝트 디렉터리에 마운트합니다. 예를 들어, SASTgl-sast-report.json이라는 파일을 생성합니다.

분석기 개발

분석기를 업데이트하려면:

  1. Go 소스 코드를 수정합니다.
  2. 새 Docker 이미지를 빌드합니다.
  3. 분석기를 해당 테스트 프로젝트에 실행시킵니다.
  4. 생성된 보고서를 예상 값과 비교합니다.

analyzer라는 Docker 이미지를 생성하는 방법은 다음과 같습니다:

docker build -t analyzer .

예를 들어, Secret Detection을 테스트하려면 다음을 실행합니다:

wget https://gitlab.com/gitlab-org/security-products/ci-templates/-/raw/master/scripts/compare_reports.sh
sh ./compare_reports.sh sd test/fixtures/gl-secret-detection-report.json test/expect/gl-secret-detection-report.json \
| patch -Np1 test/expect/gl-secret-detection-report.json && Git commit -m 'Update expectation' test/expect/gl-secret-detection-report.json
rm compare_reports.sh

또한 자체 환경에서 이진 파일을 컴파일하고 로컬에서 실행할 수 있지만, 분석기의 실행에 필요한 런타임 종속성이 없어서 analyzerun이 작동하지는 않을 것입니다.

다음은 SpotBugs를 기반으로 한 예시입니다:

go build -o analyzer
./analyzer search test/fixtures
./analyzer convert test/fixtures/app/spotbugsXml.Xml > ./gl-sast-report.json

실행 기준

SAST 활성화를 위해서는 GitLab CI/CD 구성에 미리 정의된 템플릿를 포함해야 합니다.

다음 독립적인 기준들은 프로젝트에서 실행될 분석기를 결정합니다:

  1. SAST 템플릿은 특정 파일의 존재 여부에 따라 실행할 분석기를 결정하기 위해 rules:exists를 사용합니다. 예를 들어, Brakeman 분석기는 .rb 파일과 Gemfile이 있는 경우 실행됩니다.
  2. 각 분석기는 실제 분석을 실행하기 전에 사용자 정의 match interface를 실행합니다. 예를 들어, Flawfinder는 C/C++ 파일을 확인합니다.
  3. 일부 일반 파일 확장자에서 실행되는 분석기를 위해 CI/CD 변수 기반의 확인이 있습니다. 예를 들어, Kubernetes 매니페스트는 YAML로 작성되기 때문에 SCAN_KUBERNETES_MANIFESTS가 true로 설정될 때만 Kubesec가 실행됩니다.

단계 1은 프로젝트에 적합하지 않은 분석기를 실행하는 컴퓨트 할당량의 낭비를 방지합니다. 그러나 기술적 제한 사항으로 인해 대형 프로젝트에서 사용할 수 없습니다. 따라서 단계 2는 일치하지 않는 분석기가 조기에 종료될 수 있도록 최종 확인 작업을 수행합니다.

분석기 테스트 방법

의존성 스캐닝 분석기가 하류 파이프라인 기능을 사용하여 테스트 프로젝트에 대해 분석기를 테스트하는 영상 안내:

How Sec leverages the downstream pipeline feature of GitLab to test analyzers end to end

로컬 변경 사항 테스트

분석기에서 공유 모듈(예: command 또는 report)의 로컬 변경 사항을 테스트하려면 go mod replace 지시문을 사용하여 원격으로 태그된 command 버전 대신 로컬 변경 사항이 있는 command를 로드할 수 있습니다. 예를 들면:

go mod edit -replace gitlab.com/gitlab-org/security-products/analyzers/command/v3=/local/path/to/command

또는 go.mod 파일을 수동으로 업데이트하여 동일한 결과를 얻을 수 있습니다:

module gitlab.com/gitlab-org/security-products/analyzers/awesome-analyzer/v2

replace gitlab.com/gitlab-org/security-products/analyzers/command/v3 => /path/to/command

require (
    ...
    gitlab.com/gitlab-org/security-products/analyzers/command/v3 v2.19.0
)

도커에서 로컬 변경 사항 테스트

go.mod 파일에서 replace를 사용하여 Docker를 사용하려면:

  1. command의 내용을 분석기 디렉토리로 복사합니다. cp -r /path/to/command path/to/analyzer/command.
  2. 분석기의 Dockerfile에 복사 명령문을 추가합니다: COPY command /command.
  3. 위 단계에서 COPY 명령문의 대상과 일치하도록 replace 문을 업데이트합니다: replace gitlab.com/gitlab-org/security-products/analyzers/command/v3 => /command

분석기 스크립트

analyzer-scripts 저장소에는 대부분의 분석기와 상호 작용할 수 있는 스크립트가 포함되어 있습니다. 이 스크립트를 사용하면 GitLab CI와 유사한 환경에서 분석기를 빌드, 실행 및 디버그할 수 있으며, 분석기의 변경 내용을 로컬에서 유효성 검사하는 데 유용합니다.

자세한 정보는 프로젝트 README를 참조하세요.

버전 및 릴리스 프로세스

GitLab 보안 제품은 GitLab의 MAJOR.MINOR와는 별도로 독립적인 버전 관리 시스템을 사용합니다. 모든 제품은 Semantic Versioning의 변형을 사용하며 Docker 이미지로 제공됩니다.

Major는 GitLab의 새로운 주요 릴리스마다 증가하며, 파괴적인 변경이 허용된 때 증가합니다. Minor는 새로운 기능을 위해, Patch는 버그 수정을 위해 사용됩니다.

분석기는 다음과 같은 방식으로 Docker 이미지로 릴리스됩니다:

  • 기본 브랜치로의 각 푸시는 edge 이미지 태그를 덮어씁니다.
  • awesome-feature 브랜치로의 각 푸시는 해당 awesome-feature 이미지 태그를 생성합니다.
  • 각 Git 태그는 해당하는 Major.Minor.Patch 이미지 태그를 생성합니다. 수동 작업을 통해 해당 Majorlatest 이미지 태그를 이 Major.Minor.Patch로 설정하는 것이 가능합니다.

대부분의 상황에서는 자동으로 최신 경고 또는 도구에 대한 패치로 자동 유지되는 MAJOR 이미지를 사용하는 것이 좋습니다. 당사의 포함된 CI 템플릿은 주 버전을 고정하지만 원하는 경우 사용자가 직접 버전을 재정의할 수 있습니다.

새로운 분석기 Docker 이미지를 릴리스하려면 두 가지 옵션이 있습니다:

새로운 분석기 버전이 릴리스될 때 생성되는 Docker 태그를 설명하는 다음 다이어그램을 참조하세요:

graph LR A1[git tag v1.1.0]--> B1(run CI pipeline) B1 -->|build and tag patch| D1[1.1.0] B1 -->|tag minor| E1[1.1] B1 -->|retag major| F1[1] B1 -->|retag latest| G1[latest] A2[git tag v1.1.1]--> B2(run CI pipeline) B2 -->|build and tag patch| D2[1.1.1] B2 -->|retag minor| E2[1.1] B2 -->|retag major| F2[1] B2 -->|retag latest| G2[latest] A3[default 브랜치로 푸시]--> B3(run CI pipeline) B3 -->|build and tag edge| D3[edge]

지속적 배포 흐름의 경우, GitLab 레일 애플리케이션에 해당하는 새로운 구성요소를 포함하는 경우 언제든지 컴포넌트를 릴리스할 수 있습니다. 구성 요소가 기존 애플리케이션과 통합되기 전까지 표준 릴리스 주기와 프로세스에 의해 반복이 차단되어서는 안됩니다.

수동 릴리스 프로세스

  1. 새로운 분석기에 대한 CHANGELOG.md 항목이 올바른지 확인합니다.
  2. 릴리스 소스(일반적으로 master 또는 main 브랜치)에서 성공적인 파이프라인이 실행 중인지 확인합니다.
  3. 프로젝트 창의 왼쪽에있는 Deployments 메뉴를 선택한 다음 Releases 하위 메뉴를 선택하여, 분석기 프로젝트에 대한 새 릴리스를 생성합니다.
  4. New release를 선택하여 New Release 페이지를 엽니다.
    1. Tag name 드롭다운에서 CHANGELOG.md에서 사용된 동일한 버전(예: v2.4.2)을 입력하고 태그를 만드는 옵션을 선택합니다(Create tag v2.4.2를 여기에 선택).
    2. Release title 텍스트 상자에 위와 동일한 버전(예: v2.4.2)을 입력합니다.
    3. Release notes 텍스트 상자에 CHANGELOG.md의 해당 버전에서 노트를 복사하여 붙여넣습니다.
    4. 다른 설정은 기본값으로 남깁니다.
    5. Create release를 선택합니다.

위 과정을 따라 새 릴리스를 생성한 후, 지정된 Tag name과 함께 새로운 파이프라인이 트리거되고 새 분석기 Docker 이미지가 빌드됩니다.

분석기가 analyzer.yml 템플릿을 사용하는 경우, 위의 New release 프로세스의 일환으로 트리거된 파이프라인이 분석기 Docker 이미지의 새 버전을 자동으로 태그하고 배포합니다.

분석기가 analyzer.yml 템플릿을 사용하지 않는 경우, 분석기 Docker 이미지의 새 버전을 수동으로 태그하고 배포해야 합니다:

  1. 프로젝트 창의 왼쪽에 있는 CI/CD 메뉴를 선택한 다음 Pipelines 하위 메뉴를 선택합니다.
  2. 이전에 사용한 동일한 태그(예: v2.4.2)와 함께 실행 중인 새 파이프라인이 현재 있어야 합니다.
  3. 파이프라인이 완료되면 blocked 상태가 됩니다.
  4. 창 오른쪽에 있는 Manual job 재생 버튼을 선택한 다음 tag version을 선택하여 새 분석기 Docker 이미지의 새 버전을 태그하고 배포합니다.

Git 태그를 생성하여 릴리스 작업을 트리거할 시기를 결정하기 위해 최선의 판단을 사용합니다. 판단할 수 없는 경우 다른 사람의 의견을 물어봅니다.

자동 릴리스 프로세스

자동 릴리스 프로세스를 사용하기 전에 다음을 수행해야 합니다.

  1. CI/CD 환경 변수CREATE_GIT_TAG: true를 구성합니다.
  2. CI/CD 프로젝트 설정에서 Variables를 확인합니다. 프로젝트가 이미 프로젝트 그룹에서 GITLAB_TOKEN 환경 변수를 상속받지 않은 경우 프로젝트 액세스 토큰을 만들어 API에 대한 완전한 읽기/쓰기 액세스 권한으로 구성하고, 이 토큰을 참조하는 CI/CD 환경 변수GITLAB_TOKEN을 구성합니다.

위 단계를 완료한 후, 자동 릴리스 프로세스는 다음과 같이 실행됩니다.

  1. 프로젝트 유지자는 MR을 기본 브랜치에 병합합니다.
  2. 기본 파이프라인이 트리거되고, upsert git tag 작업이 실행됩니다.
    • CHANGELOG.md의 가장 최근 버전이 Git 태그 중 하나와 일치하는 경우, 작업은 무시됩니다.
    • 그렇지 않으면, 이 작업은 자동으로 프로젝트의 CHANGELOG.md 파일의 가장 최근 항목에서 버전 및 메시지를 가져와 새 릴리스와 Git 태그를 자동으로 생성합니다.
  3. 새 Git 태그를 위해 자동으로 파이프라인이 트리거됩니다. 이 파이프라인은 분석기의 latest, major, minorpatch Docker 이미지를 릴리스합니다.

분석기 릴리스 후 수행할 단계

  1. 분석기 Docker 이미지의 새 버전이 태깅되고 배포된 후 해당 테스트 프로젝트로 테스트합니다.
  2. 해당 그룹 Slack 채널에 릴리스를 발표합니다. 예시 메시지:

    FYI, 방금 ANALYZER_NAME ANALYZER_VERSION을(를) 릴리스했습니다. LINK_TO_RELEASE

한 번 푸시된 Git 태그를 삭제하지 마십시오. 해당 태그가 Go 패키지 레지스트리에서 사용되거나 캐시될 수 있는 가능성이 매우 높습니다.

중요한 수정 사항 또는 패치를 백포팅하는 방법

이전 버전으로 중요한 수정 사항이나 패치를 백포팅하려면 아래 단계를 따릅니다.

  1. 백포팅할 수정 사항의 태그에서 새 브랜치를 생성합니다(존재하지 않는 경우).
    • 예를 들어, 가장 최신 안정 버전 태그가 v4이고 v3로 수정 사항을 백포팅하는 경우 v3이라는 새 브랜치를 만듭니다.
  2. 방금 생성한 브랜치를 대상으로 하는 MR을 제출합니다.
  3. 승인된 후 MR을 해당 브랜치로 병합합니다.
  4. 브랜치에 새 태그를 생성합니다.
  5. 분석기가 자동 릴리스 프로세스를 사용하는 경우 새 버전이 릴리스됩니다.
  6. 그렇지 않으면 새 버전을 릴리스하려면 수동 힐리스 프로세스를 따라야 합니다.
  7. 참고: 릴리스 파이프라인은 가장 최근의 edge 태그를 덮어쓸 수 있으므로 해당 태그의 가장 최근 릴리스 파이프라인의 tag edge 작업을 재실행하여 해당 태그에 대한 회귀를 피해야 합니다.

새로운 분석기 개발

가끔씩 새로운 프레임워크 및 도구를 지원하기 위해 새로운 분석기 프로젝트를 빌드해야 합니다. 이를 위해 우리는 공학 오픈 소스 가이드라인을 따라야 하며, 라이선스코드 표준을 포함합니다.

또한 GitLab 애플리케이션에 통합될 사용자 지정 분석기를 작성하기 위해 최소 기능 세트가 요구됩니다:

체크리스트

기본 도구가 다음을 가지고 있는지 확인합니다:

  • 허용되는 소프트웨어 라이선스.
  • 헤드리스 실행(CLI 도구).
  • Docker 이미지로 패키지화할 수 있는 종속성(Linux 또는 Windows Docker 실행기를 사용하여 GitLab Runner에서 실행 가능).
  • 파일 이름 또는 확장자를 기반으로 감지할 수 있는 호환 프로젝트.
  • 오프라인 실행(인터넷 액세스 없음) 또는 사용자 정의 프록시 및/또는 CA 인증서 사용 구성 가능.

Dockerfile

Dockerfile은 관리되는 사용자인 GitLab이라는 권한이 없는 사용자를 사용해야 합니다. 이는 Red Hat OpenShift 인스턴스에서 관리자(루트) 사용자로 컨테이너를 실행하는 것을 허용하지 않기 때문에 필요합니다. 사용자 권한이 없는 사용자로 컨테이너를 실행할 때 고려해야 할 몇 가지 제한 사항이 있으며, Docker 파일 시스템에 쓰여야 하는 모든 파일은 GitLab 사용자의 적절한 권한이 필요합니다. 자세한 내용은 다음 머지 요청을 참조하세요: Use GitLab user instead of root in Docker image.

최소 취약점 데이터

전체 필수 필드 목록을 확인하려면 security-report-schemas를 참조하세요.

security-report-schema 리포지토리에는 각 보고서 유형에 대해 필요한 필드를 나열한 JSON 스키마가 포함되어 있습니다:

컨테이너 이미지의 위치

컨테이너 레지스트리에 쓰기 액세스하는 사람 수를 제한하기 위해 모든 이미지는 아래 위치에 게시되어야 합니다. 개발 프로젝트의 컨테이너 레지스트리는 비공개여야 합니다.

  • 그룹: https://gitlab.com/security-products/
  • 프로젝트 경로: https://gitlab.com/security-products/<NAME> (예시)
  • 레지스트리 주소: registry.gitlab.com/security-products/<NAME>[/<IMAGE_NAME>]:[TAG]
  • 권한
    • 최상위 그룹
      • 유지자: @gitlab-org/secure/managers, @gitlab-org/govern/managers
    • 프로젝트 수준
  • 프로젝트 설정
    • 가시성, 프로젝트 기능, 권한.
      • 프로젝트 가시성: 공개. “사용자가 액세스 요청” 선택 해제.
      • 이슈: 비활성화.
      • 저장소: “프로젝트 멤버만”로 설정. 비활성화: 머지 리퀘스트, 포크, Git LFS, 패키지, CI/CD.
      • 남은 항목 비활성화: 분석, 요구사항, 위키, 스니펫, 페이지, 운영.
    • 서비스 데스크: 비활성화

Sec 섹션의 각 그룹은 다음을 담당합니다: 1. 사용되지 않는 이미지를 관리하여 삭제 및 제거 일정을 생성합니다. 1. 새 위치에 프로젝트를 만들고 구성합니다. 1. 새 위치에 릴리스 아티팩트를 푸시하도록 빌드를 구성합니다. 1. 자체 지원 계약에 따라 이전 위치에서 이미지를 삭제하거나 유지합니다.

컨테이너 이미지의 일일 재구축

분석기 이미지는 매일 재구축되어, 우리가 의존하는 기본 이미지의 공급업체가 제공하는 패치를 자주 자동으로 반영합니다.

이 프로세스는 현재 MAJOR 릴리스와 일치하는 GitLab 버전에서 사용되는 이미지에만 적용됩니다. 매일 새로운 버전을 릴리스하는 것이 목적이 아니라, 각 활성화된 이미지 변형을 재구축하고 해당 태그를 덮어씁니다.

  • MAJOR.MINOR.PATCH 이미지 태그 (예: 4.1.7)
  • MAJOR.MINOR 이미지 태그(예: 4.1)
  • MAJOR 이미지 태그 (예: 4)
  • latest 이미지 태그

재구축 프로세스의 구현은 프로젝트에 따라 다양할 수 있지만, 이를 달성하기 위한 공통 CI 구성은 개발용 ci-templates 프로젝트에서 이용할 수 있습니다.

Go의 보안 및 빌드 수정

Go로 구현된 안전 분석기의 DockerfileMINOR 개정이 아닌 MAJOR 릴리스를 참조해야 합니다. 이렇게 함으로써 분석기를 컴파일하는 데 사용되는 Go 버전이 특정 시점의 모든 보안 수정사항을 포함하게 됩니다. 예를 들어, 분석기의 다단계 Dockerfile은 분석기 CLI를 빌드할 때 golang:1.15-alpine 이미지를 사용해야 하지만, golang:1.15.4-alpine을 사용하면 안 됩니다.

MINOR 개정이 릴리스되고 그것이 보안 수정사항을 포함하는 경우, 프로젝트 유지관리자는 안전 분석기를 재구축해야 하는지 확인해야 합니다. 빌드에 사용된 Go 버전은 릴리스에 해당하는 build 작업 로그에 나타나야 하며, 또한 strings 명령을 사용하여 Go 이진 파일에서 추출할 수도 있습니다.

분석기의 최신 이미지가 해당 버전의 Go로 빌드된 경우, 다시 빌드해야 합니다. 이미지를 다시 빌드하려면 유지관리자가 다음과 같은 작업을 수행할 수 있습니다:

  • 안정 버전에 해당하는 Git 태그에 대한 새 파이프라인을 트리거하거나
  • BUILD 번호가 증가된 새로운 Git 태그를 만들거나
  • 기본 브랜치에 대한 파이프라인을 트리거하고, PUBLISH_IMAGES 변수를 비어있지 않은 값으로 설정할 수 있습니다.

어느 쪽이든 새 Docker 이미지가 빌드되고, 동일한 이미지 태그가 사용됩니다: MAJOR.MINOR.PATCHMAJOR.

이 작업 흐름은 동일 MAJOR 릴리스의 MINOR 개정 사이의 완전한 호환을 가정합니다. 호환성 문제가 있는 경우, 프로젝트 파이프라인은 테스트를 실행할 때 실패합니다. 이 경우 Dockerfile에서 MINOR 개정을 참조하고 호환성 문제가 해결될 때까지 해당 예외를 문서화해두는 것이 필요할 수 있습니다.

Dockerfile에 언급되지 않았기 때문에, MINOR 개정의 Go는 프로젝트 변경 로그에 언급되지 않습니다.

빌드 관련 변경 사항이고 변경 사항이 변경 로그 항목을 필요로 하지 않는 경우에는 빌드 태그를 사용하는 것이 합리적일 수 있습니다. 예를 들어, Docker 이미지를 새 레지스트리 위치로 푸시하는 경우입니다.

재구축하는 Git 태그

분석기를 다시 빌드하기 위해 새로운 Git 태그를 만들 때, 새 태그는 이전과 동일한 MAJOR.MINOR.PATCH 버전을 가지지만, BUILD 번호는 증가됩니다(이는 semver에서 정의됨).

예를 들어, 분석기의 최신 릴리스가 v1.2.3이고 해당하는 Docker 이미지가 영향 받는 버전의 Go를 사용하여 빌드되었다면, 유지관리자는 이미지를 재구축하기 위해 v1.2.3+1 Git 태그를 만듭니다. 만약 최신 릴리스가 v1.2.3+1이라면, 이후 v1.2.3+2를 만듭니다.

빌드 번호는 이미지 태그에서 자동으로 제거됩니다. 예를 들어, gemnasium 프로젝트에서 v1.2.3+1 Git 태그를 만드는 경우, 파이프라인이 이미지를 재빌드하고, gemnasium:1.2.3로 푸시됩니다.

재빌드하기 위해 만든 Git 태그에는 새로운 빌드가 필요한 이유를 설명하는 간단한 메시지가 포함됩니다. 예: Go 1.15.6로 재구축. 태그에는 릴리스 노트가 없으며, 릴리스가 만들어지지 않습니다.

분석기를 다시 빌드하기 위해 새로운 Git 태그를 만들려면 다음 단계를 따르세요:

  1. Git 태그를 만들고 메시지를 제공합니다.

    git tag -a v1.2.3+1 -m "Go 1.15.6로 재구축"
    
  2. 태그를 레포지토리로 푸시합니다.

    git push origin --tags
    
  3. Git 태그에 대한 새 파이프라인이 트리거되고 새 이미지가 빌드되고 태그가 달립니다.
  4. master 브랜치에 대한 새 파이프라인을 실행하여 완전한 테스트 스위트를 실행하고 새로 태그가 달린 이미지에 대한 새로운 취약점 보고서를 생성하세요. 이는 위의 3. 단계에서 트리거된 릴리스 파이프라인이 일부 테스트만 실행하기 때문에 필요합니다. 예를 들어, 컨테이너 스캐닝 분석은 수행하지 않습니다.

매월 릴리스 프로세스

이 작업은 매월 18일에 수행되어야 합니다. 그러나 이는 준연한 기한이며 몇 일 이후에 수행되어도 문제가 되지 않습니다.

먼저, 해당 저장소의 스크립트를 사용하여 릴리스를 위한 새 이슈를 만듭니다: ./scripts/release_issue.rb MAJOR.MINOR. 이 이슈는 릴리스 프로세스 전반을 안내합니다. 일반적으로 다음 작업을 수행해야 합니다:

의존성 업데이트

분석기 소스에 사용된 모든 종속성 및 상위 스캐너(있는 경우)는 월간 주기로 업데이트됩니다. 이에는 주로 보안 수정과 호환되는 변경 사항이 포함됩니다.

  • 정적 분석 팀은 SAST 분석기의 모든 종속성을 자동화하기 위해 사용자 정의 내부 도구(SastBot)를 사용합니다. SastBot은 매월 8일에 MR(병합 요청)을 생성하고, 해당 MR을 정적 분석 팀 멤버들에게 배정하여 검토를 진행합니다. 프로세스에 대한 자세한 내용은 의존성 업데이트 자동화를 참조하십시오.