feat(audit): annotate endpoints in EvidenceLocker + Integrations + Scanner (Batch 1)

- Add AuditedRouteGroupExtensions with WithAuditFilter() and Audited() helpers
- EvidenceLocker: 7 endpoints (store, snapshot, verify, hold, store_verdict,
  verify_verdict, export)
- Integrations: 6 endpoints (create, update, delete, test, discover,
  run_code_guard)
- Scanner: ~55 annotations across 25 endpoint files covering sources CRUD,
  scan submission, scan policies, approvals, triage, webhooks, reports,
  reachability, secret detection, offline kit, runtime, and more
- Skipped read-only POSTs per convention (delta compare, counterfactual,
  EPSS batch, slice query, policy diagnostics/preview/runtime/overlay)
- All 3 services build clean with 0 errors/warnings
- Sprint 005: FILTER-001, FILTER-002, FILTER-003 marked DONE

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-09 11:08:00 +03:00
parent ddfc154a99
commit 7c7525f353
31 changed files with 224 additions and 79 deletions

View File

@@ -0,0 +1,48 @@
// Copyright (c) StellaOps. Licensed under the BUSL-1.1.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
namespace StellaOps.Audit.Emission;
/// <summary>
/// Convenience extensions for applying the <see cref="AuditActionFilter"/> to route groups
/// and individual endpoints.
/// </summary>
public static class AuditedRouteGroupExtensions
{
/// <summary>
/// Registers <see cref="AuditActionFilter"/> at the route-group level so that all
/// endpoints in the group are evaluated. Only endpoints that carry an
/// <see cref="AuditActionAttribute"/> via <c>.WithMetadata()</c> will actually emit
/// audit events; the rest pass through silently.
/// </summary>
public static RouteGroupBuilder WithAuditFilter(this RouteGroupBuilder group)
{
group.AddEndpointFilter<AuditActionFilter>();
return group;
}
/// <summary>
/// Shorthand: adds the <see cref="AuditActionFilter"/> and the
/// <see cref="AuditActionAttribute"/> metadata in a single call.
/// Use this on individual endpoints when group-level registration is not feasible.
/// </summary>
/// <param name="builder">The route handler builder.</param>
/// <param name="module">The owning module name (e.g., "scanner", "integrations").</param>
/// <param name="action">The action name (e.g., "create", "delete").</param>
/// <param name="resourceType">
/// Optional resource type override. When <c>null</c>, the filter infers the type from the route.
/// </param>
public static RouteHandlerBuilder Audited(
this RouteHandlerBuilder builder,
string module,
string action,
string? resourceType = null)
{
return builder
.AddEndpointFilter<AuditActionFilter>()
.WithMetadata(new AuditActionAttribute(module, action) { ResourceType = resourceType });
}
}