Files

8.4 KiB

Remediation Module Architecture

Status: Partially implemented. Core remediation APIs exist, and marketplace source endpoints now run with persistence-backed list/get/upsert behavior. Remaining areas are still incremental (template lifecycle depth, contributor workflow hardening, and broader policy integration).

Overview

The Remediation module provides a developer-facing signed-PR remediation marketplace for the Stella Ops platform. It enables developers to discover, apply, and verify community-contributed or vendor-supplied fix templates for known vulnerabilities (CVEs).

Key Concepts

Fix Templates

Structured remediation patches tied to specific CVE + PURL combinations. Templates include unified diff content, version range applicability, and trust scores from contributor history.

PR Submissions

Tracks the lifecycle of a remediation pull request from submission through scanning, merging, and post-merge verification. Each submission produces attestation evidence including reachability deltas and fix-chain DSSE envelopes.

Contributors

Community members or vendors who submit fix templates. Each contributor has a trust score computed from their verification history (verified fixes, rejections).

Marketplace Sources

Curated collections of fix templates from community, partner, or vendor origins. Sources are rated independently and can be enabled or disabled per tenant.

Domain Model

FixTemplate (remediation.fix_templates)
|- CveId (text, indexed)
|- Purl (text, indexed - pkg:type/name)
|- VersionRange (semver range)
|- PatchContent (unified diff)
|- Status (pending/verified/rejected)
|- TrustScore (0.0-1.0)
|- DsseDigest (nullable - signed envelope hash)
`- ContributorId / SourceId (foreign keys)

PrSubmission (remediation.pr_submissions)
|- FixTemplateId (nullable FK)
|- PrUrl, RepositoryUrl, SourceBranch, TargetBranch
|- CveId (text, indexed)
|- Status (opened/scanning/merged/verified/failed/inconclusive)
|- PreScanDigest, PostScanDigest
|- ReachabilityDeltaDigest, FixChainDsseDigest
|- Verdict (fixed/partial/not_fixed/inconclusive)
`- ContributorId

Contributor (remediation.contributors)
|- Username (unique)
|- VerifiedFixes, TotalSubmissions, RejectedSubmissions
`- TrustScore (computed)

MarketplaceSource (remediation.marketplace_sources)
|- Key (tenant-scoped unique key)
|- SourceType (community/partner/vendor)
|- Enabled, TrustScore
`- LastSyncAt

Trust Scoring

Contributor trust score formula:

score = clamp((verified * 1.0 - rejected * 0.5) / max(total, 1), 0, 1)

Trust tiers:

  • trusted (> 0.8): Verified track record
  • established (> 0.5): Growing history
  • new (> 0.2): Recently joined
  • untrusted (<= 0.2): Insufficient or negative history

API Surface

All endpoints are under /api/v1/remediation/.

Templates

  • GET /templates - List fix templates (filter by CVE, PURL)
  • GET /templates/{id} - Get template detail
  • POST /templates - Create template (requires remediation.submit)

Submissions

  • GET /submissions - List PR submissions
  • GET /submissions/{id} - Get submission with attestation chain
  • POST /submissions - Submit PR for verification
  • GET /submissions/{id}/status - Pipeline status

Matching

  • GET /match?cve=...&purl=...&version=... - Find applicable fix templates

Contributors

  • GET /contributors - List contributors
  • GET /contributors/{username} - Profile with trust score

Sources

  • GET /sources - List marketplace sources
  • GET /sources/{key} - Source detail
  • POST /sources - Create/update source (requires remediation.manage)

Implemented source API contract (2026-03-04):

  • Request model for upsert (POST /sources): key, name, url, sourceType, enabled, trustScore, lastSyncAt.
  • Deterministic behavior:
    • key normalization uses lowercase invariant
    • list ordering is key-based ordinal ordering
    • upsert is idempotent by tenant + source key
  • Validation:
    • key pattern: ^[a-z0-9][a-z0-9._-]{0,63}$
    • sourceType allowed values: community, partner, vendor
    • trustScore range: 0..1
    • url must be an absolute http/https URL when provided
  • Tenant isolation:
    • all source endpoints require tenant context (RequireTenant)
    • repository operations are tenant-scoped for list/get/upsert behavior

