한국어

GitLab CI/CD에서 Codex Security 실행

GitLab CI/CD에서 Codex Security를 실행하여 커밋된 변경 사항과 보호된 브랜치를 스캔하고, 발견 항목을 GitLab Security에 게시하며, 선택적으로 검증된 수정 사항을 초안 병합 요청으로 제안하세요.

이 워크플로는 스캔 자격 증명을 리포지토리 쓰기 권한과 분리합니다. 생성된 변경 사항은 병합 전에 항상 사람의 검토를 거쳐야 합니다.

먼저 스캔 전용 보고부터 시작하세요. 프로젝트의 러너, 발견 항목 및 자격 증명 경계를 확인한 후에만 수정을 활성화하세요.

시작하기 전에

다음이 필요합니다:

  • Codex 샌드박스의 사용자 네임스페이스를 지원하는 신뢰할 수 있는 러너가 있는 GitLab 프로젝트.
  • 프로젝트 CI/CD 변수와 보호된 리소스를 구성할 수 있도록 GitLab 프로젝트의 Maintainer 또는 Owner 역할.
  • Codex Security 액세스 권한이 있는 OpenAI API key. Platform API key를 사용하는 조직은 Cyber용 Trusted Access를 요청할 수 있습니다. ChatGPT 인증을 사용하는 개인은 개인 Trusted Access 절차를 이용할 수 있습니다. 일부 계정이나 리포지토리는 전체 리포지토리 스캔에 이 액세스 권한이 필요합니다.
  • SARIF 2.1.0 수집을 위한 GitLab Ultimate 19.2 이상.
  • 병합 요청 작업에서 병합 기준점을 계산할 수 있도록 전체 Git 기록.

파이프라인 이미지는 Node.js 26, Python 3, Git, rg 및 고정된 Codex Security CLI를 설치합니다. 자동 수정에는 기존 회귀 테스트와 보호된 자격 증명 없이 리포지토리가 제어하는 명령을 실행할 수 있는 러너도 필요합니다.

스캔 전용 파이프라인으로 시작

CODEX_SECURITY_API_KEY라는 마스킹되고 숨겨진 보호된 GitLab CI/CD 변수를 생성하세요. Codex Security 액세스 권한이 있는 OpenAI Platform API key를 사용하고 환경 범위를 codex-security/openai로 설정하세요. 환경 범위가 지정된 CI/CD 변수를 참조하세요.

먼저 이 최소 파이프라인을 테스트 프로젝트에 추가하세요. 적격한 보호된 병합 요청에서 커밋된 변경 사항을 스캔하고, 보고 작업이 성공하면 SARIF를 게시하며, 별도의 게이트에서 스캐너 결과를 복원합니다:

stages:
  - security_scan
  - security_gate

.codex-security-merge-request:
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID && $CI_MERGE_REQUEST_SOURCE_BRANCH_PROTECTED == "true" && $CI_MERGE_REQUEST_TARGET_BRANCH_PROTECTED == "true"'

codex-security:
  extends: .codex-security-merge-request
  stage: security_scan
  image: node:26-bookworm-slim
  environment:
    name: codex-security/openai
    action: access
  variables:
    GIT_DEPTH: "0"
  before_script:
    - npm install --prefix /tmp/codex-security-cli --ignore-scripts --no-audit --no-fund @openai/codex-security@0.1.20
  script:
    - |
      set -eu
      test -n "${CODEX_SECURITY_API_KEY:-}"

      CODEX_SECURITY_BIN="/tmp/codex-security-cli/node_modules/.bin/codex-security"
      RESULTS_DIR="/tmp/codex-security-results-$CI_JOB_ID"
      ARTIFACT_DIR="codex-security-artifacts"
      BASE_REVISION="$(git merge-base \
        "$CI_MERGE_REQUEST_DIFF_BASE_SHA" "$CI_COMMIT_SHA")"
      install -d -m 700 "$RESULTS_DIR" "$ARTIFACT_DIR/results"

      codex_security_api_key="$CODEX_SECURITY_API_KEY"
      unset CODEX_SECURITY_API_KEY
      set +e
      OPENAI_API_KEY="$codex_security_api_key" \
        "$CODEX_SECURITY_BIN" scan . \
          --diff "$BASE_REVISION" \
          --head "$CI_COMMIT_SHA" \
          --auth api-key \
          --output-dir "$RESULTS_DIR" \
          --json
      scan_exit="$?"
      set -e
      unset codex_security_api_key

      case "$scan_exit" in
        0|1|2) ;;
        *) exit "$scan_exit" ;;
      esac

      "$CODEX_SECURITY_BIN" export "$RESULTS_DIR" \
        --export-format sarif \
        --source-root "$CI_PROJECT_DIR" \
        --output "$ARTIFACT_DIR/results.sarif"
      test -s "$ARTIFACT_DIR/results.sarif"
      cp -R "$RESULTS_DIR"/. "$ARTIFACT_DIR/results/"
      printf '%s\n' "$scan_exit" > "$ARTIFACT_DIR/scan-exit-code.txt"
      exit 0
  artifacts:
    when: always
    access: maintainer
    expire_in: 7 days
    paths:
      - codex-security-artifacts/
    reports:
      sarif: codex-security-artifacts/results.sarif

