Ir al contenido

Los artefactos .sei/*

✅ Estable

El directorio .sei/ del repositorio contiene los artefactos de evidencia firmados que el motor escribe tras ejecutar los subcomandos correspondientes. Cada artefacto es un fichero JSON en un sobre versionado (SeiArtifact<T>) acompañado de un fichero de firma (.sig). La plataforma cloud lee estos ficheros desde el repositorio y los verifica antes de renderizar cualquier informe.


Todos los artefactos .sei/* siguen el mismo contrato de envelope definido en crates/seigarrena-core/src/sei_artifact.rs. El sobre es un wrapper versionado con serialización determinista (sin timestamps, orden de campos estable):

Forma del envelope SeiArtifact<T>
{
"schema_version": 1,
"kind": "conformance",
"system": "loan",
"payload": { ... }
}
CampoTipo RustDescripción
schema_versionu32Versión incremental del esquema del payload (por tipo de artefacto). Actualmente 1 para todos los tipos.
kindStringTipo de artefacto: "conformance" o "reconstruct".
systemStringNombre del sistema al que pertenece el artefacto (ancla legible; el ancla técnica es la referencia git externa).
payloadTContenido específico del artefacto (varía por kind).

La serialización es determinista (JSON pretty, orden de declaración de campos) — los mismos bytes se firman y se almacenan. No hay timestamps en el envelope; la trazabilidad temporal la aporta el historial git.


Cada artefacto <nombre>.json tiene un fichero hermano <nombre>.json.sig. La firma sigue el mismo esquema que el bundle principal:

  • Algoritmo: ECDSA sobre la curva NIST P-256 con SHA-256, firmas deterministas (RFC 6979); firma en formato crudo r‖s (64 bytes) dentro de un sobre DSSE (Dead Simple Signing Envelope)
  • Statement: in-toto Statement v1 (tipo https://in-toto.io/Statement/v1)
  • Payload canónico: JCS (RFC 8785) para determinismo byte-a-byte
  • Subject: SHA-256 de los bytes del artefacto — vincula firma y contenido
  • keyid: hex(SHA-256(pubkey SEC1 sin comprimir, 65 B)) — identifica la clave verificadora sin transportarla

El backend de firma es enchufable (variable de entorno SEI_SIGNING_BACKEND): local (escalar EC P-256 de 32 bytes en hex en SEI_SIGNING_KEY; sin él, escalar de desarrollo fijo, solo integridad, sin no-repudio) o scaleway-kms (firma delegada al Scaleway Key Manager, alg EC-P256-SHA256; la clave privada nunca sale del KMS). sei pubkey exporta la pubkey verificadora (SEC1, 65 B hex) para registrarla en la nube por conexión (ScmConnection.signerPubkey).

Ver Firmar y verificar evidencia para el flujo completo y el estado actual de la cadena de confianza.


Fichero .sei/FirmaComando que lo escribeFlag requeridokind
bundle.jsonbundle.json.sigsei run(siempre)(bundle, no SeiArtifact)
reconstruct.jsonreconstruct.json.sigsei reconstruct--out"reconstruct"
conformance/<slug>.jsonconformance/<slug>.json.sigsei conformance--out"conformance"

bundle.json no usa el envelope SeiArtifact<T>: es un EvidenceBundle firmado directamente. Es el artefacto central que los demás referencian. Su firma se verifica con sei verify.

El slug del fichero de conformidad se genera a partir del id del estándar reemplazando / y @ por _:

eu/pren-18228@2026 → .sei/conformance/eu_pren-18228_2026.json
iso/23894@2023 → .sei/conformance/iso_23894_2023.json

Esta transformación la realiza la función standard_slug en sei_artifact.rs.


La función write_sei_artifact en crates/seigarrena-cli/src/util/artifact.rs sigue este patrón para todos los artefactos:

Patrón de escritura (de util/artifact.rs)
// 1. Construir el envelope
let art = SeiArtifact::new(1, "conformance", &system, payload);
// 2. Serializar a JSON determinista
let json = artifact.to_json()?;
// 3. Firmar los bytes (ECDSA-P256; el backend lo elige SEI_SIGNING_BACKEND
// internamente vía signer_from_env: LocalSigner o ScalewayKmsSigner)
let proof = EcdsaDsseSigner.sign(json.as_bytes())?;
// 4. Escribir <rel>.json y <rel>.json.sig
std::fs::write(&path, &json)?;
std::fs::write(sig_path, &proof)?;

Los subdirectorios se crean automáticamente (p. ej. .sei/conformance/ para los informes de conformidad).


La plataforma cloud (TypeScript, cloud/lib/sei/) reproduce la verificación de sei verify sin llamar al CLI:

  1. Lee los bytes del artefacto (.json) y la firma (.sig).
  2. Parsea el sobre DSSE e in-toto Statement del fichero .sig.
  3. Verifica la firma ECDSA-P256 (raw r‖s) sobre el PAE (Pre-Authentication Encoding DSSE) con @noble/curves.
  4. Comprueba que el keyid del sobre coincide con hex(SHA-256(pubkey SEC1)) de la pubkey esperada de ESA conexión (ScmConnection.signerPubkey), de forma fail-loud: sin pubkey registrada, la nube no verifica en silencio sino que falla.
  5. Verifica que el subject.sha256 del Statement coincide con el SHA-256 de los bytes del artefacto.

La nube no calcula evidencia: solo lee y verifica lo que el motor ha committeado. La fuente de verdad es siempre el repositorio git.

Verificar la firma del bundle desde el CLI
sei verify --repo /ruta/al/proyecto

sei compile → genera oscal.assessment_plan (no es un SeiArtifact)
sei run → escribe .sei/bundle.json + bundle.json.sig
sei reconstruct --out → escribe .sei/reconstruct.json + .sig
sei conformance --out → escribe .sei/conformance/<slug>.json + .sig
[git commit -A .sei/] → los artefactos quedan versionados y trazables

Los artefactos no se commitean automáticamente; el commit es un acto humano deliberado que constituye el “poner en mercado” del estado de conformidad.

Ver también: Referencia del CLI sei, Firmar y verificar evidencia.