leverage

package
v0.20.0-rc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 30, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package leverage is the neutral home for the cross-SSP leveraged-authorization projection and aggregation. It was extracted from internal/api/handler/oscal so that internal/api/handler (which oscal imports, not the other way round) can read the same leverage data without an import cycle — the compliance-progress endpoint (package oscal) and the lineage engine (package handler) both build on it.

It may import relational, relational/risks and converters/labelfilter; it must NOT import anything under internal/api.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AggregateByControl

func AggregateByControl(summaries []LinkSummary) map[ControlKey]ControlAggregate

AggregateByControl folds link summaries into per-control aggregates. Pure and unit-testable: statement-scoped and control-scoped links for the same control-id collapse into one ControlKey, statuses take the worst, satisfaction is full only if all links are full, counts sum, origins dedupe by (upstream SSP, offering), and Credit holds only when every link is active and full.

func BulkResolveUpstreamResponsibilities

func BulkResolveUpstreamResponsibilities(db *gorm.DB, providedUUIDs []uuid.UUID) (map[uuid.UUID][]Responsibility, error)

BulkResolveUpstreamResponsibilities is the batched resolver: two queries total regardless of how many providedUUIDs are requested, rather than two queries per item (the catalog list and the leveraged-controls projection each resolve responsibilities for many items/links in one request). The two-step lookup is unavoidable because ControlImplementationResponsibility and ProvidedControlImplementation are siblings under Export with no direct FK between them — only the shared OSCAL-level provided-uuid value — so responsibilities are scoped by (export_id, provided_uuid) pairs, not provided_uuid alone, since provided-uuid values are only unique within a single upstream's Export. providedUUIDs with no matching ProvidedControlImplementation row (e.g. the upstream row was since deleted) map to an empty slice, not an error or a missing key.

func DriftDedupeKey

func DriftDedupeKey(linkID uuid.UUID) string

DriftDedupeKey returns the dedupe key for the drift risk associated with a single SSPLeverageLink. One risk per leverage link: the link itself is the natural, deterministic scope (no risk template is involved, unlike evidence-driven risks), and the key is directly parseable back to the link that produced it without needing a separate link table. The "leverage-drift:%s" format keeps the drift writer (applyDriftToLink) and the projection reader in lockstep.

func NormalizeControlID

func NormalizeControlID(controlID string) string

NormalizeControlID folds a control-id to the canonical key form (trimmed, upper).

func ProjectForControl

func ProjectForControl(db *gorm.DB, controlID string) (map[uuid.UUID][]Projection, error)

ProjectForControl builds the Projection for every downstream SSP holding at least one leverage link for controlID (UPPER-folded match, no catalog id — the same keying every leverage read uses). It groups the links by downstream SSP and runs the same batched resolution projectLinks performs per SSP, so ResponsibilityPosture and the drift-risk lookup (both SSP-scoped) run once per involved downstream SSP — bounded by subscriber count, acceptable because this backs the drawer endpoint only. The returned map is keyed by downstream SSP id.

func ResponsibilityPosture

func ResponsibilityPosture(db *gorm.DB, downstreamSSPID uuid.UUID, responsibilityUUIDs []uuid.UUID) (map[uuid.UUID]string, error)

ResponsibilityPosture computes per-responsibility compliance posture (satisfied / not-satisfied / unknown) for a downstream SSP, using the same evidence status-count/collapse logic as control-keyed posture (relational.CollapseEvidenceStatus), but keyed by responsibility_uuid via filter_responsibilities instead of by (catalogId, controlId) via filter_controls (BCH-1339). Feeds the Inherited Capability projection so a downstream can see whether an inherited responsibility is actually backed by satisfying evidence, not just recorded as satisfied at subscribe time. Every requested uuid is always present in the returned map — defaulting to "unknown" when no filter targets it — never an absent key, matching BulkResolveUpstreamResponsibilities's convention.

Types

type ControlAggregate

type ControlAggregate struct {
	Links int
	// Credit is the inherited-credit rule at the leverage layer: ≥1 link AND every link
	// Status == active AND every link (live-derived) Satisfaction == full AND
	// TotalResponsibilities > 0. The last clause denies credit to a link whose upstream
	// responsibilities resolve to empty — a dangling link (upstream Provided/responsibility
	// rows deleted, so BulkResolve returns []) or a genuinely zero-responsibility offering
	// — which would otherwise silently inflate compliance before drift detection runs.
	// The evidence-wins and in-scope conditions are applied by the consumer, not here.
	Credit bool
	// Status is the worst link status: drifted > revoked > superseded > active.
	Status relational.SSPLeverageStatus
	// Satisfaction is full iff every link is full, else partial.
	Satisfaction relational.SSPLeverageSatisfaction
	// OutstandingCount and TotalResponsibilities are summed across links.
	OutstandingCount      int
	TotalResponsibilities int
	// InheritedFrom is the deduped set of upstream origins, in first-seen order.
	InheritedFrom []Origin
}

ControlAggregate is the per-control rollup of every leverage link sharing a ControlKey — the unit the compliance and lineage surfaces read.

type ControlKey

type ControlKey struct {
	SSPID     uuid.UUID
	ControlID string
}