codex-security-gate:
  extends: .codex-security-merge-request
  stage: security_gate
  image: alpine:3.20
  needs:
    - job: codex-security
      artifacts: true
  script:
    - exit "$(cat codex-security-artifacts/scan-exit-code.txt)"

보안 정보가 필요한 작업을 실행하기 전에 .gitlab-ci.yml의 모든 변경 사항을 검토하세요. 최소 예제에서는 의도적으로 전체 스캔과 수정을 생략합니다.

프로덕션 파이프라인 도입

  1. 전체 GitLab 파이프라인을 다운로드하고 리포지토리 루트에 .gitlab-ci.yml로 저장하세요. 리포지토리에 이미 파이프라인이 있다면 예제의 단계, 숨겨진 템플릿 및 작업을 기존 파일에 병합하세요.
  2. 기존 빌드, 테스트 및 배포 단계를 유지하세요. 프로젝트에서 workflow: rules 설정을 사용하는 경우 스캔하려는 파이프라인 이벤트가 허용되는지 확인하세요.

이 예제는 security_scan, security_remediation, security_publishsecurity_gate 단계를 추가합니다. 스캔 전용 보고에는 CODEX_SECURITY_API_KEY만 필요합니다.

기본적으로 스캔 작업은 보호된 브랜치 사이에서 발생하는 동일 프로젝트 병합 요청에만 실행됩니다. 보호된 기본 브랜치 푸시와 수동 파이프라인을 스캔하려면 CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH=true로 설정하세요. 보호된 기본 브랜치에서 예약 심층 스캔을 활성화하려면 CODEX_SECURITY_SCHEDULED_DEEP_SCAN=true로 설정하고 명시적인 시간 및 비용 예산을 구성하세요.

병합 요청 파이프라인은 다음 조건을 모두 충족해야 보호된 변수와 러너에 액세스할 수 있습니다:

포크 파이프라인과 보호되지 않은 병합 요청에는 스캔 자격 증명이 제공되지 않습니다. 보안 정보가 필요한 작업을 실행하기 전에 .gitlab-ci.yml의 모든 변경 사항을 검토하세요. 변수를 마스킹하고 숨겨도 신뢰할 수 없는 CI 코드가 안전해지는 것은 아닙니다.

스캔 실행 및 발견 항목 검토

적격한 보호된 병합 요청을 생성하거나 보호된 기본 브랜치에서 파이프라인을 실행하세요. 유료 전체 리포지토리 스캔을 실행하기 전에 작은 diff부터 시작하세요.

codex-security 작업을 열고 아티팩트에 다음 항목이 포함되어 있는지 확인하세요:

  • scan-manifest.json
  • findings.json
  • coverage.json
  • results.sarif
  • scan-exit-code.txt

그런 다음 파이프라인의 Security 탭을 열고 수집 경고를 검토한 뒤 발견 항목 식별자, 심각도 수준 및 소스 위치를 확인하세요. 기본 브랜치 스캔은 프로젝트 취약점 기록도 생성합니다. 병합 요청 발견 항목은 파이프라인 Security 탭이나 병합 요청 보안 위젯에 표시되지만 프로젝트 전체 취약점 기록은 생성하지 않습니다.

스캔 결과에는 취약한 소스 코드 조각, 증거 및 수정 세부 정보가 포함될 수 있으므로 아티팩트 액세스를 제한하세요.

스캔 프로필 선택

파이프라인은 트리거에 따라 프로필을 선택합니다:

