Rename Vexer to Excititor
This commit is contained in:
		
							
								
								
									
										25
									
								
								src/StellaOps.Excititor.WebService/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/StellaOps.Excititor.WebService/AGENTS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| # AGENTS | ||||
| ## Role | ||||
| ASP.NET Minimal API surface for Excititor ingest, provider administration, reconciliation, export, and verification flows. | ||||
| ## Scope | ||||
| - Program bootstrap, DI wiring for connectors/normalizers/export/attestation/policy/storage. | ||||
| - HTTP endpoints `/excititor/*` with authentication, authorization scopes, request validation, and deterministic responses. | ||||
| - Job orchestration bridges for Worker hand-off (when co-hosted) and offline-friendly configuration. | ||||
| - Observability (structured logs, metrics, tracing) aligned with StellaOps conventions. | ||||
| ## Participants | ||||
| - StellaOps.Cli sends `excititor` verbs to this service via token-authenticated HTTPS. | ||||
| - Worker receives scheduled jobs and uses shared infrastructure via common DI extensions. | ||||
| - Authority service provides tokens; WebService enforces scopes before executing operations. | ||||
| ## Interfaces & contracts | ||||
| - DTOs for ingest/export requests, run metadata, provider management. | ||||
| - Background job interfaces for ingest/resume/reconcile triggering. | ||||
| - Health/status endpoints exposing pull/export history and current policy revision. | ||||
| ## In/Out of scope | ||||
| In: HTTP hosting, request orchestration, DI composition, auth/authorization, logging. | ||||
| Out: long-running ingestion loops (Worker), export rendering (Export module), connector implementations. | ||||
| ## Observability & security expectations | ||||
| - Enforce bearer token scopes, enforce audit logging (request/response correlation IDs, provider IDs). | ||||
| - Emit structured events for ingest runs, export invocations, attestation references. | ||||
| - Provide built-in counters/histograms for latency and throughput. | ||||
| ## Tests | ||||
| - Minimal API contract/unit tests and integration harness will live in `../StellaOps.Excititor.WebService.Tests`. | ||||
							
								
								
									
										91
									
								
								src/StellaOps.Excititor.WebService/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/StellaOps.Excititor.WebService/Program.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,91 @@ | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Microsoft.Extensions.Options; | ||||
