feat: Initialize Zastava Webhook service with TLS and Authority authentication

- Added Program.cs to set up the web application with Serilog for logging, health check endpoints, and a placeholder admission endpoint.
- Configured Kestrel server to use TLS 1.3 and handle client certificates appropriately.
- Created StellaOps.Zastava.Webhook.csproj with necessary dependencies including Serilog and Polly.
- Documented tasks in TASKS.md for the Zastava Webhook project, outlining current work and exit criteria for each task.
This commit is contained in:
master
2025-10-19 18:36:22 +03:00
parent 2062da7a8b
commit d099a90f9b
966 changed files with 91038 additions and 1850 deletions

View File

@@ -1,5 +1,6 @@
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Options;
using Mongo2Go;
@@ -181,6 +182,78 @@ public sealed class MongoVexRepositoryTests : IAsyncLifetime
Assert.Null(remaining);
}
[Fact]
public async Task ClaimStore_AppendsAndQueriesStatements()
{
var database = _client.GetDatabase($"vex-claims-{Guid.NewGuid():N}");
var store = new MongoVexClaimStore(database);
var product = new VexProduct("pkg:demo/app", "Demo App", version: "1.0.0", purl: "pkg:demo/app@1.0.0");
var document = new VexClaimDocument(
VexDocumentFormat.Csaf,
"sha256:claim-1",
new Uri("https://example.org/vex/claim-1.json"),
revision: "2025-10-19");
var initialClaim = new VexClaim(
vulnerabilityId: "CVE-2025-0101",
providerId: "redhat",
product: product,
status: VexClaimStatus.NotAffected,
document: document,
firstSeen: DateTimeOffset.UtcNow.AddMinutes(-30),
lastSeen: DateTimeOffset.UtcNow.AddMinutes(-10),
justification: VexJustification.ComponentNotPresent,
detail: "Package not shipped in this channel.",
confidence: new VexConfidence("high", 0.9, "policy/default"),
signals: new VexSignalSnapshot(
new VexSeveritySignal("CVSS:3.1", 5.8, "medium", "CVSS:3.1/..."),
kev: false,
epss: 0.21),
additionalMetadata: ImmutableDictionary<string, string>.Empty.Add("source", "csaf"));
await store.AppendAsync(new[] { initialClaim }, DateTimeOffset.UtcNow.AddMinutes(-5), CancellationToken.None);
var secondDocument = new VexClaimDocument(
VexDocumentFormat.Csaf,
"sha256:claim-2",
new Uri("https://example.org/vex/claim-2.json"),
revision: "2025-10-19.1");
var secondClaim = new VexClaim(
vulnerabilityId: initialClaim.VulnerabilityId,
providerId: initialClaim.ProviderId,
product: initialClaim.Product,
status: initialClaim.Status,
document: secondDocument,
firstSeen: initialClaim.FirstSeen,
lastSeen: DateTimeOffset.UtcNow,
justification: initialClaim.Justification,
detail: initialClaim.Detail,
confidence: initialClaim.Confidence,
signals: new VexSignalSnapshot(
new VexSeveritySignal("CVSS:3.1", 7.2, "high"),
kev: true,
epss: 0.43),
additionalMetadata: initialClaim.AdditionalMetadata.ToImmutableDictionary(kvp => kvp.Key, kvp => kvp.Value));
await store.AppendAsync(new[] { secondClaim }, DateTimeOffset.UtcNow, CancellationToken.None);
var all = await store.FindAsync("CVE-2025-0101", product.Key, since: null, CancellationToken.None);
var allList = all.ToList();
Assert.Equal(2, allList.Count);
Assert.Equal("sha256:claim-2", allList[0].Document.Digest);
Assert.True(allList[0].Signals?.Kev);
Assert.Equal(0.43, allList[0].Signals?.Epss);
Assert.Equal("sha256:claim-1", allList[1].Document.Digest);
Assert.Equal("csaf", allList[1].AdditionalMetadata["source"]);
var recentOnly = await store.FindAsync("CVE-2025-0101", product.Key, DateTimeOffset.UtcNow.AddMinutes(-2), CancellationToken.None);
var recentList = recentOnly.ToList();
Assert.Single(recentList);
Assert.Equal("sha256:claim-2", recentList[0].Document.Digest);
}
private MongoVexRawStore CreateRawStore(IMongoDatabase database, int thresholdBytes)
{
var options = Options.Create(new VexMongoStorageOptions