트리거 대상 모드 작업량
보호된 동일 프로젝트 병합 요청 커밋된 diff standard low
선택적으로 실행하는 보호된 기본 브랜치 푸시 또는 수동 실행 전체 리포지토리 standard high
보호된 기본 브랜치에서 선택적으로 실행하는 예약 작업 전체 리포지토리 deep xhigh

병합 요청 스캔은 커밋된 변경 사항에 피드백을 집중합니다. 기본 브랜치 스캔은 통합된 리포지토리를 검토합니다. 예약 심층 스캔은 더 폭넓은 정기적 검사 범위를 제공합니다. diff 스캔이 완료되어도 해당 변경 사항에만 적용되며 전체 리포지토리에 문제가 없음을 의미하지 않습니다.

워크플로는 CLI를 리포지토리 외부에 설치하고 절대 경로로 실행합니다. 드라이런 사전 점검에서는 프로세스 범위 API key를 사용하지만 유료 스캔을 시작하거나 API 인증, Codex Security 액세스, 할당량 또는 모델 가용성을 검증하지 않습니다.

워크플로는 스캔 상태와 결과를 작업 트리 외부에 기록하고 OPENAI_API_KEY의 범위를 스캔 프로세스로 제한합니다. CLI는 모든 GitLab 변수를 상속하지 않고 작고 명시적인 환경을 전달받습니다. diff 스캔의 경우 워크플로가 병합 기준점을 계산하고 검토된 기준 및 헤드 리비전에 스캔을 바인딩합니다.

이 예제는 @openai/codex-security 패키지를 0.1.20에 고정합니다. 고정 버전을 변경하기 전에 인증, 아티팩트, SARIF 수집 및 정책 게이트를 다시 테스트하세요.

보고와 정책 적용 분리

GitLab은 성공한 보고 작업에서 SARIF를 수집합니다. 파이프라인은 먼저 보고서를 게시한 다음 별도의 codex-security-gate 작업에서 스캐너의 종료 상태를 복원합니다.

보고 작업은 종료 코드 01의 발견 항목을 허용합니다. 종료 코드 2는 스캔 매니페스트에서 스캔 완료가 입증되고 검사 범위가 명시적으로 partial이며 비어 있지 않은 SARIF 보고서가 존재할 때만 허용합니다. 그 밖의 런타임, 구성 또는 내보내기 실패는 계속 차단됩니다.

최종 게이트는 다음 스캐너 종료 코드를 유지합니다:

종료 의미
0 스캔이 전체 검사 범위로 완료되었으며 정책을 통과했습니다.
1 스캔이 완료되었고 구성된 임곗값 이상의 문제를 발견했습니다.
2 스캔의 검사 범위가 불완전했거나 입력 또는 런타임 오류가 발생했습니다.

이 예제는 부분 검사 범위를 조정하는 동안 종료 코드 2를 일시적으로 허용합니다. 불완전한 검사 범위가 파이프라인을 차단해야 할 때는 이 허용 설정을 제거하세요.

수정과 게시는 최종 정책 게이트보다 먼저 실행됩니다. 적격한 발견 항목은 이후 게이트에서 파이프라인이 실패하더라도 검증된 초안 병합 요청을 생성할 수 있습니다.

검증된 수정 활성화

자동 수정은 선택 사항이며 보호된 기본 브랜치 파이프라인에서만 실행됩니다. Codex 수정 프로세스와 리포지토리가 제어하는 검증 명령에는 GitLab 프로젝트 액세스 토큰이나 러너가 주입한 자격 증명이 제공되지 않습니다.

보안 계약은 세 부분으로 구성됩니다. 리포지토리가 제어하는 명령은 OpenAI 또는 GitLab 자격 증명을 전달받지 않고, 게시 작업만 리포지토리 쓰기 권한을 받으며, 생성된 모든 변경 사항은 사람이 검토하고 병합할 때까지 초안으로 유지됩니다.

워크플로는 다음을 수행합니다:

  1. 전체 스캔 범위와 high 또는 critical 심각도의 발견 항목을 요구합니다.
  2. 패치를 적용하기 전에 구성된 회귀 테스트가 실패하는지 확인합니다.
  3. 범위가 제한된 패치를 생성하고 CI, 자격 증명, 바이너리 또는 기타 보호된 파일의 변경을 거부합니다.
  4. OpenAI, GitLab, 레지스트리, 배포 또는 작업 토큰 자격 증명 없이 회귀 테스트를 실행합니다.
  5. verify-fix 명령으로 fixed, still_vulnerable 또는 inconclusive 상태를 반환합니다. 작업은 verify-fixfixed 상태를 반환하고 검증 프로세스에서 패치가 변경되지 않은 경우에만 패치를 게시합니다.

