Files
git.stella-ops.org/docs/modules/concelier/prep/2025-11-20-policy-linkset-prep.md
master d519782a8f
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
prep docs and service updates
2025-11-21 06:56:36 +00:00

3.1 KiB
Raw Blame History

Concelier · Policy Engine Linkset API Prep

  • Date: 2025-11-20
  • Scope: PREP-CONCELIER-POLICY-20-001 (LNM APIs not exposed via OpenAPI)
  • Working directory: src/Concelier/StellaOps.Concelier.WebService

Goal

Freeze the contract Policy Engine will consume for advisory lookups without inference/merges, and locate where the OpenAPI surface must be updated so downstream Policy tasks can begin.

API surface to expose

  • Endpoint: GET /v1/lnm/linksets
    • Query params:
      • purl (repeatable), cpe, ghsa, cve, advisoryId, source (nvd|ghsa|osv|vendor:), severityMin, severityMax, publishedSince, modifiedSince, tenant (header enforced, not query), page (default 1), pageSize (default 50, max 200), sort (publishedAt|modifiedAt|severity desc|source|advisoryId; default modifiedAt desc).
    • Response: deterministic ordering; body fields = advisoryId, source, purl[], cpe[], summary, publishedAt, modifiedAt, severity (source-native), status (facts only), provenance (ingestedAt, connectorId, evidenceHash, dsseEnvelopeHash?), conflicts[] (raw disagreements, no merged verdicts), timeline[] (raw timestamps + hashes), remarks[] (human notes, optional).
  • Endpoint: GET /v1/lnm/linksets/{advisoryId}
    • Mirrors above fields; adds normalized block for any canonicalized IDs; cached flag already added in Sprint 110.B endpoint work.
  • Endpoint: POST /v1/lnm/linksets/search
    • Accepts body with same filters as query params plus boolean includeTimeline, includeObservations (default false). Must respect tenant guard and AOC (no inferred verdicts or merges).

OpenAPI tasks

  • Source file location: src/Concelier/StellaOps.Concelier.WebService/openapi/concelier-lnm.yaml (to be created / updated alongside code) and published copy under docs/api/concelier/.
  • Add components:
    • LinksetProvenance object (ingestedAt, connectorId, evidenceHash, dsseEnvelopeHash?).
    • LinksetConflict object (source, field, observedValue, observedAt, evidenceHash).
    • LinksetTimeline object (event, at, evidenceHash, dsseEnvelopeHash?).
  • Pagination envelope: { "items": [...], "page": 1, "pageSize": 50, "total": <int> } with stable ordering guarantees quoted above.
  • Security: Tenant header required; bearer/mtls unchanged from existing WebService.

Determinism & AOC guards

  • Responses must never include merged severity/state; surface only source-provided facts and conflicts.
  • Sorting: primary modifiedAt desc, tie-breaker advisoryId asc, then source asc for deterministic pagination.
  • Cache: the /linksets/{advisoryId} endpoint may serve cached entries but must include cached: true|false and provenance.evidenceHash so Policy Engine can verify integrity.

Deliverable

  • This prep note is the canonical contract for policy-facing LNM APIs until the OpenAPI source is committed at the path above.
  • Downstream tasks (POLICY-ENGINE-20-001 and linked Policy Engine sprints) should bind to these fields; any deviations must update this prep note and the sprints Decisions & Risks.