Files
git.stella-ops.org/src/Scanner/__Libraries/StellaOps.Scanner.Reachability/FunctionMap/FunctionMapPredicate.cs
2026-01-24 00:12:43 +02:00

222 lines
7.1 KiB
C#

// SPDX-License-Identifier: BUSL-1.1
// Copyright (c) 2025 StellaOps
// Sprint: SPRINT_20260122_039_Scanner_runtime_linkage_verification
// Task: RLV-001 - Define function_map Predicate Schema
using System.Text.Json.Serialization;
namespace StellaOps.Scanner.Reachability.FunctionMap;
/// <summary>
/// Function map predicate that declares expected call-paths for a service.
/// Used for runtime→static linkage verification via eBPF observation.
///
/// This predicate serves as the "contract" that runtime observations will be verified against.
/// It is typically generated from SBOM + static analysis and signed for attestation.
/// </summary>
/// <remarks>
/// Predicate type: https://stella.ops/predicates/function-map/v1
///
/// Key concepts:
/// - Uses nodeHash recipe from witness-v1 for consistency (PURL + normalized symbol)
/// - expectedPaths defines call-paths from entrypoints to "hot functions"
/// - probeTypes specifies acceptable eBPF probe types for each function
/// - coverage.minObservationRate maps to "≥ 95% of calls witnessed" requirement
/// - optional flag handles conditional paths (feature flags, error handlers)
/// </remarks>
public sealed record FunctionMapPredicate
{
/// <summary>
/// Predicate type URI.
/// </summary>
[JsonPropertyName("_type")]
public string Type { get; init; } = FunctionMapSchema.PredicateType;
/// <summary>
/// Subject artifact that this function map applies to.
/// </summary>
[JsonPropertyName("subject")]
public required FunctionMapSubject Subject { get; init; }
/// <summary>
/// The predicate payload containing the function map definition.
/// </summary>
[JsonPropertyName("predicate")]
public required FunctionMapPredicatePayload Predicate { get; init; }
}
/// <summary>
/// Subject artifact for the function map.
/// </summary>
public sealed record FunctionMapSubject
{
/// <summary>
/// Package URL of the subject artifact.
/// Example: "pkg:oci/myservice@sha256:abc123..."
/// </summary>
[JsonPropertyName("purl")]
public required string Purl { get; init; }
/// <summary>
/// Digest(s) of the subject artifact.
/// Key is algorithm (sha256, sha512), value is hex-encoded hash.
/// </summary>
[JsonPropertyName("digest")]
public required IReadOnlyDictionary<string, string> Digest { get; init; }
/// <summary>
/// Optional artifact name.
/// </summary>
[JsonPropertyName("name")]
public string? Name { get; init; }
}
/// <summary>
/// The main predicate payload containing function map definition.
/// </summary>
public sealed record FunctionMapPredicatePayload
{
/// <summary>
/// Schema version of this predicate.
/// </summary>
[JsonPropertyName("schemaVersion")]
public string SchemaVersion { get; init; } = FunctionMapSchema.SchemaVersion;
/// <summary>
/// Service name that this function map applies to.
/// </summary>
[JsonPropertyName("service")]
public required string Service { get; init; }
/// <summary>
/// Build ID or version of the service.
/// Used to correlate with specific builds.
/// </summary>
[JsonPropertyName("buildId")]
public string? BuildId { get; init; }
/// <summary>
/// References to source materials used to generate this function map.
/// </summary>
[JsonPropertyName("generatedFrom")]
public FunctionMapGeneratedFrom? GeneratedFrom { get; init; }
/// <summary>
/// Expected call-paths that should be observed at runtime.
/// </summary>
[JsonPropertyName("expectedPaths")]
public required IReadOnlyList<ExpectedPath> ExpectedPaths { get; init; }
/// <summary>
/// Coverage thresholds for verification.
/// </summary>
[JsonPropertyName("coverage")]
public required CoverageThresholds Coverage { get; init; }
/// <summary>
/// When this function map was generated.
/// </summary>
[JsonPropertyName("generatedAt")]
public required DateTimeOffset GeneratedAt { get; init; }
/// <summary>
/// Optional generator tool information.
/// </summary>
[JsonPropertyName("generator")]
public GeneratorInfo? Generator { get; init; }
/// <summary>
/// Optional metadata for extensions.
/// </summary>
[JsonPropertyName("metadata")]
public IReadOnlyDictionary<string, object>? Metadata { get; init; }
}
/// <summary>
/// References to source materials used to generate the function map.
/// </summary>
public sealed record FunctionMapGeneratedFrom
{
/// <summary>
/// SHA256 digest of the SBOM used.
/// </summary>
[JsonPropertyName("sbomRef")]
public string? SbomRef { get; init; }
/// <summary>
/// SHA256 digest of the static analysis results used.
/// </summary>
[JsonPropertyName("staticAnalysisRef")]
public string? StaticAnalysisRef { get; init; }
/// <summary>
/// SHA256 digest of the binary analysis results used.
/// </summary>
[JsonPropertyName("binaryAnalysisRef")]
public string? BinaryAnalysisRef { get; init; }
/// <summary>
/// Hot function patterns used for filtering.
/// </summary>
[JsonPropertyName("hotFunctionPatterns")]
public IReadOnlyList<string>? HotFunctionPatterns { get; init; }
}
/// <summary>
/// Coverage thresholds for function map verification.
/// </summary>
public sealed record CoverageThresholds
{
/// <summary>
/// Minimum observation rate required for verification to pass.
/// Value between 0.0 and 1.0 (e.g., 0.95 = 95% of expected calls must be observed).
/// </summary>
[JsonPropertyName("minObservationRate")]
public double MinObservationRate { get; init; } = FunctionMapSchema.DefaultMinObservationRate;
/// <summary>
/// Observation window in seconds.
/// Only observations within this window are considered for verification.
/// </summary>
[JsonPropertyName("windowSeconds")]
public int WindowSeconds { get; init; } = FunctionMapSchema.DefaultWindowSeconds;
/// <summary>
/// Minimum number of observations required before verification can succeed.
/// Prevents false positives from low traffic periods.
/// </summary>
[JsonPropertyName("minObservationCount")]
public int? MinObservationCount { get; init; }
/// <summary>
/// Whether to fail on unexpected symbols (not in the function map).
/// When false (default), unexpected symbols are reported but don't fail verification.
/// </summary>
[JsonPropertyName("failOnUnexpected")]
public bool FailOnUnexpected { get; init; }
}
/// <summary>
/// Information about the tool that generated this function map.
/// </summary>
public sealed record GeneratorInfo
{
/// <summary>
/// Name of the generator tool.
/// </summary>
[JsonPropertyName("name")]
public string? Name { get; init; }
/// <summary>
/// Version of the generator tool.
/// </summary>
[JsonPropertyName("version")]
public string? Version { get; init; }
/// <summary>
/// Optional commit hash of the generator tool.
/// </summary>
[JsonPropertyName("commit")]
public string? Commit { get; init; }
}