수정을 활성화하려면 다음 보호 변수를 설정하세요:

  • CODEX_SECURITY_ENABLE_REMEDIATION 변수를 true로 설정합니다.
  • CODEX_SECURITY_VERIFICATION_COMMAND를 수정 전에는 1로 종료되고 수정 후에는 0로 종료되는 기존 회귀 테스트로 설정합니다.
  • 선택적으로 CODEX_SECURITY_SETUP_COMMAND를 비대화형 종속성 설정 명령으로 지정합니다.

특정 구현이 아니라 기반 보안 불변 조건을 검사하는 회귀 테스트를 선택하세요. 생성된 테스트와 소스 변경 사항도 동일한 수준으로 면밀히 검토하세요.

고급: 리포지토리 명령 격리

validate, patchverify-fix 명령에는 프로세스 범위 CODEX_API_KEY가 제공됩니다. 리포지토리가 제어하는 설정 및 테스트 명령은 추적된 소스 파일의 쓰기 가능한 복사본에서 별도의 권한 없는 사용자로 실행됩니다. 이 복사본에서는 의도적으로 Git 메타데이터, 하위 모듈 콘텐츠 및 다운로드된 아티팩트를 제외합니다. .git 또는 하위 모듈이 필요한 설정 및 테스트 명령은 별도로 설계된 자격 증명 없는 작업에서 실행해야 합니다.

루트 소유 Codex 단계만 정식 체크아웃이나 GitLab의 인접 파일 변수 디렉터리에 액세스할 수 있습니다. 복사본의 정리된 환경에는 PATH, HOME, LANG, CICI_PROJECT_DIR만 포함됩니다. 명령에 다른 비보안 값이 필요하다면 명령을 검토한 후 허용 목록에 추가하세요. 러너에서 사용자를 변경할 수 없다면 수정을 활성화하기 전에 검증을 별도의 자격 증명 없는 작업으로 옮기세요.

초안 병합 요청 게시

Developer 역할과 apiwrite_repository 범위를 가진 GitLab 프로젝트 액세스 토큰을 생성하세요. 이를 codex-security/publish 환경으로만 범위가 지정된 보호되고 마스킹되고 숨겨진 GITLAB_REMEDIATION_TOKEN에 저장하세요.

게시를 활성화하려면 CODEX_SECURITY_CREATE_MR=true로 설정하세요. 또한 생성된 모든 수정 브랜치가 통과해야 하는 프로젝트별 보안 회귀 테스트로 비보안 CODEX_SECURITY_MR_TEST_COMMAND 변수를 설정하세요. 생성된 보호되지 않은 병합 요청에서 명령을 읽을 수 있도록 이 변수는 보호하지 마세요. 게시 워크플로는 다음을 수행합니다:

  • 리포지토리 쓰기 토큰은 받지만 OpenAI 자격 증명은 받지 않습니다.
  • codex-security/fix-<finding-hash> 브랜치를 생성합니다.
  • 초안 병합 요청을 열고, 열려 있는 기존 초안이 있으면 중복 생성하지 않고 재사용합니다.
  • 보호된 자격 증명 없이 추적된 파일만 포함한 복사본에서 권한 없는 사용자로 보호되지 않은 수정 브랜치의 회귀 테스트를 실행합니다.
  • 생성된 변경 사항을 자동으로 병합하지 않습니다.

프로젝트 액세스 토큰 대신 CI_JOB_TOKEN을 사용하지 마세요. 필요한 병합 요청 생성 작업을 수행할 수 없습니다. 병합하기 전에 제안된 패치, 검증 증거 및 발견 항목을 검토하세요.

선택 변수 구성

활성화하는 기능에 필요한 변수만 구성하세요:

