feat: Implement Wine CSP HTTP provider for GOST cryptographic operations
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
- Added WineCspHttpProvider class to interface with Wine-hosted CryptoPro CSP. - Implemented ICryptoProvider, ICryptoProviderDiagnostics, and IDisposable interfaces. - Introduced WineCspHttpSigner and WineCspHttpHasher for signing and hashing operations. - Created WineCspProviderOptions for configuration settings including service URL and key options. - Developed CryptoProGostSigningService to handle GOST signing operations and key management. - Implemented HTTP service for the Wine CSP with endpoints for signing, verification, and hashing. - Added Swagger documentation for API endpoints. - Included health checks and error handling for service availability. - Established DTOs for request and response models in the service.
This commit is contained in:
343
src/Signals/StellaOps.Signals/Models/AocProvenance.cs
Normal file
343
src/Signals/StellaOps.Signals/Models/AocProvenance.cs
Normal file
@@ -0,0 +1,343 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace StellaOps.Signals.Models;
|
||||
|
||||
/// <summary>
|
||||
/// AOC (Aggregation-Only Contract) provenance feed for runtime facts ingestion (SGSI0101).
|
||||
/// Conforms to docs/schemas/provenance-feed.schema.json.
|
||||
/// </summary>
|
||||
public sealed class ProvenanceFeed
|
||||
{
|
||||
public const int CurrentSchemaVersion = 1;
|
||||
|
||||
[BsonElement("schemaVersion")]
|
||||
[JsonPropertyName("schemaVersion")]
|
||||
public int SchemaVersion { get; init; } = CurrentSchemaVersion;
|
||||
|
||||
[BsonElement("feedId")]
|
||||
[JsonPropertyName("feedId")]
|
||||
public string FeedId { get; init; } = Guid.NewGuid().ToString("D");
|
||||
|
||||
[BsonElement("feedType")]
|
||||
[JsonPropertyName("feedType")]
|
||||
public ProvenanceFeedType FeedType { get; init; } = ProvenanceFeedType.RuntimeFacts;
|
||||
|
||||
[BsonElement("generatedAt")]
|
||||
[JsonPropertyName("generatedAt")]
|
||||
public DateTimeOffset GeneratedAt { get; init; } = DateTimeOffset.UtcNow;
|
||||
|
||||
[BsonElement("sourceService")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("sourceService")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? SourceService { get; init; }
|
||||
|
||||
[BsonElement("tenantId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("tenantId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? TenantId { get; init; }
|
||||
|
||||
[BsonElement("correlationId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("correlationId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? CorrelationId { get; init; }
|
||||
|
||||
[BsonElement("records")]
|
||||
[JsonPropertyName("records")]
|
||||
public List<ProvenanceRecord> Records { get; init; } = new();
|
||||
|
||||
[BsonElement("metadata")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("metadata")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Dictionary<string, string?>? Metadata { get; init; }
|
||||
|
||||
[BsonElement("attestation")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("attestation")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public FeedAttestation? Attestation { get; init; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum ProvenanceFeedType
|
||||
{
|
||||
[JsonPropertyName("RUNTIME_FACTS")]
|
||||
RuntimeFacts,
|
||||
|
||||
[JsonPropertyName("SIGNAL_ENRICHMENT")]
|
||||
SignalEnrichment,
|
||||
|
||||
[JsonPropertyName("CAS_PROMOTION")]
|
||||
CasPromotion,
|
||||
|
||||
[JsonPropertyName("SCORING_OUTPUT")]
|
||||
ScoringOutput,
|
||||
|
||||
[JsonPropertyName("AUTHORITY_SCOPES")]
|
||||
AuthorityScopes
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Individual provenance record within a feed.
|
||||
/// </summary>
|
||||
public sealed class ProvenanceRecord
|
||||
{
|
||||
[BsonElement("recordId")]
|
||||
[JsonPropertyName("recordId")]
|
||||
public string RecordId { get; init; } = Guid.NewGuid().ToString("D");
|
||||
|
||||
[BsonElement("recordType")]
|
||||
[JsonPropertyName("recordType")]
|
||||
public string RecordType { get; init; } = string.Empty;
|
||||
|
||||
[BsonElement("subject")]
|
||||
[JsonPropertyName("subject")]
|
||||
public ProvenanceSubject Subject { get; init; } = new();
|
||||
|
||||
[BsonElement("occurredAt")]
|
||||
[JsonPropertyName("occurredAt")]
|
||||
public DateTimeOffset OccurredAt { get; init; }
|
||||
|
||||
[BsonElement("observedBy")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("observedBy")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? ObservedBy { get; init; }
|
||||
|
||||
[BsonElement("confidence")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("confidence")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public double? Confidence { get; init; }
|
||||
|
||||
[BsonElement("facts")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("facts")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public RuntimeProvenanceFacts? Facts { get; init; }
|
||||
|
||||
[BsonElement("evidence")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("evidence")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public RecordEvidence? Evidence { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subject of a provenance record.
|
||||
/// </summary>
|
||||
public sealed class ProvenanceSubject
|
||||
{
|
||||
[BsonElement("type")]
|
||||
[JsonPropertyName("type")]
|
||||
public ProvenanceSubjectType Type { get; init; } = ProvenanceSubjectType.Package;
|
||||
|
||||
[BsonElement("identifier")]
|
||||
[JsonPropertyName("identifier")]
|
||||
public string Identifier { get; init; } = string.Empty;
|
||||
|
||||
[BsonElement("digest")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("digest")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Digest { get; init; }
|
||||
|
||||
[BsonElement("namespace")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("namespace")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Namespace { get; init; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum ProvenanceSubjectType
|
||||
{
|
||||
[JsonPropertyName("CONTAINER")]
|
||||
Container,
|
||||
|
||||
[JsonPropertyName("PROCESS")]
|
||||
Process,
|
||||
|
||||
[JsonPropertyName("PACKAGE")]
|
||||
Package,
|
||||
|
||||
[JsonPropertyName("FILE")]
|
||||
File,
|
||||
|
||||
[JsonPropertyName("NETWORK")]
|
||||
Network,
|
||||
|
||||
[JsonPropertyName("IMAGE")]
|
||||
Image
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runtime-specific provenance facts.
|
||||
/// </summary>
|
||||
public sealed class RuntimeProvenanceFacts
|
||||
{
|
||||
[BsonElement("symbolId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("symbolId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? SymbolId { get; init; }
|
||||
|
||||
[BsonElement("processName")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("processName")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? ProcessName { get; init; }
|
||||
|
||||
[BsonElement("processId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("processId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public int? ProcessId { get; init; }
|
||||
|
||||
[BsonElement("socketAddress")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("socketAddress")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? SocketAddress { get; init; }
|
||||
|
||||
[BsonElement("containerId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("containerId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? ContainerId { get; init; }
|
||||
|
||||
[BsonElement("hitCount")]
|
||||
[JsonPropertyName("hitCount")]
|
||||
public int HitCount { get; init; }
|
||||
|
||||
[BsonElement("purl")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("purl")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Purl { get; init; }
|
||||
|
||||
[BsonElement("codeId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("codeId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? CodeId { get; init; }
|
||||
|
||||
[BsonElement("buildId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("buildId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? BuildId { get; init; }
|
||||
|
||||
[BsonElement("loaderBase")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("loaderBase")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? LoaderBase { get; init; }
|
||||
|
||||
[BsonElement("metadata")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("metadata")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public Dictionary<string, string?>? Metadata { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evidence supporting a provenance record.
|
||||
/// </summary>
|
||||
public sealed class RecordEvidence
|
||||
{
|
||||
[BsonElement("sourceDigest")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("sourceDigest")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? SourceDigest { get; init; }
|
||||
|
||||
[BsonElement("captureMethod")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("captureMethod")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public EvidenceCaptureMethod? CaptureMethod { get; init; }
|
||||
|
||||
[BsonElement("rawDataRef")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("rawDataRef")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? RawDataRef { get; init; }
|
||||
}
|
||||
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public enum EvidenceCaptureMethod
|
||||
{
|
||||
[JsonPropertyName("eBPF")]
|
||||
EBpf,
|
||||
|
||||
[JsonPropertyName("PROC_SCAN")]
|
||||
ProcScan,
|
||||
|
||||
[JsonPropertyName("API_CALL")]
|
||||
ApiCall,
|
||||
|
||||
[JsonPropertyName("LOG_ANALYSIS")]
|
||||
LogAnalysis,
|
||||
|
||||
[JsonPropertyName("STATIC_ANALYSIS")]
|
||||
StaticAnalysis
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attestation metadata for a provenance feed.
|
||||
/// </summary>
|
||||
public sealed class FeedAttestation
|
||||
{
|
||||
[BsonElement("predicateType")]
|
||||
[JsonPropertyName("predicateType")]
|
||||
public string PredicateType { get; init; } = "https://stella.ops/attestation/provenance-feed/v1";
|
||||
|
||||
[BsonElement("signedAt")]
|
||||
[JsonPropertyName("signedAt")]
|
||||
public DateTimeOffset SignedAt { get; init; }
|
||||
|
||||
[BsonElement("keyId")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("keyId")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? KeyId { get; init; }
|
||||
|
||||
[BsonElement("envelopeDigest")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("envelopeDigest")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? EnvelopeDigest { get; init; }
|
||||
|
||||
[BsonElement("transparencyLog")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("transparencyLog")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? TransparencyLog { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Context facts container stored on ReachabilityFactDocument.
|
||||
/// </summary>
|
||||
public sealed class ContextFacts
|
||||
{
|
||||
[BsonElement("provenance")]
|
||||
[BsonIgnoreIfNull]
|
||||
[JsonPropertyName("provenance")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public ProvenanceFeed? Provenance { get; set; }
|
||||
|
||||
[BsonElement("lastUpdatedAt")]
|
||||
[JsonPropertyName("lastUpdatedAt")]
|
||||
public DateTimeOffset LastUpdatedAt { get; set; }
|
||||
|
||||
[BsonElement("recordCount")]
|
||||
[JsonPropertyName("recordCount")]
|
||||
public int RecordCount { get; set; }
|
||||
}
|
||||
@@ -31,6 +31,10 @@ public sealed class ReachabilityFactDocument
|
||||
[BsonIgnoreIfNull]
|
||||
public Dictionary<string, string?>? Metadata { get; set; }
|
||||
|
||||
[BsonElement("contextFacts")]
|
||||
[BsonIgnoreIfNull]
|
||||
public ContextFacts? ContextFacts { get; set; }
|
||||
|
||||
[BsonElement("score")]
|
||||
public double Score { get; set; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user