Authorization Policies

Policy Description
remediation.read Read templates, submissions, contributors, sources
remediation.submit Create templates and submit PRs
remediation.manage Manage marketplace sources, verify/reject templates

Runtime Storage Contract (2026-03-05)

Remediation runtime storage is now selected through Remediation:Storage:Driver (or Storage:Driver) with explicit startup validation:

  • postgres (default):

    • Required settings: ConnectionStrings:Default or Remediation:Storage:Postgres:ConnectionString.
    • Optional schema override: Remediation:Storage:Postgres:SchemaName (defaults to remediation).
    • Behavior: repositories are wired with RemediationDataSource and Postgres-backed constructors.
    • Startup: fails fast when required connection configuration is missing.
  • inmemory:

    • Allowed only in Test/Testing environment profiles.
    • Intended for deterministic automated tests only.
    • Startup: fails fast outside test profiles.

This removes implicit production-like in-memory behavior and makes storage mode explicit and auditable.

Migration notes:

  • Legacy webservice wiring that instantiated parameterless repository constructors has been removed.
  • Existing deployments must provide a Postgres connection string (or explicitly run with inmemory in Test/Testing profiles).
  • Integration tests should pin REMEDIATION__STORAGE__DRIVER=inmemory under a testing environment profile for deterministic non-network execution.

Service Integration Baseline (2026-03-05)

  • Router integration enabled (serviceName: remediation) with endpoint refresh on startup.
  • Local alias binding/logging enabled via remediation.stella-ops.local.
  • CORS and tenant middleware are part of the default request pipeline before endpoint execution.

Verification Pipeline

  1. PR submitted (status: opened)
  2. Pre-merge scan captures baseline SBOM digest
  3. PR merged (status: merged)
  4. Post-merge scan captures updated SBOM digest
  5. Reachability delta computed between pre and post digests
  6. Fix-chain DSSE envelope signed
  7. Verdict determined: fixed, partial, not_fixed, or inconclusive

Webhook Integration

The RemediationPrWebhookHandler in the Signals module detects remediation PRs by:

  • Title convention: fix(CVE-XXXX-NNNNN): description
  • Label: stella-ops/remediation

Module Location

src/Remediation/
|- StellaOps.Remediation.Core/                  - Domain models, interfaces, services
|- StellaOps.Remediation.WebService/            - API endpoints, Program.cs
|- StellaOps.Remediation.Persistence/           - SQL migrations, repositories
|- __Tests/StellaOps.Remediation.Tests/         - Repository/domain unit tests
`- __Tests/StellaOps.Remediation.WebService.Tests/ - Source endpoint integration tests
  • SPRINT_20260220_010: Registry and persistence
  • SPRINT_20260220_011: Signals webhook handler
  • SPRINT_20260220_012: Verification pipeline
  • SPRINT_20260220_013: Matching, sources, policy
  • SPRINT_20260220_014: UI components
  • SPRINT_20260220_015: Documentation
  • docs/contracts/remediation-pr-v1.md

Advisory Gap Status (2026-03-04 Batch)

Status:

  • Advisory gap REM-001 is closed for marketplace sources.

Closed behaviors:

  • GET /api/v1/remediation/sources returns persisted tenant-scoped sources with deterministic ordering.
  • GET /api/v1/remediation/sources/{key} resolves persisted records (no unconditional stub source_not_found path).
  • POST /api/v1/remediation/sources performs validated upsert and no longer returns 501.
  • Marketplace source repository abstraction and implementation are wired through DI:
    • IMarketplaceSourceRepository
    • PostgresMarketplaceSourceRepository

Verification evidence:

  • dotnet test src/Remediation/__Tests/StellaOps.Remediation.Tests/StellaOps.Remediation.Tests.csproj -m:1 -v minimal - 28 passed.
  • dotnet test src/Remediation/__Tests/StellaOps.Remediation.WebService.Tests/StellaOps.Remediation.WebService.Tests.csproj -m:1 -v minimal - 4 passed.

Tracking sprint:

  • docs/implplan/SPRINT_20260304_308_Remediation_marketplace_sources_api_completion.md