feat(rstix): Graph + Marking + Store and STIX 2.1 spec-exact closure - #327
Merged
mostafa merged 2 commits intoJul 17, 2026
Merged
Conversation
Add optional graph, marking, and store features; enforce wire MUST rules at parse; close remaining spec-audit differentials; refactor shared ref-path inventory; and parse MITRE ATT&CK bundles with allow_custom (x-mitre-* types and in-bundle custom ref kind checks).
Signed-off-by: Meghdad Shamsaei <meghdadshamsaei@gmail.com>
mostafa
approved these changes
Jul 17, 2026
mostafa
left a comment
Member
There was a problem hiding this comment.
@SecurityEnthusiast Thank you for your contribution! LGTM. 🚀
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
This PR completes the Graph + Marking + Store vertical slice for
rstixand closes the remaining STIX 2.1 spec-audit differentials (36/36 resolved). It adds three independent optional features (graph,marking,store/store-fs), enforces wire MUST rules at the defaultserdeparse boundary (Decision A), aligns the Validation Pipeline with advisory semantics, and refactors shared ref-path inventory out ofstix_object.rs.Graph (
graphfeature)StixGraph::from_bundle— zero-copy property graph over a parsedBundle.relationship(source → target) andsighting(sighting id →sighting_of_ref); full payloads viaSroEdgePayload/Edge::relationship()/Edge::sighting()._ref/_refsproperties (including nested SCO extension refs) with property paths.StixGraph::from(id).out_edges_matching(pred).targets_as::<T>(), plusout_refs/in_refs(including dangling targets).RelationshipExpander— multi-hop expansion from any start node or from anIndicatorId; collects identity, infrastructure, indicator, malware, threat-actor, campaign, attack-pattern, course-of-action, and vulnerability summaries.model/ref_paths.rs— path-aware ref inventory shared with bundle ref validation (~350 lines moved fromstix_object.rs;collect_internal_refs()delegates here).tests/graph.rs, fixtures undertests/fixtures/graph/.Marking (
markingfeature)TlpV2Level— all five predefined TLP 2.0 UUIDs;TLP:AMBER+STRICTvsTLP:AMBERwith distinctpermits_disclosure.TlpV1Level— legacy TLP 1.x ingestion for ATT&CK feeds (#[allow(deprecated)]on impl for-D warningsCI).MarkingResolver— indexesmarking-definitionobjects from a bundle:effective_for_object(most restrictive TLP wins)effective_for_property/effective_for_selector(granular selectors with JSON path resolution)permits_disclosure(audience)andEffectiveMarking::language_tagsmodel/validate.rssyntax rules and runs on custom object wire JSON whenallow_customis enabled.tests/marking.rs, fixtures undertests/fixtures/marking/.Store (
store/store-fsfeatures)StixStoretrait (object-safe) +MemoryStore:QueryCursor/next_cursor)delete,export_bundle,StixQuerybuilder (text_search,modified_after, labels, …)id; UUIDv5 fingerprint reported viaFingerprintConflictinImportReport(never silently rewrites SCO ids).FsStore(store-fs) — durable JSON-on-disk store with atomic writes (temp file + rename).tests/store.rs,tests/store_fs.rs, fixtures undertests/fixtures/store/.STIX 2.1 spec-exact closure
Decision A — wire MUST at parse
Required workspace deps:
idna,email_address,url,base64,encoding_rs.domain-name.valueemail-addr.valueurl.valuehttp,https,ftp)SCO
*_enc(§3.1 / §3.9.1)file.name_enc,directory.path_enconly.validate_sco_string_encoding_pair+validate_extra_enc_pairingsfor any_enckeys inScoCommonProps::extra(IANA charset + pairing rules).vocab/iana_charset.rsclosed vocabulary helper.file-name-enc-without-name.json,file-name-enc-invalid.json,file-extra-enc-without-base.json,file-with-name-enc.json.Email-message (§6.6)
model/rfc2047.rs— RFC 2047 encoded-word decoding on ingest forsubject,message_id,body,received_lines,additional_header_fields._encsiblings (e.g. pattern fixturesubject_enc) remain incommon.extra;get_fieldreads them for pattern evaluation.Language-content (§7.1.1)
""list placeholders, unknown target fields silently ignored (no advisory).bundle-language-content-unknown-field.json(spec MUST ignore).Granular markings / custom objects (§7.2.3 / §11.2)
allow_customis enabled.Spec-audit items closed (previously open)
Bundle::validate()+ custom wire JSONBundle::validate()common.extra/MarkingDefinition.extra; fixtureidentity-standalone-extra.jsonobjectswith SROObservedDataEmbeddedObject::Sro; fixtureobserved-data-deprecated-objects-sro.jsonBundle::validate()SHOULD warningsBundle::validate()advisory*_encvalidate_extra_enc_pairings()forcommon.extraValidation Pipeline alignment
ScoEncWithoutBaseProperty/ScoEncInvalidCharset— property names carried in tagged wire errors; invalid charset maps to E0013 (closed vocab), not I0002.property_typesaligned to SHOULD warning (W0010), matchingBundle::validate().validate_diagnostic_coverage.rs— E0013 case for unknown opinion; encryption → W0010.validate_conformance.rs— language-content unknown-field fixture excluded per §7.1.1.Serialization conventions
BTreeMap(ExtensionMap,common.extra,LanguageContent.contents, SCOhashes,Bundle.extra_properties()values).HashMap(Bundle.id_index, graph adjacency, store buckets, marking resolver).docs/content/library/rstix.md.Documentation
crates/rstix/README.md— Graph/Marking/Store sections, wire-format validation, serialization map conventions, expanded testing layout, updated invariant table.docs/content/library/rstix.md— feature status, extensions, serialization conventions, full feature-flag table.docs/content/reference/architecture.md,feature-flags.md— Graph + Marking + Store complete; Validation Pipeline complete.CHANGELOG.md—[Unreleased]entry.Test plan
cargo fmt --all -- --checkcargo check --workspace --all-targets --all-features --lockedcargo clippy --workspace --all-targets --all-features --locked -- -D warningscargo test --workspace --all-features --lockedcargo +1.88.0 check --workspace --all-targets --all-features --lockedRUSTDOCFLAGS="-D warnings -D rustdoc::broken-intra-doc-links" cargo doc --workspace --all-features --locked --no-depscargo test -p rstix --features validate,serde,pattern,graph,marking,store,store-fs --lockedcd docs && npm ci && npm run docs:build && npm run docs:validatecargo llvm-cov --workspace --all-features --lockedzizmor --pedantic .github/workflows