Verify evalúa. Tu pipeline sigue decidiendo.
Dos pipelines de ejemplo funcionales llaman al CLI local tras tu build y tests, y detienen el pipeline cuando el resultado es FAIL o NO_CONSTA bajo configuración fail-closed.
CONSTRUIR → PROBAR → VERIFY → DECISIÓN → (despliegue: un sistema aparte, no Verify) # integrations/github-actions/verify.yml
name: verify
on: [push]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
working-directory: cli
- name: Run Verify against the build artifact
working-directory: cli
run: |
node bin/verify.mjs kernel-evaluate \
--bundle ../artifact/bundle.json \
--pins ../artifact/pins.json \
--json > result.json
- name: Fail closed on FAIL or NO_CONSTA
run: |
status=$(node -e "console.log(require('./cli/result.json').result.security_assessment_status)")
echo "status=$status"
if [ "$status" != "PASS" ]; then
echo "::error::Verify status is $status, stopping the pipeline."
exit 1
fi # integrations/generic-ci/verify.sh
set -euo pipefail
node cli/bin/verify.mjs kernel-evaluate \
--bundle "$ARTIFACT_BUNDLE" --pins "$ARTIFACT_PINS" --json > result.json
status=$(node -e "console.log(require('./result.json').result.security_assessment_status)")
if [ "$status" != "PASS" ]; then
echo "Verify status is $status — refusing to continue." >&2
exit 1
fi
echo "Verify: PASS. Continuing pipeline." Ningún ejemplo incrusta secretos, y ninguno hace push a un remoto ni realiza un despliegue.
Cómo decide de verdad una puerta de pipeline.
Cómo funciona esto
- 01
Tu build produce el expediente y sus pins
Verify no los crea. Tu pipeline declara qué construyó y qué espera, y entrega ambos.
- 02
La puerta evalúa y reporta tres cosas
Si el expediente es interpretable, qué muestra la evidencia, y — siempre — que no se concede ningún permiso.
- 03
El pipeline lee el resultado, no el código de salida
Un cero significa que el expediente se pudo leer. Los scripts de ejemplo leen security_assessment_status y record_valid antes de decidir nada.
- 04
Se detiene igual ante FAIL que ante NO_CONSTA
Una respuesta desfavorable y una irresoluble paran el pipeline por igual. La ausencia de evidencia no se toma por evidencia de seguridad.
Paso a paso
-
Copia integrations/generic-ci/verify.sh a tu pipeline.
Verás un script que necesita dos rutas: tu expediente y tus pins.
Eso significa se encaja después de tus tests, antes de lo que publique las cosas.
-
Ejecútalo una vez a mano con un ejemplo que pase.
Verás Verify: PASS, y el pipeline continúa.
Eso significa la puerta está bien conectada.
-
Ejecútalo otra vez apuntando al ejemplo UNFAVOURABLE_RESULT.
Verás se niega y sale con código distinto de cero.
Eso significa tu pipeline ya se detendrá ante una mala respuesta en lugar de publicarla.