Files
git.stella-ops.org/src/Policy/StellaOps.Policy.Engine/Attestation/VerdictReasonCode.cs
StellaOps Bot 5146204f1b feat: add security sink detection patterns for JavaScript/TypeScript
- Introduced `sink-detect.js` with various security sink detection patterns categorized by type (e.g., command injection, SQL injection, file operations).
- Implemented functions to build a lookup map for fast sink detection and to match sink calls against known patterns.
- Added `package-lock.json` for dependency management.
2025-12-22 23:21:21 +02:00

189 lines
5.8 KiB
C#

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