Los artefactos .froga/*
✅ Estable
El directorio .froga/ 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 (FrogaArtifact<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.
El sobre FrogaArtifact<T>
Sección titulada «El sobre FrogaArtifact<T>»Todos los artefactos .froga/* siguen el mismo contrato de envelope definido en crates/froga-core/src/froga_artifact.rs. El sobre es un wrapper versionado con serialización determinista (sin timestamps, orden de campos estable):
{ "schema_version": 1, "kind": "conformance", "system": "loan", "payload": { ... }}Campos del envelope
Sección titulada «Campos del envelope»| Campo | Tipo Rust | Descripción |
|---|---|---|
schema_version | u32 | Versión incremental del esquema del payload (por tipo de artefacto). Actualmente 1 para todos los tipos. |
kind | String | Tipo de artefacto: "conformance" o "reconstruct". |
system | String | Nombre del sistema al que pertenece el artefacto (ancla legible; el ancla técnica es la referencia git externa). |
payload | T | Contenido 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.
Fichero de firma (.sig)
Sección titulada «Fichero de firma (.sig)»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 FROGA_SIGNING_BACKEND): local (escalar EC P-256 de 32 bytes en hex en FROGA_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). froga 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.
Tabla de artefactos
Sección titulada «Tabla de artefactos»Fichero .froga/ | Firma | Comando que lo escribe | Flag requerido | kind |
|---|---|---|---|---|
bundle.json | bundle.json.sig | froga run | (siempre) | (bundle, no FrogaArtifact) |
reconstruct.json | reconstruct.json.sig | froga reconstruct | --out | "reconstruct" |
conformance/<slug>.json | conformance/<slug>.json.sig | froga conformance | --out | "conformance" |
risk-projection/<slug>.json | risk-projection/<slug>.json.sig | froga risk-projection | (siempre, bajo demanda) | "risk-projection" |
Notas sobre el bundle principal
Sección titulada «Notas sobre el bundle principal»bundle.json no usa el envelope FrogaArtifact<T>: es un EvidenceBundle firmado directamente. Es el artefacto central que los demás referencian. Su firma se verifica con froga verify.
Slug de conformidad
Sección titulada «Slug de conformidad»El slug del fichero de conformidad se genera a partir del id del estándar reemplazando / y @ por _:
eu/pren-18228@2026 → .froga/conformance/eu_pren-18228_2026.jsoniso/23894@2023 → .froga/conformance/iso_23894_2023.jsonEsta transformación la realiza la función standard_slug en froga_artifact.rs.
Slug de proyección de riesgo
Sección titulada «Slug de proyección de riesgo»El slug del fichero de proyección de riesgo se genera a partir del id del marco de la misma forma:
iso/14971@2019 → .froga/risk-projection/iso_14971_2019.jsoneu/pren-18228@2026 → .froga/risk-projection/eu_pren-18228_2026.jsoniso/23894@2023 → .froga/risk-projection/iso_23894_2023.jsonCómo los escribe el CLI
Sección titulada «Cómo los escribe el CLI»La función write_froga_artifact en crates/froga-cli/src/util/artifact.rs sigue este patrón para todos los artefactos:
// 1. Construir el envelopelet art = FrogaArtifact::new(1, "conformance", &system, payload);
// 2. Serializar a JSON deterministalet json = artifact.to_json()?;
// 3. Firmar los bytes (ECDSA-P256; el backend lo elige FROGA_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.sigstd::fs::write(&path, &json)?;std::fs::write(sig_path, &proof)?;Los subdirectorios se crean automáticamente (p. ej. .froga/conformance/ para los informes de conformidad).
Cómo la nube los verifica
Sección titulada «Cómo la nube los verifica»La plataforma cloud (TypeScript, cloud/lib/froga/) reproduce la verificación de froga verify sin llamar al CLI:
- Lee los bytes del artefacto (
.json) y la firma (.sig). - Parsea el sobre DSSE e in-toto Statement del fichero
.sig. - Verifica la firma ECDSA-P256 (raw
r‖s) sobre el PAE (Pre-Authentication Encoding DSSE) con@noble/curves. - Comprueba que el
keyiddel sobre coincide conhex(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. - Verifica que el
subject.sha256del 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.
froga verify --repo /ruta/al/proyectoCiclo de vida
Sección titulada «Ciclo de vida»froga compile → genera oscal.assessment_plan (no es un FrogaArtifact)froga run → escribe .froga/bundle.json + bundle.json.sigfroga reconstruct --out → escribe .froga/reconstruct.json + .sigfroga conformance --out → escribe .froga/conformance/<slug>.json + .sigfroga risk-projection → escribe .froga/risk-projection/<slug>.json + .sig[git commit -A .froga/] → los artefactos quedan versionados y trazablesLos 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 froga, Firmar y verificar evidencia.