| using StellaOps.Excititor.Attestation.Extensions; | ||||
| using StellaOps.Excititor.Attestation; | ||||
| using StellaOps.Excititor.Attestation.Transparency; | ||||
| using StellaOps.Excititor.ArtifactStores.S3.Extensions; | ||||
| using StellaOps.Excititor.Export; | ||||
| using StellaOps.Excititor.Storage.Mongo; | ||||
| using StellaOps.Excititor.Connectors.RedHat.CSAF.DependencyInjection; | ||||
|  | ||||
| var builder = WebApplication.CreateBuilder(args); | ||||
| var configuration = builder.Configuration; | ||||
| var services = builder.Services; | ||||
|  | ||||
| services.AddOptions<VexMongoStorageOptions>() | ||||
|     .Bind(configuration.GetSection("Excititor:Storage:Mongo")) | ||||
|     .ValidateOnStart(); | ||||
|  | ||||
| services.AddExcititorMongoStorage(); | ||||
| services.AddVexExportEngine(); | ||||
| services.AddVexExportCacheServices(); | ||||
| services.AddVexAttestation(); | ||||
| services.Configure<VexAttestationClientOptions>(configuration.GetSection("Excititor:Attestation:Client")); | ||||
| services.AddRedHatCsafConnector(); | ||||
|  | ||||
| var rekorSection = configuration.GetSection("Excititor:Attestation:Rekor"); | ||||
| if (rekorSection.Exists()) | ||||
| { | ||||
|     services.AddVexRekorClient(opts => rekorSection.Bind(opts)); | ||||
| } | ||||
|  | ||||
| var fileSystemSection = configuration.GetSection("Excititor:Artifacts:FileSystem"); | ||||
| if (fileSystemSection.Exists()) | ||||
| { | ||||
|     services.AddVexFileSystemArtifactStore(opts => fileSystemSection.Bind(opts)); | ||||
| } | ||||
| else | ||||
| { | ||||
|     services.AddVexFileSystemArtifactStore(_ => { }); | ||||
| } | ||||
|  | ||||
| var s3Section = configuration.GetSection("Excititor:Artifacts:S3"); | ||||
| if (s3Section.Exists()) | ||||
| { | ||||
|     services.AddVexS3ArtifactClient(opts => s3Section.GetSection("Client").Bind(opts)); | ||||
|     services.AddSingleton<IVexArtifactStore, S3ArtifactStore>(provider => | ||||
|     { | ||||
|         var options = new S3ArtifactStoreOptions(); | ||||
|         s3Section.GetSection("Store").Bind(options); | ||||
|         return new S3ArtifactStore( | ||||
|             provider.GetRequiredService<IS3ArtifactClient>(), | ||||
|             Microsoft.Extensions.Options.Options.Create(options), | ||||
|             provider.GetRequiredService<Microsoft.Extensions.Logging.ILogger<S3ArtifactStore>>()); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| var offlineSection = configuration.GetSection("Excititor:Artifacts:OfflineBundle"); | ||||
| if (offlineSection.Exists()) | ||||
| { | ||||
|     services.AddVexOfflineBundleArtifactStore(opts => offlineSection.Bind(opts)); | ||||
| } | ||||
|  | ||||
| services.AddEndpointsApiExplorer(); | ||||
| services.AddHealthChecks(); | ||||
| services.AddSingleton(TimeProvider.System); | ||||
|  | ||||
| var app = builder.Build(); | ||||
|  | ||||
| app.MapGet("/excititor/status", async (HttpContext context, | ||||
|     IEnumerable<IVexArtifactStore> artifactStores, | ||||
|     IOptions<VexMongoStorageOptions> mongoOptions, | ||||
|     TimeProvider timeProvider) => | ||||
| { | ||||
|     var payload = new StatusResponse( | ||||
|         timeProvider.GetUtcNow(), | ||||
|         mongoOptions.Value.RawBucketName, | ||||
|         mongoOptions.Value.GridFsInlineThresholdBytes, | ||||
|         artifactStores.Select(store => store.GetType().Name).ToArray()); | ||||
|  | ||||
|     context.Response.ContentType = "application/json"; | ||||
|     await System.Text.Json.JsonSerializer.SerializeAsync(context.Response.Body, payload); | ||||
| }); | ||||
|  | ||||
| app.MapHealthChecks("/excititor/health"); | ||||
|  | ||||
| app.Run(); | ||||
|  | ||||
| public partial class Program; | ||||
|  | ||||
| internal sealed record StatusResponse(DateTimeOffset UtcNow, string MongoBucket, int InlineThreshold, string[] ArtifactStores); | ||||
| @@ -0,0 +1,16 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net10.0</TargetFramework> | ||||
|     <LangVersion>preview</LangVersion> | ||||
|     <Nullable>enable</Nullable> | ||||
|     <ImplicitUsings>enable</ImplicitUsings> | ||||
|     <TreatWarningsAsErrors>true</TreatWarningsAsErrors> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\StellaOps.Excititor.Core\StellaOps.Excititor.Core.csproj" /> | ||||
|     <ProjectReference Include="..\StellaOps.Excititor.Storage.Mongo\StellaOps.Excititor.Storage.Mongo.csproj" /> | ||||
|     <ProjectReference Include="..\StellaOps.Excititor.Export\StellaOps.Excititor.Export.csproj" /> | ||||
|     <ProjectReference Include="..\StellaOps.Excititor.Attestation\StellaOps.Excititor.Attestation.csproj" /> | ||||
|     <ProjectReference Include="..\StellaOps.Excititor.ArtifactStores.S3\StellaOps.Excititor.ArtifactStores.S3.csproj" /> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
							
								
								
									
										8
									
								
								src/StellaOps.Excititor.WebService/TASKS.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/StellaOps.Excititor.WebService/TASKS.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| If you are working on this file you need to read docs/ARCHITECTURE_EXCITITOR.md and ./AGENTS.md). | ||||
| # TASKS | ||||
| | Task | Owner(s) | Depends on | Notes | | ||||
| |---|---|---|---| | ||||
| |EXCITITOR-WEB-01-001 – Minimal API bootstrap & DI|Team Excititor WebService|EXCITITOR-CORE-01-003, EXCITITOR-STORAGE-01-003|**DONE (2025-10-17)** – Minimal API host composes storage/export/attestation/artifact stores, binds Mongo/attestation options, and exposes `/excititor/status` + health endpoints with regression coverage in `StatusEndpointTests`.| | ||||
| |EXCITITOR-WEB-01-002 – Ingest & reconcile endpoints|Team Excititor WebService|EXCITITOR-WEB-01-001|TODO – Implement `/excititor/init`, `/excititor/ingest/run`, `/excititor/ingest/resume`, `/excititor/reconcile` with token scope enforcement and structured run telemetry.| | ||||
| |EXCITITOR-WEB-01-003 – Export & verify endpoints|Team Excititor WebService|EXCITITOR-WEB-01-001, EXCITITOR-EXPORT-01-001, EXCITITOR-ATTEST-01-001|TODO – Add `/excititor/export`, `/excititor/export/{id}`, `/excititor/export/{id}/download`, `/excititor/verify`, returning artifact + attestation metadata with cache awareness.| | ||||
| |EXCITITOR-WEB-01-004 – Resolve API & signed responses|Team Excititor WebService|EXCITITOR-WEB-01-001, EXCITITOR-ATTEST-01-002|TODO – Deliver `/excititor/resolve` (subject/context), return consensus + score envelopes, attach cosign/Rekor metadata, and document auth + rate guardrails.| | ||||
		Reference in New Issue
	
	Block a user