feat(supply-chain): SPDX and CycloneDX imports with derived SPDX export - #110
Merged
balcsida merged 2 commits intoSep 22, 2026
Merged
Conversation
balcsida
added this pull request to stack #114
September 22, 2026 21:06
balcsida
force-pushed
the
feat/supply-chain/m4-imports
branch
2 times, most recently
from
September 22, 2026 22:19
566a255 to
1b896b8
Compare
balcsida
marked this pull request as ready for review
September 22, 2026 22:20
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
…rived SPDX Accept authenticated SPDX 2.3 JSON and CycloneDX 1.6 JSON uploads into declared import streams of an authorized repository. The format is detected from the document, unsupported versions and contradictory content types are rejected explicitly, original bytes are preserved, the uploader is recorded separately from the claimed producer, and a supplied subject revision is bound only as producer_asserted. Identical bytes are idempotent, per-repository quotas apply, and non-administrators need a repository-scoped upload grant. The CycloneDX normalizer keeps nested components, dependencies, hashes, and license choices as the format carries them and warns about evidence it cannot carry. A derived SPDX export names GraphNest as creator, links the preserved original by URL and hash, carries assessments as comments only, and is validated by the same reader. Migration 035 adds imports and upload grants. Co-Authored-By: Claude <noreply@anthropic.com>
…exports Co-Authored-By: Claude <noreply@anthropic.com>
balcsida
force-pushed
the
feat/supply-chain/m4-imports
branch
from
September 22, 2026 22:30
1b896b8 to
26fbe20
Compare
balcsida
force-pushed
the
feat/supply-chain/m4-imports
branch
from
September 22, 2026 22:59
26fbe20 to
51a70e6
Compare
balcsida
force-pushed
the
feat/supply-chain/m4-imports
branch
from
September 22, 2026 23:51
51a70e6 to
26fbe20
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Milestone 4. Depends on #109.
POST /v1/supply-chain/imports– SPDX 2.3 JSON and CycloneDX 1.6 JSON only; format detected from the document (a contradictingContent-Typeis rejected), other formats/versions rejected with415 unsupported_format. Each(subject, label)is its ownimport:<subject>:<label>stream, so a container SBOM never replaces the GitHub observation and an old artifact upload never becomes the current source inventory. Original bytes preserved; uploader recorded separately from the claimed producer (aTool: ORTstring grants nothing); an optionalsubject_revisionis bound only asproducer_asserted; idempotent on identical bytes; per-repository quota; non-administrators need a repository-scoped upload grant (PUT /v1/supply-chain/upload-grants). External URLs inside documents are never dereferenced.CONTAINSedges,dependencies→DEPENDS_ON, hashes, suppliers, purl qualifiers; license choices kept as the format carries them (a list of license objects has no AND/OR meaning and is kept as a list with a warning); componentevidenceand inline license text stay only in the preserved original and are flagged (evidence_not_carried,license_text_inline). Fuzzed.GET /v1/supply-chain/exports/{id}/derived.spdx.json– GraphNest as creator, links the preserved original by URL + SHA-256 (externalDocumentRefs), assessments only aslicenseComments,licenseConcludedalwaysNOASSERTION, validated by GraphNest's own reader before serving. The original download is never altered.Verification
Integration tests: real-format round trips for both formats, stream separation, uploader vs claimed producer, spoofed GitHub tool string lands only in an import stream, producer-asserted binding, idempotency, quota per repository, permission matrix (admin / granted / ungranted / reader / unknown repo), explicit rejections (old versions, mismatched claim, unknown format, malformed, bad label/subject/revision, wrong media type), derived export structure and original preservation.
Implications
uploaded_by/upload_labelon snapshots).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