보안을 위한 코드 변경 사항 검토
풀 리퀘스트와 로컬 변경 사항에서 보안 회귀가 발생했는지 수동으로 또는 CI/CD에서 검토합니다.
보안 변경 검토를 실행하여 Git으로 관리되는 하나의 변경 세트에서 회귀를 찾습니다. Codex는 변경된 소스형 파일과 이를 직접 지원하는 코드를 각각 검토합니다. 검토 범위를 전체 리포지토리 감사로 확장하지는 않습니다.
특정 변경 사항이 아니라 전체 리포지토리를 스캔하려면 보안 스캔 실행을 참조하세요.
수동 검토 실행
데스크톱 앱에서 Security를 열고 Scans를 선택한 다음 + Scan을 선택합니다. 리포지토리를 선택한 다음 Changes를 선택합니다. 커밋되지 않은 변경 사항, 단일 커밋 또는 기준 리비전과 헤드 리비전을 검토합니다. 변경 사항 스캔에서는 Deep scan을 사용할 수 없습니다.
대화에서 Codex에 커밋되지 않은 변경 사항을 검토하도록 요청할 수도 있습니다.
Use $codex-security:security-diff-scan to review my current uncommitted changes for security regressions.커밋 또는 브랜치 범위의 경우 필요하면 양쪽 끝을 모두 지정합니다.
Use $codex-security:security-diff-scan to review the changes from origin/main to HEAD for security regressions. Focus on authentication, authorization, input handling, filesystem access, network requests, and secrets.로컬 체크아웃에서 기준 리비전과 헤드 리비전을 사용할 수 있다면 풀 리퀘스트를 지정할 수도 있습니다.
설정에서 변경 사항 확인
- Changes를 선택합니다.
- 체크아웃된 리포지토리, 현재 브랜치, 최신 커밋을 확인합니다.
- Changes to review에서 다음 중 하나를 선택합니다.
- 현재 작업 트리의 경우
Uncommitted changes. - 단일 커밋 검토의 경우 최신 커밋.
- 브랜치 또는 풀 리퀘스트 범위의 경우 기준 리비전과 헤드 리비전.
- 현재 작업 트리의 경우
- 요약이 검토하려는 변경 사항을 설명하는지 확인합니다.
- Start scan을 선택합니다.
이 워크플로는 다른 브랜치를 체크아웃하거나 선택한 작업 트리를 변경하지 않습니다. 요청한 리비전을 로컬에서 사용할 수 없다면 검토 전에 가져오거나 로컬에서 사용할 수 있는 기준 리비전과 헤드 리비전을 제공하세요.
발견 항목에 대한 조치
결과를 검토한 후 수락한 발견 항목을 수정하고 검증하거나 발견 항목을 내보내고 추적하세요.
CI/CD에서 검토 자동화
러너가 상호작용 없이 Codex CLI를 호출할 수 있다면 CI에서 동일한 $codex-security:security-diff-scan
스킬을 실행합니다. 먼저 스캔 자격 증명을 노출하지 않고 CLI와 플러그인을
설치합니다.
npm install --global @openai/codexCLI에 Codex Security 플러그인을 설치합니다.
codex plugin add codex-security@openai-curated설치 명령은 공개 Codex CLI 플러그인 마켓플레이스를 사용하며, 여기에서 제공하는 버전은 호스팅된 데스크톱 앱 카탈로그의 버전과 다를 수 있습니다. CI에서 특정 플러그인 버전이나 기능에 의존하기 전에 플러그인 변경 로그를 확인하세요.
그런 다음 스캔하는 동안에만 CI 비밀 저장소의 OpenAI API key를
CODEX_SECURITY_API_KEY로 노출합니다.
CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \
--sandbox workspace-write \
"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."스캔은 출력을
$TMPDIR/codex-security-scans/<repository>/<scan-id>/에 기록합니다.
| 파일 | 내용 |
|---|---|
report.md |
전체 스캔 디렉터리를 읽기 위한 기본 진입점입니다. |
findings/<slug>/ |
보고 가능한 발견 항목별 상세 취약점 보고서이며, 가능한 경우 이를 뒷받침하는 개념 증명 파일이 포함됩니다. |
hardening/ |
스캔에 보고 가능한 발견 항목이 있을 때 생성되는 구조적 강화 포트폴리오와 이를 뒷받침하는 제안 또는 다이어그램입니다. |
findings.json |
안정적인 식별자, 심각도, 신뢰도, 소스 위치, 해결 방법이 포함된 발견 항목입니다. 승인된 내부 보안 워크플로 또는 다운스트림 도구에 제공하세요. |
scan-manifest.json |
검토된 대상, 리비전, 아티팩트 해시가 포함된 봉인된 스캔 확인서입니다. |
coverage.json |
검토된 영역과 보류된 영역, 제외 항목, 적용 범위의 완전성입니다. |
findings.json 스키마는
전체 구조를 정의합니다. 스키마에는 다음 필드가 포함됩니다.
| 필드 | 유형 | 설명 |
|---|---|---|
documentType |
문자열 | 문서를 codex-security.findings로 식별합니다. |
schemaVersion |
문자열 | 발견 항목 스키마 버전을 식별합니다. |
scanId |
문자열 | 발견 항목을 생성한 스캔을 식별합니다. |
findings |
배열 | 0개 이상의 발견 항목 객체를 포함합니다. |
findings[].findingId |
문자열 | 발견 항목 지문에서 파생된 안정적인 발견 항목 식별자입니다. |
findings[].occurrenceId |
문자열 | 특정 스캔에서 이 발견 항목이 발생한 사례를 식별합니다. |
findings[].ruleId |
문자열 | 취약점 계열을 식별합니다. |
findings[].identity |
객체 | 의미적 앵커와 선택적 형제 인스턴스 식별자를 포함합니다. |
findings[].fingerprints |
객체 | 지문 알고리즘과 기본 지문을 포함합니다. |
findings[].title |
문자열 | 간결한 발견 항목 제목을 제공합니다. |
findings[].summary |
문자열 | 취약점과 그 영향을 요약합니다. |
findings[].severity |
객체 | 심각도 수준과 선택적 점수 세부 정보를 포함합니다. |
findings[].confidence |
객체 | 신뢰도 수준과 근거를 포함합니다. |
findings[].taxonomy |
객체 | 취약점 범주와 CWE 식별자를 포함합니다. |
findings[].locations |
배열 | 영향을 받는 파일, 줄 번호, 위치 역할을 나열합니다. |
findings[].remediation |
문자열 | 권장 수정 방법을 설명합니다. |
findings[].provenance |
객체 | 발견 항목의 출처를 식별합니다. |
예를 들어 다음 명령은 발견 항목마다 탭으로 구분된 행 하나를 출력합니다.
jq -r '
.findings[] |
[.findingId, .severity.level, .confidence.level, .locations[0].path, .locations[0].startLine, .title] |
@tsv
' findings.json이 예시에서는 Node.js와 npm, Git, Python
3, jq 및 제공업체의 명령줄 도구가 설치된 신뢰할 수 있는 Linux 러너를 가정합니다. npm 전역 패키지 접두사에는
쓰기 권한이 있어야 합니다.
사용 중인 CI 제공업체에 맞는 예시를 선택하세요. 스캔 결과에는 민감한 취약점 세부 정보가 포함될 수 있습니다. 아티팩트를 비공개로 유지하고 대상 독자, 내용, 필요한 승인을 검토한 후에만 발견 항목을 게시하세요.
name: Codex Security review
on:
pull_request:
jobs:
security-review:
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Install Codex Security
env:
CODEX_HOME: ${{ runner.temp }}/codex-home
run: |
npm install --global @openai/codex
codex plugin add codex-security@openai-curated
- name: Review code changes
env:
CODEX_SECURITY_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}
CODEX_HOME: ${{ runner.temp }}/codex-home
TMPDIR: ${{ runner.temp }}/codex-security
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_REVISION: ${{ github.event.pull_request.head.sha }}
run: |
BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_REVISION")"
CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \
--sandbox workspace-write \
"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."
- uses: actions/upload-artifact@v4
if: always()
with:
name: codex-security-review
path: ${{ runner.temp }}/codex-security/codex-security-scans 마스킹된 CODEX_SECURITY_API_KEY CI/CD 변수를 만들고 발견 항목을 공유하기 전에 스캔
아티팩트를 비공개로 검토하세요.
codex-security-review:
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID'
variables:
GIT_DEPTH: "0"
script:
- |
codex_security_api_key="$CODEX_SECURITY_API_KEY"
unset CODEX_SECURITY_API_KEY
export CODEX_HOME="/tmp/codex-home-$CI_JOB_ID"
export TMPDIR="/tmp/codex-security-$CI_JOB_ID"
export BASE_REVISION="$CI_MERGE_REQUEST_DIFF_BASE_SHA"
export HEAD_REVISION="${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA:-$CI_COMMIT_SHA}"
npm install --global @openai/codex
codex plugin add codex-security@openai-curated
CODEX_API_KEY="$codex_security_api_key" codex exec \
--sandbox workspace-write \
"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."
after_script:
- |
unset CODEX_SECURITY_API_KEY
scan_root="/tmp/codex-security-$CI_JOB_ID/codex-security-scans"
if [ -d "$scan_root" ]; then
tar -czf codex-security-artifacts.tar.gz -C "$scan_root" .
fi
artifacts:
when: always
paths:
- codex-security-artifacts.tar.gz trigger: none
pool:
vmImage: ubuntu-latest
steps:
- checkout: self
fetchDepth: 0
- bash: |
set -euo pipefail
export CODEX_HOME="$AGENT_TEMPDIRECTORY/codex-home"
npm install --global @openai/codex
codex plugin add codex-security@openai-curated
displayName: Install Codex Security
- bash: |
set -euo pipefail
export CODEX_HOME="$AGENT_TEMPDIRECTORY/codex-home"
export TMPDIR="$AGENT_TEMPDIRECTORY/codex-security"
export HEAD_REVISION="$SYSTEM_PULLREQUEST_SOURCECOMMITID"
export BASE_REVISION="$(git merge-base HEAD^1 "$HEAD_REVISION")"
CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \
--sandbox workspace-write \
"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."
displayName: Review code changes
condition: and(succeeded(), ne(variables['System.PullRequest.IsFork'], 'True'))
env:
CODEX_SECURITY_API_KEY: $(CODEX_SECURITY_API_KEY)
- publish: $(Agent.TempDirectory)/codex-security/codex-security-scans
artifact: codex-security-review
condition: always()Azure Repos의 경우 풀 리퀘스트에서 파이프라인을 실행하도록 Build validation 브랜치 정책을 구성합니다.
pipeline {
agent { label 'linux' }
stages {
stage('Codex Security review') {
when {
allOf {
changeRequest()
expression { !env.CHANGE_FORK?.trim() }
}
}
steps {
sh '''#!/usr/bin/env bash
set -euo pipefail
export CODEX_HOME="/tmp/codex-home-$BUILD_TAG"
export TMPDIR="/tmp/codex-security-$BUILD_TAG"
mkdir -p "$TMPDIR"
git fetch --no-tags origin "$CHANGE_TARGET"
target="$(git rev-parse FETCH_HEAD)"
git fetch --no-tags origin "$CHANGE_BRANCH"
git rev-parse FETCH_HEAD > "$TMPDIR/head"
git merge-base "$target" "$(cat "$TMPDIR/head")" > "$TMPDIR/base"
npm install --global @openai/codex
codex plugin add codex-security@openai-curated
'''
withCredentials([string(credentialsId: 'codex-security-api-key', variable: 'CODEX_SECURITY_API_KEY')]) {
sh '''#!/usr/bin/env bash
set +x
set -euo pipefail
export CODEX_HOME="/tmp/codex-home-$BUILD_TAG"
export TMPDIR="/tmp/codex-security-$BUILD_TAG"
export HEAD_REVISION="$(cat "$TMPDIR/head")"
export BASE_REVISION="$(cat "$TMPDIR/base")"
CODEX_API_KEY="$CODEX_SECURITY_API_KEY" codex exec \
--sandbox workspace-write \
"Use \$codex-security:security-diff-scan to review changes from $BASE_REVISION to $HEAD_REVISION for security regressions. Do not modify the checkout."
'''
}
}
post {
always {
sh '''#!/usr/bin/env bash
set -euo pipefail
scan_root="/tmp/codex-security-$BUILD_TAG/codex-security-scans"
if [ -d "$scan_root" ]; then
tar -czf codex-security-artifacts.tar.gz -C "$scan_root" .
fi
'''
archiveArtifacts artifacts: 'codex-security-artifacts.tar.gz', allowEmptyArchive: true
}
}
}
}
} 이 예시에서는 포크에서 생성된 풀 리퀘스트를 건너뜁니다. 보호된 파이프라인 정의에서만,
그리고 스캔 자격 증명을 신뢰할 수 있는 기여자의 경우에만 자격 증명이 필요한 작업을
실행하세요. 구조화된 발견 항목, 매니페스트, 적용 범위 아티팩트, report.md 및 여기에 연결된 findings/와
hardening/ 출력을 함께 보관하려면 codex-security-scans을 아카이브하세요. 먼저 권고용 결과로 시작하고 작업을 필수 검사로
지정하기 전에 적용 범위와 런타임을 검토하세요.
API key 처리와 샌드박스 제어에 관한 내용은 비대화형
모드를 참조하세요. 조직에서 Codex
GitHub Action 사용을 허용하는 경우 런타임에 CLI를 설치할 수 있지만,
여전히 플러그인을 먼저 설치하고 Action의 codex-home 입력이
동일한 CODEX_HOME을 가리키도록 해야 합니다.