namespace StellaOps.Policy.Engine.Attestation;
///
/// Structured reason codes explaining verdict outcomes.
/// Format: CATEGORY.SUBCATEGORY.DETAIL
///
public enum VerdictReasonCode
{
// PASS reasons
///
/// No CVEs found in artifact.
///
PassNoCves,
///
/// All CVEs are not reachable.
///
PassNotReachable,
///
/// All CVEs are covered by VEX not_affected statements.
///
PassVexNotAffected,
///
/// All CVEs are below severity threshold.
///
PassBelowThreshold,
// FAIL reasons - CVE
///
/// Reachable CVE exceeds severity threshold.
///
FailCveReachable,
///
/// CVE in CISA KEV (Known Exploited Vulnerabilities).
///
FailCveKev,
///
/// CVE with high EPSS score.
///
FailCveEpss,
///
/// CVE severity exceeds maximum allowed.
///
FailCveSeverity,
// FAIL reasons - Policy
///
/// License violation detected.
///
FailPolicyLicense,
///
/// Blocked package detected.
///
FailPolicyBlockedPackage,
///
/// Unknown budget exceeded.
///
FailPolicyUnknownBudget,
///
/// SBOM completeness below threshold.
///
FailPolicySbomCompleteness,
// FAIL reasons - Provenance
///
/// Missing provenance attestation.
///
FailProvenanceMissing,
///
/// Provenance signature invalid.
///
FailProvenanceInvalid,
// EXCEPTION reasons
///
/// CVE covered by approved exception.
///
ExceptionCve,
///
/// License covered by approved exception.
///
ExceptionLicense,
///
/// Unknowns covered by approved exception.
///
ExceptionUnknown,
// INDETERMINATE reasons
///
/// Insufficient data to evaluate.
///
IndeterminateInsufficientData,
///
/// Analyzer does not support this artifact type.
///
IndeterminateUnsupported,
///
/// Conflicting VEX statements.
///
IndeterminateVexConflict,
///
/// Required knowledge source unavailable.
///
IndeterminateFeedUnavailable
}
///
/// Extension methods for reason code handling.
///
public static class VerdictReasonCodeExtensions
{
///
/// Gets the category of a reason code (Pass, Fail, Exception, Indeterminate).
///
public static string GetCategory(this VerdictReasonCode code)
{
return code.ToString() switch
{
var s when s.StartsWith("Pass", StringComparison.Ordinal) => "Pass",
var s when s.StartsWith("Fail", StringComparison.Ordinal) => "Fail",
var s when s.StartsWith("Exception", StringComparison.Ordinal) => "Exception",
var s when s.StartsWith("Indeterminate", StringComparison.Ordinal) => "Indeterminate",
_ => "Unknown"
};
}
///
/// Gets a human-readable description of the reason code.
///
public static string GetDescription(this VerdictReasonCode code)
{
return code switch
{
VerdictReasonCode.PassNoCves => "No CVEs found in artifact",
VerdictReasonCode.PassNotReachable => "All CVEs are not reachable",
VerdictReasonCode.PassVexNotAffected => "All CVEs covered by VEX not_affected statements",
VerdictReasonCode.PassBelowThreshold => "All CVEs below severity threshold",
VerdictReasonCode.FailCveReachable => "Reachable CVE exceeds severity threshold",
VerdictReasonCode.FailCveKev => "CVE in CISA Known Exploited Vulnerabilities list",
VerdictReasonCode.FailCveEpss => "CVE with high EPSS score",
VerdictReasonCode.FailCveSeverity => "CVE severity exceeds maximum allowed",
VerdictReasonCode.FailPolicyLicense => "License violation detected",
VerdictReasonCode.FailPolicyBlockedPackage => "Blocked package detected",
VerdictReasonCode.FailPolicyUnknownBudget => "Unknown budget exceeded",
VerdictReasonCode.FailPolicySbomCompleteness => "SBOM completeness below threshold",
VerdictReasonCode.FailProvenanceMissing => "Missing provenance attestation",
VerdictReasonCode.FailProvenanceInvalid => "Provenance signature invalid",
VerdictReasonCode.ExceptionCve => "CVE covered by approved exception",
VerdictReasonCode.ExceptionLicense => "License covered by approved exception",
VerdictReasonCode.ExceptionUnknown => "Unknowns covered by approved exception",
VerdictReasonCode.IndeterminateInsufficientData => "Insufficient data to evaluate",
VerdictReasonCode.IndeterminateUnsupported => "Analyzer does not support this artifact type",
VerdictReasonCode.IndeterminateVexConflict => "Conflicting VEX statements",
VerdictReasonCode.IndeterminateFeedUnavailable => "Required knowledge source unavailable",
_ => code.ToString()
};
}
///
/// Checks if a reason code indicates a passing state.
///
public static bool IsPass(this VerdictReasonCode code)
{
return code.GetCategory() == "Pass";
}
///
/// Checks if a reason code indicates a failing state.
///
public static bool IsFail(this VerdictReasonCode code)
{
return code.GetCategory() == "Fail";
}
}