Declaración contrafirmada: crear, verificar, empaquetar

codafort attest crea y verifica la declaración contrafirmada de un scan. Crear requiere el plan Verified o Platform; verificar es gratis y offline.

La declaración (el artefacto coda-attestation/1) afirma: este resultado, en este commit, con este ruleset y esta evidencia, llegó a este veredicto. Cualquiera puede verificarla, sin licencia.

Qué prueba y qué no prueba: prueba la integridad y la autoría del resultado. No prueba ausencia de vulnerabilidades y no sustituye el pentest independiente (Res. CMN 5.274, Art. 22-A); es evidencia complementaria de homologación de proveedores (TPRM). El mismo texto va dentro del paquete que recibe el comprador.

Crear

codafort attest create [ruta] \
  --standard asvs-l2-sast \          # o asvs-l1-sast (default: l2)
  --evidence vet.json \              # coda-evidence/1 de otra herramienta (repetible)
  --evidence iast-ev.json \
  --artifact dist/app.tar.gz \       # SHA-256 calculado aquí: la declaración apunta a la release
  --artifact-digest "ghcr.io/org/app@sha256:<64 hex>"   # digest calculado fuera (imagen OCI)
  --supersedes atestado-anterior.txt # mismo commit y mismo resultado: sucesión

Qué hace el comando:

  1. Escanea la ruta con un perfil fijo (el de scan, sin --rules-dir), para que el ruleset declarado sea el que corrió.
  2. Arma el payload: commit, estándar, veredicto, findings por severidad, evidencias (evidence[]) y artefactos (artifacts[], en forma in-toto).
  3. Contrafirma. Online, envía el payload a codafort, que verifica la licencia (Verified o Platform) y si fue revocada. Sin red (air-gapped), define CODAFORT_ATTEST_KEY (subclave) y CODAFORT_ATTEST_DELEGATION (delegación firmada por la clave raíz): el comando firma localmente y la delegación va en el token, para que attest verify la verifique.

Reglas que el comando aplica sin preguntar:

  • Un --evidence con un archivo que no sea coda-evidence/1 es error.
  • --supersedes exige el mismo commit y el mismo resultado de scan. Un scan distinto es una declaración nueva.
  • --artifact es una declaración del emisor, contrafirmada. No prueba que el build salió de ese código fuente (eso es provenance de build, SLSA L2+); el verificador y el mapa de conformidad lo dicen.
  • Un árbol con cambios sin commit se sella con dirty: true: el commit declarado no describe el código escaneado.

Verificar (gratis, offline)

codafort attest verify <token | archivo | sobre.intoto.json>

Acepta el token (payload.firma) y el sobre DSSE / Statement in-toto. Verifica la firma, el tipo (el formato antiguo codafort-attestation/1 sigue válido) y, en la declaración firmada sin red, la delegación y su vigencia. ¿Sin CLI a mano? La página codafort.com/verify hace la misma verificación en el navegador, sin enviar nada.

Empaquetar

codafort attest bundle [ruta] --standard asvs-l2-sast --evidence … --artifact … \
  --format zip -o codafort-attestation.zip          # cara TPRM / data room
codafort attest bundle … --format in-toto --artifact dist/app.tar.gz \
  -o codafort-attestation.intoto.json              # cara policy-engine (exige --artifact)

El .zip es lo que va a quien evalúa al proveedor: el token, un resumen legible, el COMPLIANCE-MAP.md (estándar, veredicto, commit, digest y modalidades, con lo que prueba y no prueba) y las instrucciones para verificar offline.

La salida in-toto lleva el mismo payload en un sobre DSSE (application/vnd.in-toto+json), con Statement https://in-toto.io/Statement/v1 y predicate https://codafort.com/coda-attestation/v1, para escribir política en Kyverno o en policy-controller.

La regla del veredicto

La regla es fija para cada estándar (--standard), y el .codafort-gate.yaml del repositorio no la cambia. El veredicto es fail cuando el resultado tiene cualquier finding blocker o critical, cualquier vulnerabilidad, o cuando una evidencia IAST trae un finding confirmado en ejecución. unreached y sanitized no cambian el veredicto. Lo que lleva cada evidencia está en La cadena de evidencia.

Flujo completo, de punta a punta

codafort vet --evidence-out vet.json                      # el código de IA fue juzgado
codatrace collect --socket "$SOCK" --static static.json --output laudo-iast.json
codatrace evidence --report laudo-iast.json --coverage coverage.json > iast-ev.json  # contribución IAST
codaprobe evidence --report laudo-dast.json > dast-ev.json  # contribución DAST (del informe del codaprobe scan)
codafort attest bundle --evidence vet.json --evidence iast-ev.json --evidence dast-ev.json \
  --artifact dist/app.tar.gz -o atestado.zip
# del otro lado, sin licencia:
codafort attest verify atestado.zip/token.txt