Scanner Endpoint Registration Matrix
Last updated: 2026-07-17 (Sprint 20260714_002, tasks SVC-4/SVC-6).
This file is the Scanner WebService source-of-truth for endpoint registration intent and authorization posture.
Active endpoint maps (registered in Program.cs)
| Map method | Base path | Authorization posture | Notes |
|---|---|---|---|
MapHealthEndpoints | /healthz, /readyz | scanner.scans.read | Health and readiness are authenticated. |
MapObservabilityEndpoints | /metrics | AllowAnonymous | Prometheus scrape path is explicitly anonymous. |
MapOfflineKitEndpoints | /offline-kit | Mixed explicit policies | Offline import/status/manifest/validate policies are explicit per route. |
MapScanEndpoints | /api/v1/scans | Explicit policies per route | Includes nested scan maps (callgraphs, sbom, reachability, export, evidence, approval, manifest, github-code-scanning). |
MapSourcesEndpoints | /api/v1/sources | scanner.sources.read/write/admin | Tenant-aware source CRUD and source-run operations (sbom_source_runs reads/writes are tenant-filtered). |
MapWebhookEndpoints | /api/v1/webhooks | AllowAnonymous | External provider ingress; tenant-scoped source resolution for name routes. |
MapSbomUploadEndpoints | /api/v1/sbom | Explicit policies per route | Includes SBOM upload and hot lookup maps. |
MapReachabilityDriftRootEndpoints | /api/v1/reachability | scanner.scans.read/write | Root drift query/compute routes. |
MapDeltaCompareEndpoints | /api/v1/delta | Explicit policies per route | Delta compare operations. |
MapSmartDiffEndpoints | /api/v1/smart-diff | Explicit policies per route | Smart diff + VEX candidate workflows. |
MapBaselineEndpoints | /api/v1/baselines | scanner.scans.read | Reserved recommendation/rationale route shapes fail closed with deterministic HTTP 501 scanner_baseline_recommendations_unavailable; the former synthesized response is unwired until a persisted tenant truth source exists. |
MapActionablesEndpoints | /api/v1/actionables | Explicit policies per route | Actionable findings operations. |
MapCounterfactualEndpoints | /api/v1/counterfactuals | Explicit policies per route | Counterfactual analysis operations. |
MapProofSpineEndpoints | /api/v1/spines | Explicit policies per route | Proof spine APIs. |
MapReplayEndpoints | /api/v1/replay | Explicit policies per route | Replay command and verification APIs. |
MapScoreReplayEndpoints (feature-gated) | /api/v1/replay/score | Explicit policies per route | Enabled only when scanner:scoreReplay:enabled=true. |
MapWitnessEndpoints | /api/v1/witnesses | Explicit policies per route | Witness management APIs. |
MapEpssEndpoints | /api/v1/epss | Explicit policies per route | EPSS ingestion/query APIs. |
MapTriageStatusEndpoints | /api/v1/triage | scanner.triage.read/write | Triage status workflows. |
MapTriageInboxEndpoints | /api/v1/triage | scanner.triage.read/write | GET /inbox requires artifactDigest; optional filter, sortBy, similarityThreshold, and descending are parsed explicitly. Each path exposes canonical bare UUIDs in findingIds[]. |
MapBatchTriageEndpoints | /api/v1/triage | scanner.triage.read/write | Cluster statistics are live; batch action responses are non-persistent and unsigned until the triage decision/snapshot store is composed. |
MapProofBundleEndpoints | /api/v1/triage | scanner.triage.write | Reserved proof-bundle generation shape; IProofBundleGenerator has no implementation/DI registration and the contract is not tenant-bound. |
MapUnknownsEndpoints | /api/v1/unknowns | scanner.scans.read | Tenant-scoped unknown listing/detail/evidence/history/stats/bands routes. |
MapSecretDetectionSettingsEndpoints | /api/v1/secrets/config | scanner.secret-settings.* / scanner.secret-exceptions.* | Secret detection config APIs with tenant-scoped exception get/update/delete lookups. |
MapScannerTenantSettingsEndpoints | /api/v1/scanner/settings | GET scanner.operations.read (scanner:read or scanner.admin); PUT scanner.operations.write (scanner:write or scanner.admin) | Tenant-scoped GET/PUT of disabled signed-analyzer IDs; strong ETag compare-and-swap, audit event, and Worker consumption. |
MapScannerAnalyzerEndpoints | /api/v1/scanner/analyzers | scanner.operations.read (scanner:read or scanner.admin) | Worker probe-report truth plus tenant enablement; health is healthy, unhealthy, or evidence-absent unknown. |
MapScannerPerformanceEndpoints | /api/v1/scanner/performance | scanner.operations.read (scanner:read or scanner.admin) | Tenant-scoped pending depth and non-replay duration percentiles over durable Scanner records; unavailable metrics are omitted with reasons. |
MapPolicyEndpoints (feature-gated) | /api/v1/policy | Explicit policies per route | Enabled only when policy preview feature flag is true. |
MapReportEndpoints | /api/v1/reports | scanner.reports | Report generation and retrieval routes. |
MapRuntimeEndpoints | /api/v1/runtime | scanner.runtime.ingest and scan policies | Runtime ingest/reconcile APIs. |
MapSliceEndpoints | /api/slices | Explicit policies per route | Reachability slice query/replay APIs. |
Webhook tenant contract (name routes)
- Name-based webhook routes are:
POST /api/v1/webhooks/docker/{sourceName}POST /api/v1/webhooks/github/{sourceName}POST /api/v1/webhooks/gitlab/{sourceName}POST /api/v1/webhooks/harbor/{sourceName}- Tenant context is required for name-based routes (claim or
X-StellaOps-TenantId/compatibility alias). Missing tenant returns400withtenant_missing; claim/header mismatch returns400withtenant_conflict. - Source lookup is tenant-scoped via
GetByNameAsync(tenantId, sourceName), so same-name sources in different tenants cannot cross-dispatch. POST /api/v1/webhooks/{sourceId}accepts optional tenant context; if present and it does not match source ownership, the endpoint returns404.
Triage tenant contract
- Triage and finding-evidence routes resolve tenant context via
ScannerRequestContextResolver. - Resolution uses the validated tenant claim through the shared
StellaOpsTenantResolver; there is no default-tenant fallback. The canonical tenant-switch header is honored only for authenticated global-admin principals, and legacy tenant headers are not tenancy sources. - Missing or conflicting validated tenancy returns a deterministic request error rather than selecting a fallback tenant.
- Triage-facing contracts now require tenant input (
ITriageStatusService,ITriageQueryService,IFindingQueryService,IGatingReasonService,IUnifiedEvidenceService,IReplayCommandService,IFindingRationaleService) and enforce tenant-filtered data access. - Triage persistence is tenant partitioned (
triage_scan.tenant_id,triage_finding.tenant_id), and the active-case uniqueness key includestenant_idto avoid cross-tenant collisions. - Cross-tenant finding lookups are treated as deterministic not-found responses (
404) on triage/finding endpoints. /api/v1/triage/inbox?artifactDigest=...is the canonical identity bridge:artifactDigestfilters all matching tenant rows andpaths[].findingIds[]returns bare UUIDs consumed unchanged by/findings/{findingId}/evidence. Findings-service matcher tokens are not Scanner Triage aliases.- Existing findings may return partial unified evidence as
200with typedavailability.missing[]; missing and cross-tenant findings return a non-echoing404 scanner.triage.finding_not_foundwith producer and recovery metadata.
Unknowns tenant contract
- Unknowns routes resolve tenant context via
ScannerRequestContextResolverusing canonical and compatibility claim/header paths with conflict detection. - Unknown queries are tenant-scoped by data access predicates (
tenant_id::text = @tenantId) in the Scanner WebService query service. - Missing records across tenant boundaries resolve as deterministic
404for detail/evidence/history endpoints.
Reachability + SmartDiff tenant contract (SCAN-TEN-11)
- Reachability drift routes (
/api/v1/scans/{scanId}/drift,/api/v1/drift/{driftId}/sinks) now resolve tenant context viaScannerRequestContextResolverbefore repository access. - Drift persistence/retrieval paths are tenant-parameterized end-to-end (
call_graph_snapshots,code_changes,reachability_drift_results,drifted_sinks) instead of using a fixed tenant scope. - SmartDiff routes (
/api/v1/smart-diff/**) now resolve tenant context and pass it explicitly to material-change and VEX-candidate stores. - SmartDiff persistence/retrieval paths are tenant-parameterized (
material_risk_changes,vex_candidates), so candidate ID collisions across tenants resolve as deterministic not-found. - Remaining reachability/SmartDiff storage adapters used by these flows are tenant-parameterized as well (
risk_state_snapshots,reachability_results), removing fixed-tenant constants from Postgres adapter implementations.
Source-runs + secret-exception tenant contract (SCAN-TEN-13)
- Source run routes (
/api/v1/sources/{sourceId}/runs,/api/v1/sources/{sourceId}/runs/{runId}) now pass resolved tenant context intoISbomSourceRunRepositoryand SQL predicates (tenant_id = @tenantId) forscanner.sbom_source_runs. - Secret exception routes (
/api/v1/secrets/config/exceptions/{tenantId}/{exceptionId}) now use tenant-scoped repository methods for get/update/delete againstsecret_exception_patternrather than ID-only lookups. - The generic webhook route (
POST /api/v1/webhooks/{sourceId}) remains compatibility-tolerant for missing tenant context, but enforces ownership match when tenant context is present.
Deferred endpoint maps (not registered by design)
| Map method | Current state | Reason for deferral | Activation prerequisite |
|---|---|---|---|
MapValidationEndpoints | Deferred | Validation endpoint stack is not wired in Program.cs (validator service graph and option bindings are not part of default webservice startup contract). | Add explicit validation DI and contract docs, then register in Program.cs. |
MapReachabilityEvidenceEndpoints | Deferred | Legacy standalone /api/reachability surface is not part of current /api/v1/scans/triage scanner API contract. | Contract decision to promote or remove this surface. |
MapReachabilityStackEndpoints | Deferred | Stack endpoints depend on optional repository path and are not part of the current public API registration set. | Contract decision and stable backing repository implementation. |
MapFidelityEndpoints | Deferred | Fidelity analyzer endpoints are experimental and require explicit analyzer service contract decisions before exposure. | Product sign-off and DI contract hardening. |
