Repository navigation
feat: add SRAC document validation foundation - #3271
devashridatta-dotcom wants to merge 3 commits into
Conversation
Signed-off-by: Devashri Datta <devashri.datta@gmail.com>
|
@gaganhr94 Thank you for encouraging this prototype and suggesting a fork-based implementation. The experimental read-only SRAC ingestor is now ready for maintainer review. Could you please review it, or have a GUAC maintainer add you as the formal reviewer? GitHub did not allow me, as a fork author, to use the reviewer-assignment control. |
|
The experimental SRAC ingestion prototype is working for the defined MVP scope. The following tests pass locally: Validated behavior includes:
Therefore, the prototype demonstrates that GUAC can parse and preserve externally authored SRAC safety context without creating or approving safety decisions. Current limitation: the SRAC document is ingested directly. Automatic discovery through a CycloneDX I would appreciate maintainer feedback on whether this separate-parser architecture is suitable for the MVP. |
|
Thanks, Gagan. This is very helpful and aligns with the two-stage path I had in mind. This draft PR currently implements the first case: a separate SRAC parser using the existing ingestion flow. For the initial prototype, I used product-scoped Based on your feedback in #3256, I propose evolving the MVP toward a dedicated safety-assertion model:
Later, the SPDX and CycloneDX parsers could map their native safety representations into the same internal model, avoiding separate query behavior for each input format. For the first reviewable MVP, would you recommend:
My preference is GraphQL first, followed by REST only if there is a concrete endpoint requirement. |
|
The proposed first-class database and GraphQL model has been separated into design draft #3272. This keeps this parser prototype reviewable while maintainers confirm the ontology and backend scope. |
Signed-off-by: Devashri Datta <devashri.datta@gmail.com>
|
CI follow-up:
A fresh CI run has been triggered by the formatting fix. I have not changed the unrelated deps.dev test. |
gaganhr94
left a comment
There was a problem hiding this comment.
@devashridatta-dotcom Thanks for putting this together, the parsing and validation pieces are a reasonable starting point.
As discussed in #3256 and agreed in the maintainers meeting, SRAC assertions need their own storage and ontology rather than being projected into HasMetadata. HasMetadata is a generic key/value predicate. Packing the component, classification, evidence, and review state into a JSON string means:
- the component is never a node in the graph, so "what is the safety context for component X" can't be answered by a graph query, only by fetching every product's metadata and parsing the JSON client-side
- none of the fields (status, reviewer, classification, evidence digests) are queryable or filterable
| digest := sha256.Sum256(doc.Blob) | ||
| documentDigest := hex.EncodeToString(digest[:]) | ||
|
|
||
| for _, assertion := range parsed.Assertions { |
There was a problem hiding this comment.
srac.Correlate is never called from the ingestion path, so none of the matched/unmatched/ambiguous/invalid handling runs. Every valid assertion is ingested, and PkgMatchTypeSpecificVersion will create the product package node even if it doesn't exist in the graph yet. The PR description and docs say correlation is enforced, but it's only reachable from unit tests. In the reworked design this probably belongs in the certifier for out-of-order ingestion, but either way it has to be wired in.
| func Correlate(assertion Assertion, candidates []Candidate) CorrelationResult { | ||
| var identifierMatches []Candidate | ||
| for _, candidate := range candidates { | ||
| if candidate.ProductPURL != assertion.Product.PURL || candidate.ComponentPURL != assertion.Component.PURL { |
There was a problem hiding this comment.
Raw string comparison of pURLs will miss equivalent pURLs that differ only in qualifier order, type case, or encoding. Please normalize both sides (e.g. packageurl.FromString(...).ToString()) before comparing, the same way the rest of GUAC canonicalizes pURLs.
| for _, candidate := range identifierMatches { | ||
| if digestsMatch(assertion.Component.Digests, candidate.Digests) { | ||
| matches = append(matches, candidate) | ||
| } else if len(assertion.Component.Digests) > 0 { |
There was a problem hiding this comment.
If the candidate has no digest data at all, this reports invalid ("digest mismatch"). Missing data and conflicting data should be different outcomes. I'd expect unmatched (or a separate unknown state) when the candidate has no digests to compare.
|
Addressed the review direction in commit 616a53d: removed the HasMetadata projection and unwired correlation path, added canonical pURL handling, and narrowed this PR to SRAC document validation. Graph ingestion and correlation will be implemented through the certifier after the first-class ontology in #3272 is approved. |
Summary
Adds an experimental, read-only SRAC ingestion path to make the product-context use case in #3256 concrete.
The prototype:
0.2-draftSRAC JSON documents;matched,unmatched,ambiguous, andinvalidcorrelation states;HasMetadatawith keysrac.safety-relevance; andThe
HasMetadatarepresentation is intentionally experimental so maintainers can evaluate the workflow without committing GUAC to a permanent ontology change.Demonstration
docs/examples/srac/product-context.srac.jsoncontains two synthetic products using the same component:safety-related/ASIL-B;not-safety-related.docs/srac.mddocuments the correlation contract and an existingHasMetadataquery for retrieving the product-scoped assertions.Validation
All listed packages pass locally. Tests cover schema validation, product-context separation, matched, unmatched, ambiguous, digest-mismatch, document guessing, provenance preservation, and parser integration.
Scope
This PR does not add a native safety predicate to the GUAC ontology and does not claim that SRAC semantics are finalized. It is a small prototype for maintainer feedback on the ingestion extension point and graph representation.
Closes #3256 only if maintainers consider the prototype sufficient; otherwise, relates to #3256.