save development progress

This commit is contained in:
StellaOps Bot
2025-12-25 23:09:58 +02:00
parent d71853ad7e
commit aa70af062e
351 changed files with 37683 additions and 150156 deletions

View File

@@ -11,6 +11,7 @@ using StellaOps.Auth.ServerIntegration;
using StellaOps.Configuration;
using StellaOps.DependencyInjection;
using StellaOps.Findings.Ledger.Domain;
using Domain = StellaOps.Findings.Ledger.Domain;
using StellaOps.Findings.Ledger.Infrastructure;
using StellaOps.Findings.Ledger.Infrastructure.AirGap;
using StellaOps.Findings.Ledger.Infrastructure.Merkle;
@@ -23,18 +24,27 @@ using StellaOps.Findings.Ledger.Services;
using StellaOps.Findings.Ledger.WebService.Contracts;
using StellaOps.Findings.Ledger.WebService.Mappings;
using StellaOps.Findings.Ledger.WebService.Services;
using StellaOps.Findings.Ledger.WebService.Endpoints;
using StellaOps.Telemetry.Core;
using StellaOps.Findings.Ledger.Services.Security;
using StellaOps.Findings.Ledger;
using StellaOps.Findings.Ledger.Observability;
using StellaOps.Findings.Ledger.OpenApi;
using System.Text.Json.Nodes;
using System.Security.Cryptography;
using System.Text;
using System.Threading.RateLimiting;
using StellaOps.Findings.Ledger.Services.Incident;
using StellaOps.Router.AspNet;
const string LedgerWritePolicy = "ledger.events.write";
const string LedgerExportPolicy = "ledger.export.read";
// Scoring API policies (SPRINT_8200.0012.0004 - Wave 7)
const string ScoringReadPolicy = "scoring.read";
const string ScoringWritePolicy = "scoring.write";
const string ScoringAdminPolicy = "scoring.admin";
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddStellaOpsDefaults(options =>
@@ -79,17 +89,15 @@ builder.Services.AddHealthChecks();
builder.Services.AddStellaOpsTelemetry(
builder.Configuration,
configureMetering: meterBuilder =>
serviceName: "StellaOps.Findings.Ledger",
configureMetrics: meterBuilder =>
{
meterBuilder.AddAspNetCoreInstrumentation();
meterBuilder.AddHttpClientInstrumentation();
},
configureTracing: tracerBuilder =>
{
tracerBuilder.AddAspNetCoreInstrumentation();
tracerBuilder.AddHttpClientInstrumentation();
meterBuilder.AddMeter("StellaOps.Findings.Ledger");
});
// Rate limiting is handled by API Gateway - see docs/modules/gateway/rate-limiting.md
// Endpoint-level rate limits: scoring-read (1000/min), scoring-calculate (100/min), scoring-batch (10/min), scoring-webhook (10/min)
builder.Services.AddIncidentMode(builder.Configuration);
builder.Services.AddStellaOpsResourceServerAuthentication(
@@ -140,6 +148,28 @@ builder.Services.AddAuthorization(options =>
policy.Requirements.Add(new StellaOpsScopeRequirement(scopes));
policy.AddAuthenticationSchemes(StellaOpsAuthenticationDefaults.AuthenticationScheme);
});
// Scoring API policies (SPRINT_8200.0012.0004 - Wave 7)
options.AddPolicy(ScoringReadPolicy, policy =>
{
policy.RequireAuthenticatedUser();
policy.Requirements.Add(new StellaOpsScopeRequirement(scopes));
policy.AddAuthenticationSchemes(StellaOpsAuthenticationDefaults.AuthenticationScheme);
});
options.AddPolicy(ScoringWritePolicy, policy =>
{
policy.RequireAuthenticatedUser();
policy.Requirements.Add(new StellaOpsScopeRequirement(scopes));
policy.AddAuthenticationSchemes(StellaOpsAuthenticationDefaults.AuthenticationScheme);
});
options.AddPolicy(ScoringAdminPolicy, policy =>
{
policy.RequireAuthenticatedUser();
policy.Requirements.Add(new StellaOpsScopeRequirement(scopes));
policy.AddAuthenticationSchemes(StellaOpsAuthenticationDefaults.AuthenticationScheme);
});
});
builder.Services.AddSingleton<ILedgerIncidentNotifier, LoggingLedgerIncidentNotifier>();
@@ -184,6 +214,19 @@ builder.Services.AddSingleton<VexConsensusService>();
// Alert and Decision services (SPRINT_3602)
builder.Services.AddSingleton<IAlertService, AlertService>();
builder.Services.AddSingleton<IDecisionService, DecisionService>();
builder.Services.AddSingleton<IEvidenceBundleService, EvidenceBundleService>();
// Evidence-Weighted Score services (SPRINT_8200.0012.0004)
builder.Services.AddSingleton<IScoreHistoryStore, InMemoryScoreHistoryStore>();
builder.Services.AddSingleton<IFindingScoringService, FindingScoringService>();
// Webhook services (SPRINT_8200.0012.0004 - Wave 6)
builder.Services.AddSingleton<IWebhookStore, InMemoryWebhookStore>();
builder.Services.AddSingleton<IWebhookDeliveryService, WebhookDeliveryService>();
builder.Services.AddHttpClient("webhook-delivery", client =>
{
client.Timeout = TimeSpan.FromSeconds(30);
});
// Stella Router integration
var routerOptions = builder.Configuration.GetSection("FindingsLedger:Router").Get<StellaRouterOptionsBase>();
@@ -414,7 +457,7 @@ app.MapGet("/ledger/export/vex", async Task<Results<FileStreamHttpResult, JsonHt
httpContext.Request.Query["status"].ToString(),
httpContext.Request.Query["statement_type"].ToString(),
exportQueryService.ClampPageSize(ParseInt(httpContext.Request.Query["page_size"])),
filtersHash: string.Empty,
FiltersHash: string.Empty,
PagingKey: null);
var filtersHash = exportQueryService.ComputeFiltersHash(request);
@@ -484,7 +527,7 @@ app.MapGet("/ledger/export/advisories", async Task<Results<FileStreamHttpResult,
cvssScoreMin,
cvssScoreMax,
exportQueryService.ClampPageSize(ParseInt(httpContext.Request.Query["page_size"])),
filtersHash: string.Empty,
FiltersHash: string.Empty,
PagingKey: null);
var filtersHash = exportQueryService.ComputeFiltersHash(request);
@@ -548,7 +591,7 @@ app.MapGet("/ledger/export/sboms", async Task<Results<FileStreamHttpResult, Json
ParseBool(httpContext.Request.Query["contains_native"]),
httpContext.Request.Query["slsa_build_type"].ToString(),
exportQueryService.ClampPageSize(ParseInt(httpContext.Request.Query["page_size"])),
filtersHash: string.Empty,
FiltersHash: string.Empty,
PagingKey: null);
var filtersHash = exportQueryService.ComputeFiltersHash(request);
@@ -1863,6 +1906,10 @@ app.MapPatch("/api/v1/findings/{findingId}/state", async Task<Results<Ok<StateTr
// Refresh Router endpoint cache
app.TryRefreshStellaRouterEndpoints(routerOptions);
// Map EWS scoring and webhook endpoints (SPRINT_8200.0012.0004)
app.MapScoringEndpoints();
app.MapWebhookEndpoints();
app.Run();
static Created<LedgerEventResponse> CreateCreatedResponse(LedgerEventRecord record)