# Aggregation-Only Guard Library Reference > **Packages:** `StellaOps.Aoc`, `StellaOps.Aoc.AspNetCore` > **Related tasks:** `WEB-AOC-19-001`, `WEB-AOC-19-003`, `DEVOPS-AOC-19-001` > **Audience:** Concelier/Excititor service owners, Platform guild, QA The Aggregation-Only Contract (AOC) guard library enforces the canonical ingestion rules described in `docs/ingestion/aggregation-only-contract.md`. Service owners should use the guard whenever raw advisory or VEX payloads are accepted so that forbidden fields are rejected long before they reach MongoDB. ## Packages ### `StellaOps.Aoc` - `IAocGuard` / `AocWriteGuard` — validate JSON payloads and emit `AocGuardResult`. - `AocGuardOptions` — toggles for signature enforcement, tenant requirements, and required top-level fields. - `AocViolation` / `AocViolationCode` — structured violations surfaced to callers. - `ServiceCollectionExtensions.AddAocGuard()` — DI helper that registers the singleton guard. - `AocGuardExtensions.ValidateOrThrow()` — throws `AocGuardException` when validation fails. ### `StellaOps.Aoc.AspNetCore` - `AocGuardEndpointFilter` — Minimal API endpoint filter that evaluates request payloads through the guard before invoking handlers. - `AocHttpResults.Problem()` — Produces a RFC 7807 payload that includes violation codes, suitable for API responses. ## Minimal API integration ```csharp using StellaOps.Aoc; using StellaOps.Aoc.AspNetCore.Routing; using StellaOps.Aoc.AspNetCore.Results; var builder = WebApplication.CreateBuilder(args); builder.Services.AddAocGuard(); builder.Services.Configure(options => { options.RequireSignatureMetadata = true; options.RequireTenant = true; }); var app = builder.Build(); app.MapPost("/ingest", async (IngestionRequest request, IAocGuard guard, ILogger logger) => { // additional application logic return Results.Accepted(); }) .AddEndpointFilter(new AocGuardEndpointFilter( request => new object?[] { request.Payload }, serializerOptions: null, guardOptions: null)) .ProducesProblem(StatusCodes.Status400BadRequest) .WithTags("AOC"); app.UseExceptionHandler(errorApp => { errorApp.Run(async context => { var exceptionHandler = context.Features.Get(); if (exceptionHandler?.Error is AocGuardException guardException) { var result = AocHttpResults.Problem(context, guardException); await result.ExecuteAsync(context); return; } context.Response.StatusCode = StatusCodes.Status500InternalServerError; }); }); ``` Key points: - Register the guard singleton before wiring repositories or worker services. - Use `AocGuardEndpointFilter` to protect Minimal API endpoints. The `payloadSelector` can yield multiple payloads (e.g. batch ingestion) and the filter will validate each one. - Wrap guard exceptions with `AocHttpResults.Problem` to ensure clients receive machine-readables codes (`ERR_AOC_00x`). ## Worker / repository usage Inject `IAocGuard` (or a module-specific wrapper such as `IVexRawWriteGuard`) anywhere documents are persisted. Call `ValidateOrThrow` before writes to guarantee fail-fast behaviour, for example: ```csharp public sealed class AdvisoryRawRepository { private readonly IAocGuard _guard; public AdvisoryRawRepository(IAocGuard guard) => _guard = guard; public Task WriteAsync(JsonDocument document, CancellationToken cancellationToken) { _guard.ValidateOrThrow(document.RootElement); // proceed with storage logic } } ``` ## Configuration tips - Adjust `AocGuardOptions.RequiredTopLevelFields` when staging new schema changes. All configured names are case-insensitive. - Set `RequireSignatureMetadata = false` for legacy feeds that do not provide signature envelopes yet; track the waiver in the module backlog. - Use module-specific wrappers (`AddConcelierAocGuards`, `AddExcititorAocGuards`) to combine guard registration with domain exceptions and metrics. ## Testing guidance - Unit-test guard behaviour with fixture payloads (see `src/Aoc/__Tests`). - Service-level tests should assert that ingestion endpoints return `ERR_AOC_*` codes via `AocHttpResults`. - CI must run `stella aoc verify` once CLI support lands (`DEVOPS-AOC-19-002`). - Roslyn analyzer enforcement (`WEB-AOC-19-003`) will ensure the guard is registered; keep services wired through the shared extensions to prepare for that gate. For questions or updates, coordinate with the BE‑Base Platform guild and reference `WEB-AOC-19-001`.