Ejecuta Codex Security en GitLab CI/CD para analizar los cambios registrados en commits y las ramas protegidas, publicar hallazgos en GitLab Security y, si lo deseas, proponer correcciones verificadas en borradores de solicitudes de fusión.
El flujo de trabajo mantiene las credenciales de análisis separadas del acceso de escritura al repositorio. Los cambios generados siempre requieren revisión humana antes de fusionarse.
Empieza por generar solo informes de análisis. Habilita la corrección automática solo después de revisar el runner, los hallazgos y el alcance de las credenciales de tu proyecto.
Antes de empezar
Necesitas:
- Un proyecto de GitLab con un runner de confianza compatible con el espacio de nombres de usuario del sandbox de Codex.
- El rol Maintainer u Owner en el proyecto de GitLab para configurar las variables de CI/CD del proyecto y los recursos protegidos.
- Una clave de API de OpenAI con acceso a Codex Security. Las organizaciones que usan claves de API de la plataforma pueden solicitar Trusted Access for Cyber. Quienes se autentican con ChatGPT pueden usar el proceso de Trusted Access para particulares. Algunas cuentas o repositorios requieren este acceso para analizar todo el repositorio.
- GitLab Ultimate 19.2 o posterior para la importación de informes SARIF 2.1.0.
- El historial completo de Git para que los trabajos de las solicitudes de fusión puedan calcular la base de fusión.
La imagen del pipeline instala Node.js 26, Python 3, Git, rg y la versión fijada de la CLI de Codex Security. La corrección automática también requiere una prueba de regresión existente y un runner que pueda ejecutar comandos definidos por el repositorio sin credenciales protegidas.
Empieza con un pipeline que solo ejecute análisis
Crea una variable de CI/CD de GitLab enmascarada, oculta y protegida llamada CODEX_SECURITY_API_KEY. Usa una clave de API de la plataforma de OpenAI con acceso a Codex Security y limita su alcance al entorno codex-security/openai. Consulta la documentación sobre variables de CI/CD con alcance limitado a un entorno.
Agrega primero este pipeline a un proyecto de prueba. Analiza los cambios registrados en commits de las solicitudes de fusión protegidas que cumplen los requisitos, publica el informe SARIF si el trabajo que lo genera finaliza correctamente y recupera el resultado del análisis en un control de políticas independiente:
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:
- apt-get update -qq
- apt-get install -y -qq --no-install-recommends ca-certificates git python3 ripgrep
- npm install --prefix /tmp/codex-security-cli --ignore-scripts --no-audit --no-fund @openai/codex-security@0.8.1
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" \
--fail-on-severity high \
--json
scan_exit="$?"
set -e
unset codex_security_api_key
case "$scan_exit" in
0|1) ;;
*) 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)"
Revisa cada cambio en .gitlab-ci.yml antes de ejecutar un trabajo con acceso a secretos. Este ejemplo omite los análisis completos y la corrección automática.
Adopta el pipeline de producción
- Descarga el pipeline completo de GitLab y guárdalo como
.gitlab-ci.ymlen la raíz del repositorio. Si tu repositorio ya tiene un pipeline, incorpora las etapas, las plantillas ocultas y los trabajos del ejemplo al archivo existente. - Conserva las etapas de compilación, prueba y despliegue existentes. Si el proyecto usa
workflow: rules, confirma que permita ejecutar el pipeline para los eventos que quieres analizar.
El ejemplo agrega las etapas security_scan, security_remediation, security_publish y security_gate. Para generar solo informes de análisis, basta con configurar CODEX_SECURITY_API_KEY.
De forma predeterminada, el trabajo de análisis solo se ejecuta para solicitudes de fusión entre ramas protegidas del mismo proyecto. Configura CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH=true para ejecutar análisis cuando se envíen cambios a la rama predeterminada protegida o se inicie un pipeline manual en esa rama. Configura CODEX_SECURITY_SCHEDULED_DEEP_SCAN=true y establece presupuestos explícitos de tiempo y costo para habilitar los análisis profundos programados en la rama predeterminada protegida.
El pipeline de una solicitud de fusión solo puede acceder a las variables y los runners protegidos si se cumplen estas condiciones:
- Proteges las ramas de origen y destino en el mismo proyecto.
- El proyecto permite que los pipelines de solicitudes de fusión accedan a las variables y los runners protegidos.
- El usuario que inicia el pipeline puede enviar o fusionar cambios en la rama de destino.
Los pipelines de forks y las solicitudes de fusión sin protección no reciben la credencial de análisis. Revisa cada cambio en .gitlab-ci.yml antes de ejecutar un trabajo con acceso a secretos. Enmascarar y ocultar una variable no hace que sea seguro ejecutar código de CI que no es de confianza.
Ejecuta un análisis y revisa los hallazgos
Crea una solicitud de fusión protegida que cumpla los requisitos o ejecuta el pipeline en la rama predeterminada protegida. Empieza con un conjunto pequeño de cambios antes de ejecutar un análisis de pago de todo el repositorio.
Abre el trabajo codex-security y confirma que sus artefactos incluyan:
results/scan-manifest.jsonresults/findings.jsonresults/report.mdresults.sarifscan-exit-code.txt
Luego abre la pestaña Security del pipeline, revisa las advertencias de importación y confirma los identificadores de los hallazgos, sus niveles de gravedad y sus ubicaciones en el código fuente. Los análisis de la rama predeterminada también crean registros de vulnerabilidades del proyecto. Los hallazgos de las solicitudes de fusión aparecen en la pestaña Security del pipeline o en el widget de seguridad de la solicitud, pero no generan registros de vulnerabilidades a nivel de proyecto.
Restringe el acceso a los artefactos porque los resultados del análisis pueden contener fragmentos de código fuente vulnerable, evidencias y detalles sobre cómo corregir las vulnerabilidades.
Elige un perfil de análisis
El pipeline selecciona un perfil según el evento que lo activa:
| Evento | Objetivo | Modo | Esfuerzo |
|---|---|---|---|
| Solicitud de fusión entre ramas protegidas del mismo proyecto | Diferencias entre commits | standard |
low |
| Envío de cambios a la rama predeterminada protegida o ejecución manual en esa rama, si se habilita | Repositorio completo | standard |
high |
| Ejecución programada en la rama predeterminada protegida, si se habilita | Repositorio completo | deep |
xhigh |
Los análisis de solicitudes de fusión se centran en los cambios registrados en los commits de la solicitud. Los análisis de la rama predeterminada revisan el repositorio con los cambios ya integrados. Los análisis profundos programados ofrecen una cobertura periódica más amplia. Un análisis de diferencias completado solo se aplica al cambio analizado y no demuestra que todo el repositorio esté libre de problemas.
El flujo de trabajo instala la CLI fuera del repositorio y la ejecuta mediante su ruta absoluta. La comprobación preliminar en modo de simulación usa la clave de API limitada al proceso, pero no inicia un análisis de pago ni verifica la autenticación de la API, el acceso a Codex Security, la cuota o la disponibilidad del modelo.
El flujo de trabajo guarda el estado y los resultados del análisis fuera del worktree y limita OPENAI_API_KEY al proceso de análisis. La CLI recibe un entorno reducido definido explícitamente en lugar de heredar todas las variables de GitLab. Para los análisis de diferencias, el flujo de trabajo calcula la base de fusión y limita el análisis a los cambios entre las dos revisiones que se sometieron a revisión: la base y el último commit de la rama de origen.
El ejemplo fija la versión de @openai/codex-security en 0.8.1. Antes de cambiar la versión, vuelve a probar la autenticación, los artefactos, la importación de SARIF y el control de políticas.
Separa la generación de informes de la aplicación de políticas
GitLab importa el informe SARIF cuando el trabajo que lo genera finaliza correctamente. El pipeline publica primero el informe y recupera el código de salida del analizador en un trabajo independiente llamado codex-security-gate.
El trabajo de generación de informes solo exporta los hallazgos si el código de salida es 0 o 1. Con cualquier otro código de salida, se omite la exportación a SARIF y se bloquea el pipeline. Si la exportación falla, también se bloquea el pipeline.
El trabajo de generación de informes propaga los errores de ejecución y las interrupciones. Si finaliza correctamente, el control final recupera el resultado que devolvió el analizador al evaluar la política:
| Código de salida | Significado |
|---|---|
0 |
El análisis se completó y cumplió la política. |
1 |
El análisis se completó y detectó un problema cuya gravedad alcanza o supera el umbral configurado. |
2 |
Se produjo un error en la entrada, la ejecución, la integridad del objetivo o la salida requerida del análisis. |
130 / 143 |
El análisis se interrumpió o se terminó mediante una señal. |
El ejemplo usa --fail-on-severity high, por lo que el control falla si hay hallazgos de gravedad alta o crítica. Sin un umbral de gravedad, los análisis completados devuelven 0 de forma predeterminada. En results/scan-manifest.json, consulta scan.scope para conocer el alcance configurado y scan.review.excludedPaths para ver las rutas excluidas de las comparaciones de hallazgos. Consulta results/report.md para conocer las tareas de seguimiento.
La corrección automática y la publicación se ejecutan antes del control final de políticas. Un hallazgo que cumpla los requisitos puede dar lugar a un borrador de solicitud de fusión con una corrección verificada, incluso si el control bloquea el pipeline más adelante.
Habilita las correcciones verificadas
La corrección automática es opcional y solo se ejecuta en los pipelines de la rama predeterminada protegida. Ni el proceso de corrección de Codex ni los comandos de verificación definidos por el repositorio reciben el token de acceso al proyecto de GitLab ni las credenciales que inyecta el runner.
El flujo de trabajo sigue estos pasos:
- Requiere el archivo de manifiesto de un análisis completado para la revisión actual y un hallazgo de gravedad
highocritical. - Confirma que la prueba de regresión configurada falle antes de aplicar el parche.
- Genera un parche y rechaza cambios en archivos de CI, de credenciales, binarios u otros archivos protegidos.
- Ejecuta la prueba de regresión sin credenciales de OpenAI, GitLab, registro o despliegue y sin tokens de trabajo.
- Usa
verify-fixpara devolverfixed,still_vulnerableoinconclusive. El trabajo solo publica un parche cuandoverify-fixdevuelvefixedy el proceso de verificación deja el parche intacto.
Configura estas variables protegidas para habilitar la corrección automática:
- Establece
CODEX_SECURITY_ENABLE_REMEDIATIONentrue. - Asigna a
CODEX_SECURITY_VERIFICATION_COMMANDel comando de una prueba de regresión existente que devuelva1antes de la corrección y0después. - Si lo deseas, asigna a
CODEX_SECURITY_SETUP_COMMANDun comando no interactivo para configurar las dependencias.
Elige una prueba de regresión que compruebe la condición de seguridad que siempre debe cumplirse, independientemente de la implementación. Revisa con el mismo rigor los cambios generados en las pruebas y en el código fuente.
Configuración avanzada: aislamiento de los comandos del repositorio
Los comandos validate, patch y verify-fix reciben una clave OPENAI_API_KEY limitada al proceso y usan --auth api-key. Los comandos de configuración y prueba definidos por el repositorio se ejecutan con una cuenta de usuario independiente sin privilegios, en una copia con permisos de escritura de los archivos fuente bajo control de versiones. La copia excluye los metadatos de Git, el contenido de los submódulos y los artefactos descargados. Los comandos de configuración y prueba que requieren .git o submódulos deben ejecutarse en un trabajo independiente diseñado para funcionar sin credenciales.
Solo los pasos de Codex que pertenecen al usuario root pueden acceder a la copia de trabajo canónica o al directorio contiguo donde GitLab guarda las variables de tipo archivo. El entorno limpio de la copia solo contiene PATH, HOME, LANG, CI y CI_PROJECT_DIR. Si un comando necesita otro valor que no sea secreto, agrégalo a la lista de valores permitidos después de revisar el comando. Si tu runner no puede cambiar de usuario, mueve la verificación a un trabajo independiente sin credenciales antes de habilitar la corrección automática.
Publica un borrador de solicitud de fusión
Crea un token de acceso al proyecto de GitLab con el rol Developer y los alcances api y write_repository. Guárdalo en la variable protegida, enmascarada y oculta GITLAB_REMEDIATION_TOKEN, con alcance limitado al entorno codex-security/publish.
Configura CODEX_SECURITY_CREATE_MR=true para habilitar la publicación. Asigna también a la variable no secreta CODEX_SECURITY_MR_TEST_COMMAND el comando de la prueba de regresión de seguridad específica del proyecto que debe pasar cada rama de corrección generada. Deja esta variable sin protección para que la solicitud de fusión generada, que no está protegida, pueda leer el comando. El flujo de publicación funciona así:
- Recibe el token con permiso de escritura en el repositorio, pero ninguna credencial de OpenAI.
- Crea una rama
codex-security/fix-<finding-hash>. - Abre un borrador de solicitud de fusión. Si ya hay un borrador abierto, lo reutiliza para evitar duplicados.
- Ejecuta la prueba de regresión de la rama de corrección sin protección como usuario sin privilegios, en una copia que solo contiene archivos bajo control de versiones y sin credenciales protegidas.
- Nunca fusiona automáticamente el cambio generado.
No uses CI_JOB_TOKEN en lugar del token de acceso al proyecto. No permite crear la solicitud de fusión requerida. Revisa el parche propuesto, la evidencia de la verificación y el hallazgo antes de fusionar los cambios.
Configura las variables opcionales
Configura solo las variables que requieran las funciones que habilites:
| Variable | Cuándo se necesita | Valor predeterminado o finalidad |
|---|---|---|
CODEX_SECURITY_API_KEY |
En cada análisis | Protegida, enmascarada y oculta. Limita su alcance a codex-security/openai |
CODEX_SECURITY_VERSION |
Al actualizar la CLI | Versión fijada en 0.8.1. Repite las pruebas antes de cambiarla |
CODEX_SECURITY_FULL_SCAN_DEFAULT_BRANCH |
Análisis completos de la rama predeterminada | Requiere activación explícita. Desactivada de forma predeterminada |
CODEX_SECURITY_SCHEDULED_DEEP_SCAN |
Análisis profundos programados | Requiere activación explícita. Desactivada de forma predeterminada |
CODEX_SECURITY_DEEP_MAX_TIME_MINUTES |
Análisis profundos programados | Presupuesto obligatorio en minutos, mayor que 0 y menor que 480 |
CODEX_SECURITY_DEEP_MAX_COST |
Análisis profundos programados | Límite obligatorio de costo estimado en USD, mayor que 0 |
CODEX_SECURITY_ENABLE_REMEDIATION |
Generación de parches | Activación explícita mediante una variable protegida. Desactivada de forma predeterminada |
CODEX_SECURITY_VERIFICATION_COMMAND |
Generación de parches | Prueba de regresión configurada mediante una variable protegida |
CODEX_SECURITY_SETUP_COMMAND |
Configuración opcional para la corrección | Instalación de dependencias configurada mediante una variable protegida |
CODEX_SECURITY_REMEDIATION_EFFORT |
Ajuste opcional del esfuerzo de corrección | high |
CODEX_SECURITY_MAX_CHANGED_FILES |
Límite opcional del tamaño del parche | 8. El intervalo permitido va de 1 a 20 |
CODEX_SECURITY_CREATE_MR |
Creación de borradores de solicitudes de fusión | Activación explícita mediante una variable protegida. Desactivada de forma predeterminada |
GITLAB_REMEDIATION_TOKEN |
Creación de borradores de solicitudes de fusión | Token de proyecto con rol Developer y alcance limitado a codex-security/publish |
CODEX_SECURITY_GITLAB_INTERNAL_URL |
Publicación opcional en una instancia autohospedada | Origen de GitLab accesible desde el runner |
CODEX_SECURITY_MR_TEST_COMMAND |
Publicación de borradores de solicitudes de fusión | Prueba de regresión obligatoria y específica del proyecto, configurada sin secretos |
CODEX_SECURITY_MR_SETUP_COMMAND |
Configuración opcional de la rama de corrección | Configuración de dependencias sin secretos |
GitLab proporciona las variables CI_*. El pipeline administra CODEX_SECURITY_BIN, CODEX_SECURITY_EFFORT, CODEX_SECURITY_MODE, CODEX_SECURITY_STATE_DIR y CODEX_SECURITY_TARGET. No las configures como variables del proyecto. Para los análisis de diferencias, la CLI determina la identidad canónica del objetivo a partir de las revisiones normalizadas de ambos extremos de la comparación.
Ajusta los controles y el costo
Usa análisis de diferencias para obtener observaciones sobre las solicitudes de fusión, análisis estándar del repositorio para la rama predeterminada y análisis profundos programados para ampliar la cobertura. Ambos perfiles de análisis del repositorio completo están desactivados de forma predeterminada. Un análisis profundo programado también requiere CODEX_SECURITY_DEEP_MAX_TIME_MINUTES y CODEX_SECURITY_DEEP_MAX_COST. Mantén el presupuesto de tiempo de la CLI por debajo del tiempo máximo de ejecución del trabajo, que es de ocho horas. Cuando adoptes el nuevo YAML, convierte a minutos los valores existentes expresados en horas. Mide ejecuciones representativas antes de fijar un presupuesto. Usa --max-cost como límite de costo estimado, sin asumir que impone un tope estricto a la facturación.
En este ejemplo, el control bloquea el pipeline si hay hallazgos de gravedad alta o crítica. Para los análisis que solo generan informes, elimina --fail-on-severity high. Elige un umbral después de revisar los hallazgos, la cobertura, el costo y el tiempo de ejecución de análisis representativos. Consulta la descripción general de CI/CD para conocer las políticas de gravedad y la referencia de la CLI para obtener más información sobre los códigos de salida.
Si falla un trabajo:
- La falta de artefactos de análisis apunta a un problema de configuración o del runner.
- Si hay exclusiones inesperadas, comprueba el alcance y los detalles de la revisión en
results/scan-manifest.json. - Si faltan hallazgos en GitLab, comprueba si el trabajo de generación del informe SARIF finalizó correctamente y si GitLab aceptó el informe.
- Si se omitió la corrección automática, comprueba la rama protegida, el archivo de manifiesto del análisis, la gravedad del hallazgo, el comando de verificación y las variables de activación.
- Si hay errores de publicación, comprueba el rol del token del proyecto, sus alcances y la restricción de entorno.
Para conocer todos los comandos, las opciones y los artefactos, consulta la referencia de la CLI de Codex Security.