Add inline DSSE provenance documentation and Mongo schema

- Introduced a new document outlining the inline DSSE provenance for SBOM, VEX, scan, and derived events.
- Defined the Mongo schema for event patches, including key fields for provenance and trust verification.
- Documented the write path for ingesting provenance metadata and backfilling historical events.
- Created CI/CD snippets for uploading DSSE attestations and generating provenance metadata.
- Established Mongo indexes for efficient provenance queries and provided query recipes for various use cases.
- Outlined policy gates for managing VEX decisions based on provenance verification.
- Included UI nudges for displaying provenance information and implementation tasks for future enhancements.

---

Implement reachability lattice and scoring model

- Developed a comprehensive document detailing the reachability lattice and scoring model.
- Defined core types for reachability states, evidence, and mitigations with corresponding C# models.
- Established a scoring policy with base score contributions from various evidence classes.
- Mapped reachability states to VEX gates and provided a clear overview of evidence sources.
- Documented the event graph schema for persisting reachability data in MongoDB.
- Outlined the integration of runtime probes for evidence collection and defined a roadmap for future tasks.

---

Introduce uncertainty states and entropy scoring

- Created a draft document for tracking uncertainty states and their impact on risk scoring.
- Defined core uncertainty states with associated entropy values and evidence requirements.
- Established a schema for storing uncertainty states alongside findings.
- Documented the risk score calculation incorporating uncertainty and its effect on final risk assessments.
- Provided policy guidelines for handling uncertainty in decision-making processes.
- Outlined UI guidelines for displaying uncertainty information and suggested remediation actions.

---

Add Ruby package inventory management

- Implemented Ruby package inventory management with corresponding data models and storage mechanisms.
- Created C# records for Ruby package inventory, artifacts, provenance, and runtime details.
- Developed a repository for managing Ruby package inventory documents in MongoDB.
- Implemented a service for storing and retrieving Ruby package inventories.
- Added unit tests for the Ruby package inventory store to ensure functionality and data integrity.
This commit is contained in:
master
2025-11-13 00:20:33 +02:00
parent 86be324fc0
commit 7040984215
41 changed files with 1955 additions and 76 deletions

View File

@@ -892,7 +892,7 @@ internal sealed class BackendOperationsClient : IBackendOperationsClient
return result;
}
public async Task<IReadOnlyList<RubyPackageArtifactModel>> GetRubyPackagesAsync(string scanId, CancellationToken cancellationToken)
public async Task<RubyPackageInventoryModel?> GetRubyPackagesAsync(string scanId, CancellationToken cancellationToken)
{
EnsureBackendConfigured();
@@ -907,7 +907,7 @@ internal sealed class BackendOperationsClient : IBackendOperationsClient
using var response = await _httpClient.SendAsync(request, cancellationToken).ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.NotFound)
{
return Array.Empty<RubyPackageArtifactModel>();
return null;
}
if (!response.IsSuccessStatusCode)
@@ -916,11 +916,25 @@ internal sealed class BackendOperationsClient : IBackendOperationsClient
throw new InvalidOperationException(failure);
}
var packages = await response.Content
.ReadFromJsonAsync<IReadOnlyList<RubyPackageArtifactModel>>(SerializerOptions, cancellationToken)
var inventory = await response.Content
.ReadFromJsonAsync<RubyPackageInventoryModel>(SerializerOptions, cancellationToken)
.ConfigureAwait(false);
return packages ?? Array.Empty<RubyPackageArtifactModel>();
if (inventory is null)
{
throw new InvalidOperationException("Ruby package response payload was empty.");
}
var normalizedScanId = string.IsNullOrWhiteSpace(inventory.ScanId) ? scanId : inventory.ScanId;
var normalizedDigest = inventory.ImageDigest ?? string.Empty;
var packages = inventory.Packages ?? Array.Empty<RubyPackageArtifactModel>();
return inventory with
{
ScanId = normalizedScanId,
ImageDigest = normalizedDigest,
Packages = packages
};
}
public async Task<AdvisoryPipelinePlanResponseModel> CreateAdvisoryPipelinePlanAsync(

View File

@@ -49,7 +49,7 @@ internal interface IBackendOperationsClient
Task<EntryTraceResponseModel?> GetEntryTraceAsync(string scanId, CancellationToken cancellationToken);
Task<IReadOnlyList<RubyPackageArtifactModel>> GetRubyPackagesAsync(string scanId, CancellationToken cancellationToken);
Task<RubyPackageInventoryModel?> GetRubyPackagesAsync(string scanId, CancellationToken cancellationToken);
Task<AdvisoryPipelinePlanResponseModel> CreateAdvisoryPipelinePlanAsync(AdvisoryAiTaskType taskType, AdvisoryPipelinePlanRequestModel request, CancellationToken cancellationToken);

View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
@@ -26,3 +27,8 @@ internal sealed record RubyPackageRuntime(
[property: JsonPropertyName("files")] IReadOnlyList<string>? Files,
[property: JsonPropertyName("reasons")] IReadOnlyList<string>? Reasons);
internal sealed record RubyPackageInventoryModel(
[property: JsonPropertyName("scanId")] string ScanId,
[property: JsonPropertyName("imageDigest")] string ImageDigest,
[property: JsonPropertyName("generatedAt")] DateTimeOffset GeneratedAt,
[property: JsonPropertyName("packages")] IReadOnlyList<RubyPackageArtifactModel> Packages);