변수 필요한 경우 기본값 또는 용도
CODEX_SECURITY_API_KEY 모든 스캔 보호, 마스킹, 숨김; codex-security/openai로 범위 지정
CODEX_SECURITY_VERSION CLI 업그레이드 0.1.20에 고정; 변경 전 재테스트
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH 기본 브랜치 전체 스캔 명시적으로 선택해 실행; 기본적으로 꺼짐
CODEX_SECURITY_SCHEDULED_DEEP_SCAN 예약 심층 스캔 명시적으로 선택해 실행; 기본적으로 꺼짐
CODEX_SECURITY_DEEP_MAX_TIME_HOURS 예약 심층 스캔 0보다 크고 8보다 작은 시간 예산 필요
CODEX_SECURITY_DEEP_MAX_COST 예약 심층 스캔 0보다 큰 예상 USD 비용 가드레일 필요
CODEX_SECURITY_ENABLE_REMEDIATION 패치 생성 보호된 선택적 활성화; 기본적으로 꺼짐
CODEX_SECURITY_VERIFICATION_COMMAND 패치 생성 보호된 회귀 테스트
CODEX_SECURITY_SETUP_COMMAND 선택적 수정 설정 보호된 종속성 설치
CODEX_SECURITY_REMEDIATION_EFFORT 선택적 수정 조정 high
CODEX_SECURITY_MAX_CHANGED_FILES 선택적 패치 크기 제한 8; 허용 범위 1~`20`
CODEX_SECURITY_CREATE_MR 초안 병합 요청 생성 보호된 선택적 활성화; 기본적으로 꺼짐
GITLAB_REMEDIATION_TOKEN 초안 병합 요청 생성 codex-security/publish로 범위가 지정된 Developer 프로젝트 토큰
CODEX_SECURITY_GITLAB_INTERNAL_URL 선택적 자체 호스팅 게시 러너에서 연결 가능한 GitLab origin
CODEX_SECURITY_MR_TEST_COMMAND 초안 병합 요청 게시 필수 비보안 프로젝트별 회귀 테스트
CODEX_SECURITY_MR_SETUP_COMMAND 선택적 수정 브랜치 설정 비보안 종속성 설정

GitLab은 CI_* 변수를 제공합니다. 파이프라인은 CODEX_SECURITY_BIN, CODEX_SECURITY_EFFORT, CODEX_SECURITY_MODE, CODEX_SECURITY_STATE_DIRCODEX_SECURITY_TARGET 변수를 관리하므로 프로젝트 변수로 구성하지 마세요. diff 스캔의 경우 CLI가 정규화된 기준 및 헤드 리비전에서 정식 대상 ID를 파생합니다.

적용 수준 및 비용 조정

병합 요청 피드백에는 범위가 제한된 diff 스캔을, 기본 브랜치에는 표준 리포지토리 스캔을, 더 폭넓은 검사 범위에는 예약 심층 스캔을 사용하세요. 두 전체 리포지토리 프로필은 기본적으로 꺼져 있습니다. 예약 심층 스캔에는 CODEX_SECURITY_DEEP_MAX_TIME_HOURSCODEX_SECURITY_DEEP_MAX_COST 변수도 필요합니다. CLI 시간 예산은 작업의 8시간 제한보다 짧게 유지하세요. 예산을 설정하기 전에 대표적인 실행을 측정하세요. --max-cost 옵션은 엄격한 결제 상한이 아니라 예상 비용 가드레일로 취급하세요.

먼저 보고 전용 스캔부터 시작하세요. 팀에서 대표적인 발견 항목, 검사 범위, 비용 및 실행 시간을 검토한 후 --fail-on-severity 옵션을 추가하세요. 심각도 정책과 종료 코드에 관한 자세한 내용은 CI에서 Codex Security 실행을 참조하세요.

작업이 실패하는 경우:

  • 스캔 아티팩트가 없으면 구성 또는 러너 문제를 의미합니다.
  • 아티팩트가 있지만 검사 범위가 부분적이면 coverage.json을 검토해야 합니다.
  • GitLab 발견 항목이 없으면 SARIF 보고 작업이 성공했는지와 GitLab이 보고서를 수락했는지 확인해야 합니다.
  • 수정이 건너뛰어지면 보호된 브랜치, 전체 검사 범위, 발견 항목 심각도, 검증 명령 및 선택적 활성화 변수를 확인해야 합니다.
  • 게시 오류가 발생하면 프로젝트 토큰의 역할, 범위 및 환경 제한을 확인해야 합니다.

모든 명령, 플래그 및 아티팩트에 관한 자세한 내용은 Codex Security CLI 레퍼런스를 참조하세요.