Executar o Codex Security em CI
Analise alterações de pull requests e merge requests, preserve resultados estruturados, carregue SARIF e defina uma política de gravidade.
Execute a CLI do Codex Security em CI para rever as alterações exatas num pull request ou merge request, conservar as conclusões e a cobertura e, opcionalmente, fazer a verificação falhar a partir de uma gravidade escolhida. Comece com resultados consultivos, reveja a qualidade e o tempo de execução da análise e, em seguida, adicione uma política de gravidade adequada ao seu repositório.
Este guia inclui exemplos para GitHub Actions e GitLab CI/CD. Os mesmos comandos de análise e exportação funcionam noutros sistemas de CI.
Preparar o fluxo de trabalho
Guarde uma API key da OpenAI no armazenamento de segredos do seu fornecedor de CI como
CODEX_SECURITY_API_KEY.
Mapeie este segredo diretamente para a variável de ambiente OPENAI_API_KEY
do passo de análise. Restrinja a credencial ao processo de análise e utilize
--auth api-key para a selecionar explicitamente.
O executor necessita de:
- Node.js 22 ou posterior.
- Python 3.10 ou posterior.
- O pacote
@openai/codex-securitypublicado, instalado fora da cópia de trabalho do repositório. - O histórico da cabeça e da base do pull request ou merge request para que o Git possa calcular a base de intercalação.
Adicionar o fluxo de trabalho do GitHub Actions
Para repositórios privados ou internos, ative o GitHub Code Security antes de carregar SARIF.
Crie .github/workflows/codex-security.yml. Antes de obter o pull
request, instale @openai/codex-security em
$RUNNER_TEMP/codex-security para que o executável fidedigno esteja disponível em
$RUNNER_TEMP/codex-security/node_modules/.bin/codex-security:
name: Codex Security scan
on:
pull_request:
jobs:
codex-security:
if: github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]'
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Set up Node.js
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7
with:
node-version: "26"
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7
with:
python-version: "3.14"
- name: Install Codex Security
run: |
set -euo pipefail
npm install \
--prefix "$RUNNER_TEMP/codex-security" \
--ignore-scripts \
--no-audit \
--no-fund \
@openai/codex-security
- name: Verify Codex Security
env:
CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security
run: |
set -euo pipefail
test -x "$CODEX_SECURITY_BIN"
"$CODEX_SECURITY_BIN" --version
- name: Check out the pull request
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
persist-credentials: false
- name: Scan the pull request
env:
OPENAI_API_KEY: ${{ secrets.CODEX_SECURITY_API_KEY }}
CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security
CODEX_SECURITY_STATE_DIR: ${{ runner.temp }}/codex-security-state
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
SCAN_DIR: ${{ runner.temp }}/codex-security-results
run: |
set -euo pipefail
BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_SHA")"
"$CODEX_SECURITY_BIN" scan . \
--diff "$BASE_REVISION" \
--head "$HEAD_SHA" \
--auth api-key \
--output-dir "$SCAN_DIR" \
--json > "$RUNNER_TEMP/codex-security.json"
- name: Export SARIF
id: export-sarif
if: always()
env:
CODEX_SECURITY_BIN: ${{ runner.temp }}/codex-security/node_modules/.bin/codex-security
SCAN_DIR: ${{ runner.temp }}/codex-security-results
SARIF_FILE: ${{ runner.temp }}/codex-security.sarif
run: |
set -euo pipefail
if test -f "$SCAN_DIR/scan-manifest.json"; then
"$CODEX_SECURITY_BIN" export "$SCAN_DIR" \
--export-format sarif \
--source-root "$GITHUB_WORKSPACE" \
--output "$SARIF_FILE"
echo "available=true" >> "$GITHUB_OUTPUT"
fi
- name: Upload SARIF
if: always() && steps.export-sarif.outputs.available == 'true'
uses: github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # v4
with:
sarif_file: ${{ runner.temp }}/codex-security.sarif
ref: refs/pull/${{ github.event.pull_request.number }}/head
sha: ${{ github.event.pull_request.head.sha }}
category: codex-security
- name: Preserve scan results
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: codex-security-results
path: |
${{ runner.temp }}/codex-security-results
${{ runner.temp }}/codex-security.json
if-no-files-found: warn
retention-days: 7O fluxo de trabalho obtém a cabeça do pull request, calcula a respetiva base de intercalação e
analisa as alterações consolidadas entre essas revisões. O histórico completo mantém o
alvo exato. persist-credentials: false mantém o token do repositório fora da
configuração do Git da cópia de trabalho. Instalar a CLI antes da obtenção e
executá-la através do caminho absoluto mantém os executáveis controlados pelo repositório afastados da
credencial de análise. --auth api-key seleciona explicitamente a API key restrita.
A análise guarda o respetivo histórico num diretório de estado gravável fora do
repositório.
--json escreve um documento JSON completo em stdout, para que o fluxo de trabalho o possa guardar
diretamente. O progresso, os resumos de conclusão e os erros permanecem em stderr. Isto
difere de codex exec --json, que emite um fluxo de eventos JSON Lines.
O passo de exportação lê uma análise concluída e selada e escreve SARIF. Não altera o runtime nem as credenciais do Codex. Os artefactos de análise podem conter excertos de código-fonte vulnerável, provas e detalhes de correção. Escolha controlos de acesso e um período de retenção curto adequados ao seu repositório.
Adicionar o pipeline do GitLab CI/CD
O GitLab pode ingerir
relatórios SARIF 2.1.0
no GitLab Ultimate 19.2 ou posterior. Adicione uma variável de CI/CD
CODEX_SECURITY_API_KEY mascarada e oculta antes de executar o pipeline.
Adicione a fase security e a tarefa do Codex Security ao .gitlab-ci.yml raiz.
Mantenha quaisquer fases e tarefas existentes no ficheiro. Por predefinição, o exemplo analisa as alterações
do merge request. Defina CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH como "true"
para analisar também o ramo predefinido completo:
variables:
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH: "false"
stages:
- test
- security
codex-security:
stage: security
image: node:26-bookworm-slim
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_SOURCE_PROJECT_ID == $CI_PROJECT_ID'
variables:
CODEX_SECURITY_SCAN_SCOPE: "diff"
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH == "true"'
variables:
CODEX_SECURITY_SCAN_SCOPE: "full"
variables:
GIT_DEPTH: "0"
CODEX_SECURITY_CLI_DIR: "/tmp/codex-security-cli"
before_script:
- |
set -eu
apt-get update -qq
apt-get install -y -qq --no-install-recommends \
ca-certificates \
git \
python3 \
ripgrep
npm install \
--prefix "$CODEX_SECURITY_CLI_DIR" \
--ignore-scripts \
--no-audit \
--no-fund \
@openai/codex-security
export CODEX_SECURITY_BIN="$CODEX_SECURITY_CLI_DIR/node_modules/.bin/codex-security"
test -x "$CODEX_SECURITY_BIN"
"$CODEX_SECURITY_BIN" --version
script:
- |
set -eu
if test -z "${CODEX_SECURITY_API_KEY:-}"; then
echo "Set the CODEX_SECURITY_API_KEY CI/CD variable." >&2
exit 2
fi
codex_security_api_key="$CODEX_SECURITY_API_KEY"
unset CODEX_SECURITY_API_KEY
case "${CODEX_SECURITY_SCAN_SCOPE:-}" in
diff)
BASE_SHA="$CI_MERGE_REQUEST_DIFF_BASE_SHA"
HEAD_SHA="$CI_COMMIT_SHA"
BASE_REVISION="$(git merge-base "$BASE_SHA" "$HEAD_SHA")"
set -- --diff "$BASE_REVISION" --head "$HEAD_SHA"
echo "Scanning committed changes from $BASE_REVISION to $HEAD_SHA."
;;
full)
set -- --mode standard
echo "Scanning the complete default branch at $CI_COMMIT_SHA."
;;
*)
echo "Unsupported Codex Security scan scope: ${CODEX_SECURITY_SCAN_SCOPE:-unset}" >&2
exit 2
;;
esac
export CODEX_SECURITY_STATE_DIR="/tmp/codex-security-state-$CI_JOB_ID"
SCAN_DIR="/tmp/codex-security-results-$CI_JOB_ID"
JSON_FILE="/tmp/codex-security-$CI_JOB_ID.json"
SARIF_FILE="/tmp/codex-security-$CI_JOB_ID.sarif"
install -d -m 700 "$CODEX_SECURITY_STATE_DIR" "$SCAN_DIR"
set +e
OPENAI_API_KEY="$codex_security_api_key" \
"$CODEX_SECURITY_BIN" scan . \
"$@" \
--auth api-key \
--output-dir "$SCAN_DIR" \
--json > "$JSON_FILE"
scan_exit="$?"
set -e
unset codex_security_api_key
install -d -m 700 codex-security-artifacts/results
cp -R "$SCAN_DIR"/. codex-security-artifacts/results/
if test -s "$JSON_FILE"; then
cp "$JSON_FILE" codex-security-artifacts/codex-security.json
fi
printf '%s\n' "$scan_exit" > codex-security-artifacts/scan-exit-code.txt
export_exit=0
if test -f "$SCAN_DIR/scan-manifest.json"; then
set +e
"$CODEX_SECURITY_BIN" export "$SCAN_DIR" \
--export-format sarif \
--source-root "$CI_PROJECT_DIR" \
--output "$SARIF_FILE"
export_exit="$?"
set -e
if test -s "$SARIF_FILE"; then
cp "$SARIF_FILE" codex-security-artifacts/codex-security.sarif
fi
fi
if test "$scan_exit" -ne 0; then
exit "$scan_exit"
fi
exit "$export_exit"
artifacts:
when: always
access: maintainer
expire_in: 7 days
paths:
- codex-security-artifacts/
reports:
sarif: codex-security-artifacts/codex-security.sarifPor predefinição, a tarefa é executada apenas para merge requests provenientes de ramos do mesmo
projeto, pelo que os pipelines de forks não recebem a credencial de análise. Defina
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH como "true" ao nível do grupo, projeto ou
pipeline para executar também uma análise completa normal no ramo predefinido. As análises
completas demoram mais tempo e custam mais do que as análises de diferenças.
GIT_DEPTH: "0" fornece o histórico necessário para calcular a base de intercalação a partir de
CI_MERGE_REQUEST_DIFF_BASE_SHA e CI_COMMIT_SHA nas análises de merge requests.
A tarefa instala a CLI em /tmp, executa-a através do caminho absoluto e expõe a
API key apenas ao processo de análise. artifacts: when: always preserva o relatório
SARIF quando a análise falha, enquanto artifacts:access: maintainer limita o acesso
a resultados detalhados da análise.
As alterações a .gitlab-ci.yml podem expor variáveis de CI/CD, pelo que deve rever as alterações
do pipeline antes de executar a tarefa. Se
proteger CODEX_SECURITY_API_KEY,
o GitLab disponibiliza-a apenas para merge requests do mesmo projeto entre
ramos protegidos e apenas quando o utilizador pode aceder ao ramo de destino.
Escolher uma política de gravidade
Ambos os exemplos apenas produzem relatórios porque omitem --fail-on-severity. Quando
estiver preparado para que as conclusões afetem a verificação, adicione um limiar ao comando
de análise:
"$CODEX_SECURITY_BIN" scan . \
--diff origin/main \
--output-dir /path/outside/repository/results \
--fail-on-severity highOs limiares suportados são critical, high, medium e low. Um
limiar inclui conclusões dessa gravidade e superiores.
O passo de análise utiliza estes códigos de saída:
| Saída | Significado |
|---|---|
0 |
A análise foi concluída com cobertura completa e qualquer política configurada foi satisfeita. |
1 |
A análise concluída contém uma conclusão com gravidade igual ou superior ao limiar. |
2 |
A CLI encontrou um erro de entrada ou de runtime, ou a análise concluída tem cobertura incompleta. |
130 |
Ctrl-C interrompeu a análise. |
143 |
SIGTERM terminou a análise. |
Uma análise com cobertura partial ou unknown devolve 2, mesmo sem uma política de
gravidade. A CLI continua a escrever as conclusões e a cobertura disponíveis. Reveja as
áreas adiadas em coverage.json antes de considerar a verificação conclusiva.
Repetir com um diretório de resultados existente
Utilize um diretório de executor novo para cada tarefa de CI. Num executor persistente ou autoalojado,
preserve um resultado anterior com --archive-existing:
"$CODEX_SECURITY_BIN" scan . \
--diff origin/main \
--output-dir /path/outside/repository/results \
--archive-existingO comando arquiva os resultados anteriores e começa com um diretório de análise vazio.
Resolver problemas de uma análise em CI
- Referência Git desconhecida ou diferença inesperada: Obtenha o histórico da base e da cabeça, calcule a base de intercalação e forneça explicitamente ambas as revisões.
- Diretório de saída protegido ou não vazio: Escolha um diretório privado
fora da árvore de trabalho Git envolvente. Utilize
--archive-existingquando o diretório já contiver resultados. - Credenciais em falta: Confirme que
CODEX_SECURITY_API_KEYestá disponível para o fluxo de trabalho ou pipeline fidedigno e diretamente mapeada para a variável de ambienteOPENAI_API_KEYdo processo de análise. - Erro no histórico da análise: Defina
CODEX_SECURITY_STATE_DIRcomo um diretório gravável fora do repositório. - Erro de configuração do Python: Confirme que o executor utiliza Python 3.10 ou posterior.
- Cobertura incompleta: Reveja
coverage.json, incluindo superfícies adiadas e questões em aberto, e volte a executar com um alvo ou ambiente adequado. - Erro de exportação SARIF: Confirme que a análise foi concluída e que o diretório completo da análise está disponível. A exportação valida os artefactos selados antes de escrever SARIF.
- Erro de carregamento SARIF: Para GitHub Actions, confirme que a sua organização
ativou o GitHub Code Security para o repositório e que o fluxo de trabalho concede
actions: read,contents: readesecurity-events: write. Para GitLab CI/CD, confirme que o projeto utiliza GitLab Ultimate 19.2 ou posterior e que a tarefa carrega um ficheiro SARIF 2.1.0 através deartifacts:reports:sarif.
Para todos os comandos, sinalizadores, artefactos e campos de saída, consulte a referência da CLI. Para uma revisão interativa de CI baseada em plugins, consulte Rever alterações de código quanto à segurança.