Skip to content

feat(supply-chain): exact-version license evidence and assessments - #108

Merged
balcsida merged 5 commits into
feat/supply-chain/m1-uifrom
feat/supply-chain/m2-license-core
Sep 22, 2026
Merged

balcsida merged 5 commits into
feat/supply-chain/m1-uifrom
feat/supply-chain/m2-license-core

Conversation

@balcsida

@balcsida balcsida commented Sep 22, 2026 •

Copy link
Copy Markdown
Owner

Summary

Milestone 2. Depends on #107.

  • SPDX expression parser (internal/supplychain/spdxexpr) – bounded grammar (size/token/depth limits) over the embedded SPDX License List 3.27.0; preserves AND/OR/grouping/+/WITH/LicenseRef/DocumentRef and written order; NOASSERTION, NONE, UNLICENSED, unknown identifiers, and free text stay explicit statuses and are never mapped to a license. Fuzzed (normalized round-trip).
  • Resolvers (npm, NuGet, Maven) – only through routes from GRAPHNEST_SUPPLY_CHAIN_REGISTRY_* (secret-file credentials, optional CA, opt-in private hosts, namespace restriction). Fetcher pins origin + base path (redirects elsewhere rejected), blocks private/link-local/metadata addresses by default, bounds decompressed bodies, rejects hostile path segments, attaches credentials only to the route's origin. No route ⇒ no outbound license traffic; a private route never falls back to a public registry.
    • npm: exact version document only (never dist-tags); SEE LICENSE IN, legacy objects/arrays, UNLICENSED recorded as what they are.
    • NuGet: exact nuspec; expression vs file vs legacy licenseUrl preserved; the nupkg is never downloaded.
    • Maven: exact POM; bounded parent/property resolution with cycle detection; unresolved inheritance stays unknown; only unambiguous names normalized; repository declarations never followed.
  • Evidence & assessments – immutable evidence rows (raw value, parse status, resolver/list versions, content hash, outcome; identical re-fetches are new observations flagged duplicate; outages keep earlier resolved evidence with its age; negatives expire after 24h); deterministic per-occurrence assessment with conflict detection; enrichment worker queued at publication; GET .../component?element= evidence detail reachable only through an authorized occurrence.
  • UI – assessed-license column (never inferred from the declared value) and an evidence panel. Migration 034. Helm route values + Secret mounts; docs.

Verification

Resolver tests against fake TLS registries (exact-version mismatch, private/public same-name isolation, omitted origin, parent cycles, invalid expressions, outage, cross-origin/base-path redirects, oversized and gzip-bomb bodies, private-address denial, untrusted certificate, hostile names, credentials never in evidence, no traffic without routes). Assessment truth table. Store integration tests (immutability, route scoping, TTL, leases). End-to-end integration through PostgreSQL and REST.

Implications

  • Migration: 034 additive.
  • Security/egress: see above; documented in the threat model and operations guide.

Part of the Dependencies & Licenses stack (native GitHub stack #114, ten layers, main ← #104 ← #105 ← #106 ← #107 ← #108 ← #109 ← #110 ← #111 ← #112 ← #113). Design: ADR-0017; living plan with the full validation table: docs/execplans/supply-chain.md. All commits are SSH-signed. Nothing here calls a live GitHub Enterprise Server or a live package registry; GitHub and registry behavior is exercised against fixtures and fake servers only.

Stack created with GitHub Stacks CLI

@balcsida
balcsida added this pull request to stack #114 September 22, 2026 21:06
@balcsida balcsida changed the title feat/supply chain/m2 license core feat(supply-chain): exact-version license evidence and assessments Sep 22, 2026
@balcsida
balcsida force-pushed the feat/supply-chain/m2-license-core branch 2 times, most recently from 9fdb200 to 76df41b Compare September 22, 2026 22:19
@balcsida
balcsida marked this pull request as ready for review September 22, 2026 22:20
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

balcsida and others added 5 commits September 23, 2026 00:29
Parse SPDX 2.3 expressions into a tree that keeps AND, OR, grouping,
"+", WITH exceptions, LicenseRef/DocumentRef identifiers, and written
order, against the embedded SPDX License List 3.27.0. NOASSERTION, NONE,
UNLICENSED, unknown identifiers, and free text stay explicit statuses
and are never mapped to a license. Input size, token count, and nesting
depth are bounded; a fuzz target checks normalized round-trips.

Co-Authored-By: Claude <noreply@anthropic.com>
…gured registries

Add route-bound resolvers for npm (exact version document, never
dist-tags; SEE LICENSE IN, legacy objects, UNLICENSED kept as what they
are), NuGet (nuspec expression vs file vs legacy licenseUrl; no nupkg
download), and Maven (POM declarations with bounded parent/property
resolution, cycle detection, unresolved inheritance kept unknown, only
unambiguous names normalized). Routes come only from
GRAPHNEST_SUPPLY_CHAIN_REGISTRY_* configuration with secret-file
credentials and optional CA; the fetcher pins origin and base path,
blocks private and metadata addresses unless allowed, bounds
decompressed bodies, and rejects hostile path segments. Migration 034
adds immutable evidence, enrichment jobs, and component assessments.

Co-Authored-By: Claude <noreply@anthropic.com>
… API

Add the enrichment worker that queues exact-coordinate lookups for every
published snapshot whose ecosystem has a configured route, stores
immutable evidence (identical re-fetches are new observations flagged as
duplicates; outages retain earlier resolved evidence with its age), and
rebuilds per-occurrence assessments with deterministic conflict
detection over declarations and registry evidence. Component pages carry
the assessment, status reports enrichment configuration and a license
summary, and a component detail route returns declarations, evidence
history, and relationships, reachable only through an authorized
occurrence. Wire routes, worker, and metrics into the server.

Co-Authored-By: Claude <noreply@anthropic.com>
Explain registry route configuration, per-resolver behavior, evidence
immutability, negative-result expiry, assessment statuses, and the
security stance in the operations guide, README, threat model, and
CHANGELOG. Add Helm values, schema, ConfigMap rendering, Secret mounts,
and render tests for per-ecosystem routes and credentials.

Co-Authored-By: Claude <noreply@anthropic.com>
…ntory page

Add an assessed-license column with status pills that never infer an
expression from the declared value, a license summary card, the
enrichment configuration in the observation panel, and a component
evidence panel showing identity, assessment with fingerprint, producer
declarations, immutable registry evidence with resolver and license-list
versions, relationships, and notes. Selected elements are addressable in
the hash; DOM, contract, and screenshot fixtures follow the API enums.

Co-Authored-By: Claude <noreply@anthropic.com>
@balcsida
balcsida force-pushed the feat/supply-chain/m2-license-core branch from 76df41b to cd22e64 Compare September 22, 2026 22:30
@balcsida
balcsida force-pushed the feat/supply-chain/m2-license-core branch 2 times, most recently from 609206b to cd22e64 Compare September 22, 2026 23:51
@balcsida
balcsida merged commit 0def80c into main Sep 22, 2026
16 of 24 checks passed
@balcsida balcsida mentioned this pull request Sep 23, 2026
@balcsida
balcsida deleted the feat/supply-chain/m2-license-core branch September 23, 2026 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant