222 lines
7.1 KiB
C#
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; }
|
|
}
|