Model the multi-arch index ↔ per-architecture child manifest relationship - #219
Conversation
Add an ImageIndexObserved event kind that records the multi-arch
relationship between an image index (manifest list) and its per-platform
child manifests, and index it as an index -[:HAS_PLATFORM {os,
architecture, variant}]-> child edge.
- schema + example (image-index-observed)
- HAS_PLATFORM rel table + _index_image_index_observed indexer
- queries.platforms() / queries.index_of() helpers
- build-graph-event ImageIndexObserved kind (platforms input)
- stage-image-index-events composite action, wired into _mirror-image
and the three promote workflows
- indexer/queries tests + observability event-table docs
Fixes #216
There was a problem hiding this comment.
Pull request overview
Introduces a new ImageIndexObserved event and corresponding HAS_PLATFORM relationship in the supply-chain graph to model multi-arch image indices (manifest lists) and their per-platform child manifests, enabling graph queries to connect per-platform attestations/referrers back to the index lineage.
Changes:
- Adds an
ImageIndexObservedJSON schema + example and updates docs to include the new event kind in relevant workflows. - Extends graph storage/modeling with a
HAS_PLATFORMrel table and indexer support to materialize index → child edges with platform metadata. - Adds query helpers (
platforms(),index_of()) plus unit tests, and wires a new composite action into mirror/promote workflows to stage the new events.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| supply-chain-graph/schema/image-index-observed.schema.json | New schema for ImageIndexObserved events (index ↔ child manifests + platform metadata). |
| supply-chain-graph/examples/image-index-observed.yaml | Example ImageIndexObserved record for local validation/indexing tests. |
| docs/architecture/observability/supply-chain-graph.md | Documents ImageIndexObserved as produced by mirror/promote workflows. |
| apps/python-app/libs/cssc_graph/cssc_graph/graph.py | Adds HAS_PLATFORM relationship table to the graph schema. |
| apps/python-app/libs/cssc_graph/cssc_graph/indexer.py | Indexes ImageIndexObserved events into HAS_PLATFORM edges. |
| apps/python-app/libs/cssc_graph/cssc_graph/queries.py | Adds platforms() and index_of() query helpers for index/child traversal. |
| apps/python-app/libs/cssc_graph/tests/test_indexer.py | Verifies ImageIndexObserved indexing creates HAS_PLATFORM edges. |
| apps/python-app/libs/cssc_graph/tests/test_queries.py | Adds tests for platforms() and index_of() query helpers. |
| .github/actions/stage-image-index-events/action.yml | New composite action to discover index children via crane manifest and stage ImageIndexObserved. |
| .github/actions/build-graph-event/action.yml | Adds support for building ImageIndexObserved event JSON records. |
| .github/workflows/_mirror-image.yml | Stages index→platform events after mirroring when a digest is resolved. |
| .github/workflows/_promote-from-quarantine.yml | Stages index→platform events after promotion. |
| .github/workflows/_promote-from-quarantine-sbom.yml | Stages index→platform events after promotion (SBOM variant). |
| .github/workflows/_promote-override.yml | Stages index→platform events after override promotion approval. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Note: capture is wired into the acquire + catalog workflows. Wiring |
- indexer: index the required observedAt directly (fail fast, no silent '') - stage-image-index-events: exit cleanly when jq is missing too - queries.index_of: order by observedAt DESC for a stable result
What
Introduces an
ImageIndexObservedsupply-chain-graph event kind that captures the multi-arch relationship between an image index (manifest list) and its per-platform child manifests, and indexes it as:This closes the modeling gap where promote/build lineage points at the index digest while per-platform attestations attach to the child manifests, leaving referrer subjects disconnected from the rest of the graph.
Changes
image-index-observed.schema.json+ example (occurrence{registry,repository},index{digest,tag?},platforms[]{digest,os,architecture,variant?}minItems 1,observedAt).HAS_PLATFORMrel table ingraph.py;_index_image_index_observedmerges the index + each child occurrence and the platform edge.queries.platforms()(children of an index) andqueries.index_of()(child → owning index) helpers.build-graph-eventgains theImageIndexObservedkind (newplatformsargjson input); newstage-image-index-eventscomposite action readscrane manifestand stages one event per multi-arch index. Wired into_mirror-imageand the three promote workflows after copy/promote.platforms()/index_of()query tests. 51 cssc_graph + 18 graph-service tests pass.Rolling per-platform referrers up to the index (so attestations surface on the image) is tracked separately in #217.
Fixes #216