59 lines
2.4 KiB
Rust
59 lines
2.4 KiB
Rust
//! The external-evidence provider port.
|
|
//!
|
|
//! A sibling product (tramiton, for firmware) may already hold authoritative
|
|
//! analysis for an artifact. An [`EvidenceProvider`] lets compliance-scanner
|
|
//! *reconcile* that evidence — a build plan, an SBOM, a VEX document, a
|
|
//! reproducible-build lock, an attestation — instead of recomputing it. The key
|
|
//! used to match is the artifact content digest (a firmware sha256, which equals
|
|
//! [`crate::models::Artifact::content_hash`]).
|
|
//!
|
|
//! Concrete providers live in the agent (a tramiton CLI shell-out today, a cloud
|
|
//! client later) plus a deterministic mock for tests, so nothing here depends on
|
|
//! an external binary.
|
|
|
|
use std::path::Path;
|
|
|
|
use crate::error::CoreError;
|
|
use crate::models::{Artifact, ExternalSystem};
|
|
|
|
/// A single reconcilable evidence document fetched from a sibling product.
|
|
#[derive(Debug, Clone)]
|
|
pub struct EvidenceDocument {
|
|
/// What the document is: `build_plan` | `sbom` | `vex` | `lock` | `attestation`.
|
|
pub kind: String,
|
|
/// The document's format (e.g. `cyclonedx-1.5`, `openvex-0.2.0`, `toml`, `json`).
|
|
pub format: String,
|
|
/// The raw document payload.
|
|
pub content: String,
|
|
}
|
|
|
|
/// The evidence a provider could return for a target's artifact.
|
|
#[derive(Debug, Clone, Default)]
|
|
pub struct ReconciledEvidence {
|
|
/// The sibling's project identifier, if resolved.
|
|
pub project_id: Option<String>,
|
|
/// The subject content digest the evidence pertains to.
|
|
pub subject_sha256: Option<String>,
|
|
/// The documents fetched (any of build plan / SBOM / VEX / lock / attestation).
|
|
pub documents: Vec<EvidenceDocument>,
|
|
}
|
|
|
|
/// A source of externally-held, reconcilable evidence for an artifact.
|
|
#[allow(async_fn_in_trait)]
|
|
pub trait EvidenceProvider: Send + Sync {
|
|
/// Which sibling product this provider integrates.
|
|
fn system(&self) -> ExternalSystem;
|
|
|
|
/// Whether this provider can handle the given artifact + working path
|
|
/// (e.g. tramiton handles firmware images / embedded source trees).
|
|
fn handles(&self, artifact: &Artifact, working_path: Option<&Path>) -> bool;
|
|
|
|
/// Reconcile existing evidence for the artifact, keyed by its content digest.
|
|
/// Returns `Ok(None)` when the provider has nothing for this artifact.
|
|
async fn reconcile(
|
|
&self,
|
|
artifact: &Artifact,
|
|
working_path: Option<&Path>,
|
|
) -> Result<Option<ReconciledEvidence>, CoreError>;
|
|
}
|