I recently added Scaleway support to Cartography. The part I was most curious about was vulnerability management. Cartography already knows how to connect a CVE to a running container, its image, its source repository, and sometimes its owner. Would we have to teach it the same chain again for Scaleway, handling all of its specific data types?
It turned out that all we had to do was model the Scaleway resources correctly. Once the module said that a resource was a container, that it ran a particular image, and that the image came from a particular repository, the existing vulnerability queries could use it.
This is a small example of why we added an ontology to Cartography. It is also a useful way to explain what the ontology does, because “we added an ontology” is otherwise a fairly abstract claim.
Vulnerability management has been a Cartography use case for a long time. Lyft wrote about using Cartography for vulnerability management in 2020, and we covered container vulnerability management again in a 2023 BSidesSF talk.
A scanner gives you a CVE and a package. To do something with the finding, you usually need a few more facts:
The answers cross several data sources. Runtime data comes from the cloud provider or Kubernetes API, often both. Package and fix data comes from the scanner. Image provenance often comes from OCI metadata, and ownership may come from CODEOWNERS. Cartography's job is to put those facts in one graph.
Before the ontology work, queries often followed provider-specific node types.
An AWS query might start at an ECSTask, while another cloud would need a
different starting point and a different set of relationships. Adding a provider
could therefore mean adding another version of the analysis.
The Cartography
ontology
does not replace those provider-specific nodes. It adds shared concepts to them.
A ScalewayServerlessContainer can still contain the fields returned by
Scaleway's API while also participating in the more general Container concept.
Queries that only care that something is a container can use the shared label.
The Scaleway integration imports serverless containers, registries, and images. There are two relationships that matter most for this example.
The first is the relationship between a running container and its image. Scaleway
configures a container with an image tag, but tags can move. The registry module
resolves the tag to a digest and creates RESOLVED_IMAGE, so a query can work with
the image that is actually running.
The second is PACKAGED_FROM. The registry module reads OCI metadata and, when
the build has recorded its source, connects the image to a code repository.
After those edges exist, the vulnerability path uses data that was already in the graph. Trivy connects CVEs to affected images and packages. It records a fixed package version when one is available. GitHub ingestion can connect a repository to its CODEOWNERS rules and owners.
None of this means Scaleway has a special vulnerability management feature. The
Scaleway module describes its resources and how they connect to an image. The
vulnerability query works with the shared Container, Image, Package, and
CodeRepository concepts.
The diagram below came from the original Cartography draft. It is a schematic of the relationships involved, not customer data or a dump of one tested graph.

The useful shape is the path through it. Starting from a CVE, the graph can lead
to an affected image and package. A running container resolves to the same image,
which tells us the image is in use. When Trivy has remediation data, the package
can also point to a fixed version with SHOULD_UPDATE_TO.
In the other direction, PACKAGED_FROM connects the image to the repository that
built it. If the repository is on GitHub and Cartography has ingested CODEOWNERS,
the matching rule can point to an owner. That last part is conditional. A graph
cannot derive ownership data that was never provided.
Here is a simplified version of the Cypher. There is no reference to a Scaleway node type in it:
MATCH (c:CVE {cve_id: $cve_id})
MATCH (c)-[:AFFECTS]->(img:Image)
MATCH (ctr:Container)-[:RESOLVED_IMAGE]->(img)
WHERE toLower(ctr._ont_state) = 'running'
OPTIONAL MATCH (c)-[:AFFECTS]->(pkg:Package)
OPTIONAL MATCH (pkg)-[:SHOULD_UPDATE_TO]->(fix:TrivyFix)-[:APPLIES_TO]->(c)
OPTIONAL MATCH (img)-[:PACKAGED_FROM]->(repo:CodeRepository)
OPTIONAL MATCH (repo)-[:HAS_CODEOWNER_RULE]->(rule)-[:CODEOWNER]->(owner)
RETURN c, img, ctr, pkg, fix, repo, rule, owner
The query will also work for another provider whose running resources participate
in the Container concept and resolve to an Image. Provider-specific details
still matter during ingestion; they do not have to leak into every analysis that
uses the data afterward.
Scaleway support is useful, but the interesting part is what did not change. We did not add a Scaleway vulnerability pipeline or write another set of correlation queries. We taught Cartography how Scaleway resources map onto concepts the rest of the graph already understands, and the existing analysis kept working.
That is a useful constraint to keep. If every new provider needs its own logic for joining findings to workloads, images, repositories, and owners, provider coverage and security analysis are coupled. The system gets larger and more fragile with every integration. When the concepts are genuinely shared, model them once and keep the provider-specific work at the ingestion boundary. The cross-cloud permission work arrived at the same idea: the reasoning lives above the provider, so new providers can inherit it.
Two practical things follow.
You can use this approach in Cartography today. Connect your clouds, ingest Trivy results and source-control data, and run the query above. For workloads connected to the shared container and image model, it can show where a vulnerable image is running, where its code came from, whether a fix exists, and, when ownership data is present, who owns it. When the graph cannot answer one of those questions, the missing edge tells you which integration is incomplete.
If you want the result without maintaining all of that plumbing yourself, this is what SubImage’s vulnerability management is built to do. It connects scanner findings to what is actually running, the source repository, the available fix, and the team that owns it. Instead of rebuilding that context for every CVE, your security team can start with the vulnerabilities that affect deployed systems and the people who can fix them.
And if Cartography does not support your provider yet, adding it does not mean rewriting the vulnerability analysis. A provider module ingests its resources and attaches them to the shared concepts where they fit. A genuinely different runtime model may require extending the ontology, but that is different from copying the whole analysis stack. The developer guide walks through building a module, and missing providers are some of the most useful contributions to pick up.
Come add your cloud!