use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
pub const SCAN_SCHEMA: &str = "tsafe.scan.v1";
pub const LEGACY_SCAN_SCHEMA: &str = "algol.scan.v1";
pub fn is_supported_scan_schema(schema: &str) -> bool {
schema == SCAN_SCHEMA || schema == LEGACY_SCAN_SCHEMA
}
pub const ATTEST_VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum FindingKind {
EnvFile,
HardcodedSecret,
PrivateKey,
CiSecretReference,
RuntimeEnvRead,
UnsafeExport,
RiskyEnvPropagation,
SecretPlaceholder,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "lowercase")]
pub enum Severity {
Critical,
High,
Medium,
Low,
Info,
}
impl Severity {
pub fn weight(self) -> u32 {
match self {
Severity::Critical => 30,
Severity::High => 20,
Severity::Medium => 10,
Severity::Low => 3,
Severity::Info => 1,
}
}
pub fn label(self) -> &'static str {
match self {
Severity::Critical => "CRITICAL",
Severity::High => "HIGH",
Severity::Medium => "MEDIUM",
Severity::Low => "LOW",
Severity::Info => "INFO",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScanFinding {
pub id: String,
pub kind: FindingKind,
pub severity: Severity,
pub confidence: f32,
pub file: String,
pub line: usize,
pub column: usize,
pub secret_type: Option<String>,
pub name: Option<String>,
pub redacted_value: Option<String>,
pub hash: Option<String>,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObservedEnvRead {
pub name: String,
pub file: String,
pub line: usize,
pub language: String,
pub confidence: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CiSecretReference {
pub name: String,
pub provider: String,
pub file: String,
pub line: usize,
pub context: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ScanSummary {
pub total_findings: usize,
pub critical: usize,
pub high: usize,
pub medium: usize,
pub low: usize,
pub risk_score: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScanReport {
pub schema: String,
pub repo_path: String,
pub repo_commit: Option<String>,
pub scanned_at: DateTime<Utc>,
pub scanner_version: String,
pub findings: Vec<ScanFinding>,
pub observed_env_reads: Vec<ObservedEnvRead>,
pub ci_secret_references: Vec<CiSecretReference>,
pub summary: ScanSummary,
}