ControlKey identifies a (downstream SSP, control-id) pair. ControlID must be UPPER-folded and trimmed via NormalizeControlID before use as a key — leverage links are matched by control-id alone (no catalog id), the established precedent shared with implStatusBySSP and implemented requirements.

type LinkSummary

type LinkSummary struct {
	LinkID          uuid.UUID
	DownstreamSSPID uuid.UUID
	UpstreamSSPID   uuid.UUID
	OfferingID      uuid.UUID

	UpstreamSSPTitle string
	OfferingTitle    string
	OfferingVersion  int

	ControlID   string // as stored (casing preserved); folded only when aggregating
	StatementID *string

	Status       relational.SSPLeverageStatus
	Satisfaction relational.SSPLeverageSatisfaction

	OutstandingCount      int
	TotalResponsibilities int
}

LinkSummary is one leverage link reduced to what the cross-SSP compliance and lineage read surfaces need: the identity of the link, the upstream it came from (with resolved titles), its lifecycle Status, and its LIVE-derived Satisfaction and responsibility counts. Satisfaction is recomputed from the current satisfied rows via DeriveSatisfaction — never the link's stored satisfaction column, which can rot when the upstream changes its responsibility set.

func Summarize

func Summarize(db *gorm.DB, sspID *uuid.UUID) ([]LinkSummary, error)

Summarize builds a LinkSummary for every leverage link, live-deriving satisfaction, in ~7 bulk queries regardless of link count. sspID nil summarizes every downstream SSP (lineage global scope); non-nil restricts to that one downstream SSP.

It is deliberately lighter than Project: no per-responsibility posture and no drift risk id (those back the drawer/detail views, not the counts), so it stays cheap enough to run on every lineage engine build.

type Origin

type Origin struct {
	UpstreamSSPID    uuid.UUID
	UpstreamSSPTitle string
	OfferingID       uuid.UUID
	OfferingTitle    string
	OfferingVersion  int
}

Origin is one upstream capability an inherited control draws from, deduped by (UpstreamSSPID, OfferingID) within a ControlAggregate.

type Projection

type Projection struct {
	Link          relational.SSPLeverageLink
	OfferingTitle string
	ByComponentID uuid.UUID
	// Inherited is the downstream's own InheritedControlImplementation row this link
	// created; nil only if it has since been deleted out from under the link.
	Inherited    *relational.InheritedControlImplementation
	Satisfaction relational.SSPLeverageSatisfaction
	Outstanding  []Responsibility
	// Responsibilities is the FULL upstream responsibility set under this link (uuid +
	// description), so downstream surfaces can label every responsibility — including
	// ones already satisfied — with the upstream's own text. Outstanding is the subset
	// of this with no matching downstream satisfied entry.
	Responsibilities []Responsibility
	Posture          map[uuid.UUID]string
	DriftRiskID      *uuid.UUID
}

Projection is one downstream leverage link with everything the read models need already resolved: the live-recomputed satisfaction (never the link's cached value), the outstanding responsibilities, the evidence-backed posture, the open drift risk, the offering title, and the by-component + inherited row the link hangs off.

Both the /leveraged-controls endpoint and the shared-responsibility rollup read this, so satisfaction is derived in exactly one place and neither surface can drift from the other. oscal aliases leveragedControlProjection to it.

func Project

func Project(db *gorm.DB, sspID uuid.UUID) ([]Projection, error)

Project builds the Projection for every leverage link on one downstream SSP in six queries at THIS level, independent of link count — the batching that replaced this code's original four-queries-per-link loop, preserved here so no caller can regress it into an N+1. In particular the ResponsibilityPosture(db, sspID, allResponsibilityUUIDs) call below must stay a single call for every uuid, never one per link.

The end-to-end cost is ~6 + N, not six: ResponsibilityPosture finishes with a per-responsibility loop (relational.EvidenceStatusCountsForFilters) that issues one evidence aggregate — count(DISTINCT uuid) grouped by status->>state, over the latest-evidence-stream subquery and the label-filter joins — for every responsibility carrying at least one FilterResponsibility link. Those N queries are the expensive ones, and both /leveraged-controls and GET /:id/shared-responsibility pay them. Hoisting that loop rewrites evidence aggregation and belongs in its own change.

type Responsibility

type Responsibility struct {
	ResponsibilityUUID uuid.UUID `json:"responsibilityUuid"`
	Description        string    `json:"description"`
}

Responsibility is the minimal upstream-responsibility shape both the catalog exposure and the subscribe/projection paths need: enough to let a downstream subscriber pick specific responsibility UUIDs to satisfy, and to compute full/partial coverage. Its JSON tags are the wire contract (responsibilityUuid, description); oscal aliases upstreamResponsibility to it so those surfaces are unchanged.

func DeriveSatisfaction

func DeriveSatisfaction(full []Responsibility, satisfiedUUIDs map[uuid.UUID]bool) (relational.SSPLeverageSatisfaction, []Responsibility)

DeriveSatisfaction is the single definition of "full iff every upstream responsibility has a matching downstream satisfied" (vacuously full when full is empty), shared by Subscribe (computing the satisfaction to store on a new leverage link) and every read path (recomputing it live rather than trusting the stored value). Returns the subset of full not covered by satisfiedUUIDs as outstanding.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL