Skip to content

Conversation

@josemazo
Copy link

WhatIsACore and others added 30 commits December 18, 2025 02:27
fix broken links in tailscale schema documentation (`/` before
`https://` that breaks navigation)

### Summary
remove instances of `/` from before `https://` in schema.md



### Related issues or links
> Include links to relevant issues or other pages.

- https://github.com/cartography-cncf/cartography/issues/...


### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [ ] Update/add unit or integration tests.
- [ ] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

If you are changing a node or relationship:
- [ ] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [ ] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [ ] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Kunaal Sikka <kunaal@subimage.io>
Only fix a missing value in Module enum in rules.

---------

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
## Description
Implements support for tracking GitHub branch protection rules in Neo4j,
enabling security teams to identify repositories with weak branch
protection configurations.

**Note:** This PR implements protected branches only(partial
implementation of #2069).


## Changes
- **Data Model**: Created `GitHubProtectedBranch` node schema with 15
properties tracking protection settings
- **GraphQL Query**: Added `branchProtectionRules` to GitHub repository
query (fetches up to 50 rules per repo)
- **Transformation**: Added `_transform_protected_branches()` to convert
GitHub API format (camelCase) to Python/Neo4j format (snake_case)
- **Loading**: Added `load_protected_branches()` to create nodes and
`(GitHubRepository)-[:PROTECTS]->(GitHubProtectedBranch)` relationships
- **Cleanup**: Added `cleanup_protected_branches()` to remove stale
protection rules
- **Tests**: Added 5 unit tests and 1 integration test with
comprehensive coverage

## Files Changed
- `cartography/models/github/protected_branches.py` - New data model
- `cartography/intel/github/repos.py` - GraphQL query, transformation,
loading, cleanup
- `tests/data/github/protected_branches.py` - Test fixtures
- `tests/data/github/repos.py` - Added test data with
branchProtectionRules
- `tests/unit/cartography/intel/github/test_protected_branches.py` - New
unit tests
- `tests/unit/cartography/intel/github/test_repos.py` - Integration unit
test
- `tests/integration/cartography/intel/github/test_repos.py` - Neo4j
integration test

## Test Plan

### Unit Tests 
<img width="1139" height="443" alt="Screenshot 2025-12-17 at 11 23
05 PM"
src="https://github.com/user-attachments/assets/08768358-0824-4ad8-83e0-19fb278334c2"
/>

### Integration Test
<img width="1139" height="523" alt="Screenshot 2025-12-17 at 11 23
30 PM"
src="https://github.com/user-attachments/assets/e8a2f2e5-1afd-4e13-8187-3ad1588c54a2"
/>

### Query
<img width="1615" height="335" alt="Screenshot 2025-12-17 at 11 30
28 PM"
src="https://github.com/user-attachments/assets/7821e861-5d1c-4617-aaa5-ff5db167a8e7"
/>
<img width="1615" height="522" alt="Screenshot 2025-12-17 at 11 29
48 PM"
src="https://github.com/user-attachments/assets/a62a7afe-5c72-40ae-a1cc-cffedb7295ce"
/>

---------

Signed-off-by: Dang Pham <dangpham@Dangs-MacBook-Air.local>
Co-authored-by: Dang Pham <dangpham@Dangs-MacBook-Air.local>
### Summary
Fail fast with a clear error when the Cloudflare sync runs without a
configured API token. Previously, the module would silently skip with an
info log, which could be confusing. Now it raises a `ValueError` with an
explicit error message.

### Related issues or links
- N/A (operational improvement)

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [ ] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

If you are changing a node or relationship:
- [ ] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [ ] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [ ] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary

When parsing `requirements.txt` files generated by pip-compile (or
similar tools), the current parser fails on common patterns like line
continuations and hash options:

```
annotated-types==0.7.0 \
               ~~~~~~~~^
packaging.requirements.InvalidRequirement: Expected end or semicolon (after version specifier)
```

```
--hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \
^
packaging.requirements.InvalidRequirement: Expected package name at the start of dependency specifier
```

This happens because pip-compile generates requirements with `\`
continuations and `--hash` options, but the parser passes raw lines
directly to `packaging.Requirement()` which doesn't understand pip
syntax.

**Solution:** GitHub's Dependency Graph API (`dependencyGraphManifests`)
already parses these files correctly server-side—it's the same data
source that Dependabot uses. This PR:

1. **Prefers dependency graph data when available** - This aligns
cartography with what Dependabot actually sees, giving more accurate and
comprehensive dependency information (including transitive dependencies
and multi-ecosystem support).

2. **Improves the fallback parser** - For repos without dependency graph
data (private repos, GitHub Enterprise without the feature, etc.), the
manual parser now handles line continuations and skips pip option lines
before parsing.

### Related issues or links

- Aligns cartography's dependency view with Dependabot's data source
- Fixes parsing failures for pip-compile style requirements.txt files

### Checklist

- [x] Update/add unit or integration tests.

Trace
```
INFO:app.sync:[github] INFO:cartography.sync:Starting sync with update tag '1765950318'
INFO:app.sync:[github] INFO:cartography.sync:Starting sync stage 'github'
INFO:app.sync:[github] INFO:cartography.intel.github.users:Syncing GitHub users
INFO:app.sync:[github] INFO:cartography.intel.github.users:Retrieving users from GitHub organization blah
INFO:app.sync:[github] INFO:cartography.intel.github.users:Retrieving enterprise owners from GitHub organization blah
INFO:app.sync:[github] INFO:cartography.intel.github.users:Loading 1 GitHub organization to the graph
INFO:app.sync:[github] INFO:cartography.intel.github.users:Loading 6 GitHub users to the graph
INFO:app.sync:[github] INFO:cartography.intel.github.users:Loading 0 GitHub users to the graph
INFO:app.sync:[github] INFO:cartography.intel.github.users:Cleaning up GitHub users
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubUser statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubUser statement #2
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job GitHubUser
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubUser statement #1
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job GitHubUser
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Syncing GitHub repos
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Retrieving repo collaborators for affiliation "DIRECT" on org "blah".
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Retrieving repo collaborators for affiliation "OUTSIDE" on org "blah".
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Processing 11 GitHub repositories
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 2 dependency manifests in bar
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 2 dependencies in bar
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 2 dependency manifests in baz
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 2 dependencies in baz
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 1 dependency manifests in foo
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 16 dependencies in foo
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 19 dependency manifests in boop
INFO:app.sync:[github] INFO:cartography.intel.github.repos:Found 344 dependencies in boop
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #2
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #3
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job Dependency
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #2
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #3
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job Dependency
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #2
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #3
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job Dependency
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #2
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed Dependency statement #3
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job Dependency
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #2
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job DependencyGraphManifest
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #2
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job DependencyGraphManifest
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #2
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job DependencyGraphManifest
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed DependencyGraphManifest statement #2
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job DependencyGraphManifest
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #2
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #3
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #4
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #5
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #6
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #7
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #8
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #9
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #10
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #11
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #12
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #13
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #14
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #15
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #16
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #17
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed github_repos_cleanup statement #18
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job github_repos_cleanup
INFO:app.sync:[github] INFO:cartography.intel.github.teams:Loading 0 GitHub team-repos to the graph
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #1
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #2
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #3
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #4
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #5
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #6
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #7
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #8
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #9
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed GitHubTeam statement #10
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job GitHubTeam
INFO:app.sync:[github] INFO:cartography.intel.github.commits:Starting GitHub commits sync for organization: blah
INFO:app.sync:[github] INFO:cartography.intel.github.commits:Processing 11 repositories in batches of 10
INFO:app.sync:[github] INFO:cartography.intel.github.commits:Processing batch 1: 10 repositories
INFO:app.sync:[github] INFO:cartography.intel.github.commits:Loading 8 relationships for batch
INFO:app.sync:[github] INFO:cartography.intel.github.commits:Loading 8 user-repository commit relationships
INFO:app.sync:[github] INFO:cartography.intel.github.commits:Processing batch 2: 1 repositories
INFO:app.sync:[github] INFO:cartography.graph.statement:Completed COMMITTED_TO statement #1
INFO:app.sync:[github] INFO:cartography.graph.job:Finished job COMMITTED_TO
INFO:app.sync:[github] INFO:cartography.intel.github.commits:Completed GitHub commits sync
INFO:app.sync:[github] INFO:cartography.sync:Finishing sync stage 'github'
INFO:app.sync:[github] INFO:cartography.sync:Finishing sync with update tag '1765950318'
```

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary
This PR builds on top of PR #1563  and includes the following changes:

* **Improves documentation** by adding missing elements across several
modules.
* **Enhances clarity** around naming conventions used in the data model,
with detailed notes added to relevant sections.
* **Adds a test** to detect missing references to module schemas in
`docs/root/usage/schema.md`.
* **Migrates 4 modules** to align with current naming conventions for
consistency and clarity.

### Not breaking changes (backward compatibility)
This PR introduces several **breaking changes** in graph relationships:
**DigitalOcean**
* `(:DOProject)<-[:RESOURCE]-(:DODroplet)` ➡️
`(:DOProject)-[:RESOURCE]->(:DODroplet)`
* `(:DOAccount)<-[:RESOURCE]-(:DOProject)` ➡️
`(:DOAccount)-[:RESOURCE]->(:DOProject)`
**Lastpass**
* `(:LastpassUser)-[:RESOURCE]->(:LastpassTenant)` ➡️
`(:LastpassUser)<-[:RESOURCE]-(:LastpassTenant)`
**SnipeIt**
* `(:SnipeitAsset)<-[:HAS_ASSET]-(:SnipeitTenant)` ➡️
`(:SnipeitAsset)<-[:RESOURCE]-(:SnipeitTenant)`
* `(:SnipeitTenant)-[:HAS_USER]->(:SnipeitUser)` ➡️
`(:SnipeitTenant)-[:RESOURCE]->(:SnipeitUser)`
**Kandji**
* `(:KandjiDevice)-[:ENROLLED_TO]->(:KandjiTenant)` ➡️
`(:KandjiDevice)<-[:RESOURCE]-(:KandjiTenant)`
**Azure**
* `(:AzureKubernetesAgentPool)<-[:HAS_AGENT_POOL]-(:AzureSubscription)`
➡️ `(:AzureKubernetesAgentPool)<-[:RESOURCE]-(:AzureSubscription)`
* `(:AzureDataLakeFileSystem<-[:CONTAINS]-(:AzureSubscription)` ➡️
`(:AzureDataLakeFileSystem<-[:RESOURCE]-(:AzureSubscription)`
* `(:AzureMonitorMetricAlert<-[:HAS_METRIC_ALERT]-(:AzureSubscription)`
➡️ `(:AzureMonitorMetricAlert<-[:RESOURCE]-(:AzureSubscription)`
* `(:AzureSecurityAssessment<-[:HAS_ASSESSMENT]-(:AzureSubscription)` ➡️
`(:AzureSecurityAssessment<-[:RESOURCE]-(:AzureSubscription)`

### Related issues or links
- #1261

---------

Signed-off-by: Jeremy Chapeau <jeremy.chapeau@gmail.com>
Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
Bumps the minor-and-patch group with 3 updates:
[github/codeql-action](https://github.com/github/codeql-action),
[astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) and
[docker/setup-buildx-action](https://github.com/docker/setup-buildx-action).

Updates `github/codeql-action` from 4.31.8 to 4.31.9
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/releases">github/codeql-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.31.9</h2>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>4.31.9 - 16 Dec 2025</h2>
<p>No user facing changes.</p>
<p>See the full <a
href="https://github.com/github/codeql-action/blob/v4.31.9/CHANGELOG.md">CHANGELOG.md</a>
for more information.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/github/codeql-action/blob/main/CHANGELOG.md">github/codeql-action's
changelog</a>.</em></p>
<blockquote>
<h1>CodeQL Action Changelog</h1>
<p>See the <a
href="https://github.com/github/codeql-action/releases">releases
page</a> for the relevant changes to the CodeQL CLI and language
packs.</p>
<h2>[UNRELEASED]</h2>
<p>No user facing changes.</p>
<h2>4.31.9 - 16 Dec 2025</h2>
<p>No user facing changes.</p>
<h2>4.31.8 - 11 Dec 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.23.8. <a
href="https://redirect.github.com/github/codeql-action/pull/3354">#3354</a></li>
</ul>
<h2>4.31.7 - 05 Dec 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.23.7. <a
href="https://redirect.github.com/github/codeql-action/pull/3343">#3343</a></li>
</ul>
<h2>4.31.6 - 01 Dec 2025</h2>
<p>No user facing changes.</p>
<h2>4.31.5 - 24 Nov 2025</h2>
<ul>
<li>Update default CodeQL bundle version to 2.23.6. <a
href="https://redirect.github.com/github/codeql-action/pull/3321">#3321</a></li>
</ul>
<h2>4.31.4 - 18 Nov 2025</h2>
<p>No user facing changes.</p>
<h2>4.31.3 - 13 Nov 2025</h2>
<ul>
<li>CodeQL Action v3 will be deprecated in December 2026. The Action now
logs a warning for customers who are running v3 but could be running v4.
For more information, see <a
href="https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/">Upcoming
deprecation of CodeQL Action v3</a>.</li>
<li>Update default CodeQL bundle version to 2.23.5. <a
href="https://redirect.github.com/github/codeql-action/pull/3288">#3288</a></li>
</ul>
<h2>4.31.2 - 30 Oct 2025</h2>
<p>No user facing changes.</p>
<h2>4.31.1 - 30 Oct 2025</h2>
<ul>
<li>The <code>add-snippets</code> input has been removed from the
<code>analyze</code> action. This input has been deprecated since CodeQL
Action 3.26.4 in August 2024 when this removal was announced.</li>
</ul>
<h2>4.31.0 - 24 Oct 2025</h2>
<ul>
<li>Bump minimum CodeQL bundle version to 2.17.6. <a
href="https://redirect.github.com/github/codeql-action/pull/3223">#3223</a></li>
<li>When SARIF files are uploaded by the <code>analyze</code> or
<code>upload-sarif</code> actions, the CodeQL Action automatically
performs post-processing steps to prepare the data for the upload.
Previously, these post-processing steps were only performed before an
upload took place. We are now changing this so that the post-processing
steps will always be performed, even when the SARIF files are not
uploaded. This does not change anything for the
<code>upload-sarif</code> action. For <code>analyze</code>, this may
affect Advanced Setup for CodeQL users who specify a value other than
<code>always</code> for the <code>upload</code> input. <a
href="https://redirect.github.com/github/codeql-action/pull/3222">#3222</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/github/codeql-action/commit/5d4e8d1aca955e8d8589aabd499c5cae939e33c7"><code>5d4e8d1</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3371">#3371</a>
from github/update-v4.31.9-998798e34</li>
<li><a
href="https://github.com/github/codeql-action/commit/1dc115f17a8c6966e94a6477313dd3df6319bc83"><code>1dc115f</code></a>
Update changelog for v4.31.9</li>
<li><a
href="https://github.com/github/codeql-action/commit/998798e34d79baddb1566c60bbb8f68a901c04e6"><code>998798e</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3352">#3352</a>
from github/nickrolfe/jar-min-ff-cleanup</li>
<li><a
href="https://github.com/github/codeql-action/commit/5eb751966fe18977cdefa4e41e0f90e92801ce90"><code>5eb7519</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3358">#3358</a>
from github/henrymercer/database-upload-telemetry</li>
<li><a
href="https://github.com/github/codeql-action/commit/d29eddb39b7c33171bb0250114b1c9e3ff8fe2bc"><code>d29eddb</code></a>
Extract version number to constant</li>
<li><a
href="https://github.com/github/codeql-action/commit/e9626872ef3347a9c18091d60da647084c2451a6"><code>e962687</code></a>
Merge branch 'main' into henrymercer/database-upload-telemetry</li>
<li><a
href="https://github.com/github/codeql-action/commit/19c7f96922a6269458f2cadcc23faf0ebaa1368b"><code>19c7f96</code></a>
Rename <code>isOverlayBase</code></li>
<li><a
href="https://github.com/github/codeql-action/commit/ae5de9a20d0468cc3818a0dc5c99e456f996d9cf"><code>ae5de9a</code></a>
Use <code>getErrorMessage</code> in log too</li>
<li><a
href="https://github.com/github/codeql-action/commit/0cb86337c5111af4ff3dc7e8f9b98c479c9ea954"><code>0cb8633</code></a>
Prefer <code>performance.now()</code></li>
<li><a
href="https://github.com/github/codeql-action/commit/c07cc0d3a95a282fc5a54477464931c776d124ec"><code>c07cc0d</code></a>
Merge pull request <a
href="https://redirect.github.com/github/codeql-action/issues/3351">#3351</a>
from github/henrymercer/ghec-dr-determine-tools-vers...</li>
<li>Additional commits viewable in <a
href="https://github.com/github/codeql-action/compare/1b168cd39490f61582a9beae412bb7057a6b2c4e...5d4e8d1aca955e8d8589aabd499c5cae939e33c7">compare
view</a></li>
</ul>
</details>
<br />

Updates `astral-sh/setup-uv` from 7.1.4 to 7.1.6
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/astral-sh/setup-uv/releases">astral-sh/setup-uv's
releases</a>.</em></p>
<blockquote>
<h2>v7.1.6 🌈 add OS version to cache key to prevent binary
incompatibility</h2>
<h2>Changes</h2>
<p>This release will invalidate your cache existing keys!</p>
<p>The os version e.g. <code>ubuntu-22.04</code> is now part of the
cache key. This prevents failing builds when a cache got populated with
wheels built with different tools (e.g. glibc) than are present on the
runner where the cache got restored.</p>
<h2>🐛 Bug fixes</h2>
<ul>
<li>feat: add OS version to cache key to prevent binary incompatibility
<a href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/716">#716</a>)</li>
</ul>
<h2>🧰 Maintenance</h2>
<ul>
<li>chore: update known checksums for 0.9.17 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/714">#714</a>)</li>
</ul>
<h2>⬆️ Dependency updates</h2>
<ul>
<li>Bump actions/checkout from 5.0.0 to 6.0.1 @<a
href="https://github.com/apps/dependabot">dependabot[bot]</a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/712">#712</a>)</li>
<li>Bump actions/setup-node from 6.0.0 to 6.1.0 @<a
href="https://github.com/apps/dependabot">dependabot[bot]</a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/715">#715</a>)</li>
</ul>
<h2>v7.1.5 🌈 allow setting <code>cache-local-path</code> without
<code>enable-cache: true</code></h2>
<h2>Changes</h2>
<p><a
href="https://redirect.github.com/astral-sh/setup-uv/pull/612">astral-sh/setup-uv#612</a>
fixed a faulty behavior where this action set <code>UV_CACHE_DIR</code>
even though <code>enable-cache</code> was <code>false</code>. It also
fixed the cases were the cache dir is already configured in a settings
file like <code>pyproject.toml</code> or <code>UV_CACHE_DIR</code> was
already set. Here the action shouldn't overwrite or set
<code>UV_CACHE_DIR</code>.</p>
<p>These fixes introduced an unwanted behavior: You can still set
<code>cache-local-path</code> but this action didn't do anything. This
release fixes that.</p>
<p>You can now use <code>cache-local-path</code> to automatically set
<code>UV_CACHE_DIR</code> even when <code>enable-cache</code> is
<code>false</code> (or gets set to false by default e.g. on self-hosted
runners)</p>
<pre lang="yaml"><code>- name: This is now possible
  uses: astral-sh/setup-uv@v7
  with:
    enable-cache: false
    cache-local-path: &quot;/path/to/cache&quot;
</code></pre>
<h2>🐛 Bug fixes</h2>
<ul>
<li>allow cache-local-path w/o enable-cache <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/707">#707</a>)</li>
</ul>
<h2>🧰 Maintenance</h2>
<ul>
<li>set biome files.maxSize to 2MiB <a
href="https://github.com/eifinger"><code>@​eifinger</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/708">#708</a>)</li>
<li>chore: update known checksums for 0.9.16 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/706">#706</a>)</li>
<li>chore: update known checksums for 0.9.15 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/704">#704</a>)</li>
<li>chore: use <code>npm ci --ignore-scripts</code> everywhere <a
href="https://github.com/woodruffw"><code>@​woodruffw</code></a> (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/699">#699</a>)</li>
<li>chore: update known checksums for 0.9.14 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/700">#700</a>)</li>
<li>chore: update known checksums for 0.9.13 @<a
href="https://github.com/apps/github-actions">github-actions[bot]</a>
(<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/694">#694</a>)</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/681c641aba71e4a1c380be3ab5e12ad51f415867"><code>681c641</code></a>
Bump actions/checkout from 5.0.0 to 6.0.1 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/712">#712</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/2e85713bb0ad1bd68b79183f00fe093dccd19930"><code>2e85713</code></a>
Bump actions/setup-node from 6.0.0 to 6.1.0 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/715">#715</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/58b6d7b303576a48786c1bbb6959b7875a3a84ec"><code>58b6d7b</code></a>
fix: add OS version to cache key to prevent binary incompatibility (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/716">#716</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/e8b52af86e46cb518daf4b47877e582bc9e37b8b"><code>e8b52af</code></a>
chore: update known checksums for 0.9.17 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/714">#714</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/ed21f2f24f8dd64503750218de024bcf64c7250a"><code>ed21f2f</code></a>
Bump peter-evans/create-pull-request from 7.0.8 to 7.0.9 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/695">#695</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/93202d8fbe8ed7d8099f4773a9684b037e0b6205"><code>93202d8</code></a>
bump dependencies (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/709">#709</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/5ce090076db3f5a2ed5bbd4a75c9123c727ff2af"><code>5ce0900</code></a>
set biome files.maxSize to 2MiB (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/708">#708</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/4180991cd97ec5ff7a3147ba70d3cc188015b467"><code>4180991</code></a>
allow cache-local-path w/o enable-cache (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/707">#707</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/0439606c8e2f1191835c4446afb6e4ac29363801"><code>0439606</code></a>
Bump github/codeql-action from 4.30.9 to 4.31.6 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/698">#698</a>)</li>
<li><a
href="https://github.com/astral-sh/setup-uv/commit/7dd56c18e98cbf9546ad0ca8108ab326f681708a"><code>7dd56c1</code></a>
chore: update known checksums for 0.9.16 (<a
href="https://redirect.github.com/astral-sh/setup-uv/issues/706">#706</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/astral-sh/setup-uv/compare/v7.1.4...681c641aba71e4a1c380be3ab5e12ad51f415867">compare
view</a></li>
</ul>
</details>
<br />

Updates `docker/setup-buildx-action` from 3.11.1 to 3.12.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/setup-buildx-action/releases">docker/setup-buildx-action's
releases</a>.</em></p>
<blockquote>
<h2>v3.12.0</h2>
<ul>
<li>Deprecate <code>install</code> input by <a
href="https://github.com/crazy-max"><code>@​crazy-max</code></a> in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/455">docker/setup-buildx-action#455</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.62.1 to 0.63.0 in
<a
href="https://redirect.github.com/docker/setup-buildx-action/pull/434">docker/setup-buildx-action#434</a></li>
<li>Bump brace-expansion from 1.1.11 to 1.1.12 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/436">docker/setup-buildx-action#436</a></li>
<li>Bump form-data from 2.5.1 to 2.5.5 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/432">docker/setup-buildx-action#432</a></li>
<li>Bump undici from 5.28.4 to 5.29.0 in <a
href="https://redirect.github.com/docker/setup-buildx-action/pull/435">docker/setup-buildx-action#435</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-buildx-action/compare/v3.11.1...v3.12.0">https://github.com/docker/setup-buildx-action/compare/v3.11.1...v3.12.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/8d2750c68a42422c14e847fe6c8ac0403b4cbd6f"><code>8d2750c</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/455">#455</a>
from crazy-max/install-deprecated</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/e81846bcc4416a0bf18b8389e4f6fce279619ddc"><code>e81846b</code></a>
deprecate install input</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/65d18f8f8a05aab1b2d761032bec9cd5578caadb"><code>65d18f8</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/454">#454</a>
from docker/dependabot/github_actions/actions/checkout-6</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/000d75d273dec231f74115df50b6ee04c9b25e55"><code>000d75d</code></a>
build(deps): bump actions/checkout from 5 to 6</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/1583c0f09d26c58c59d25b0eef29792b7ce99d9a"><code>1583c0f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/443">#443</a>
from nicolasleger/patch-1</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/ed158e796328af702db08c75bebb92f2fb10be88"><code>ed158e7</code></a>
doc: bump actions/checkout from 4 to 5</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/4cc794f83e4b7488282e879f4469e86246e52ddd"><code>4cc794f</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/441">#441</a>
from docker/dependabot/github_actions/actions/checkout-5</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/4dfc3d6c5d9e9534040f8d8b55bd4a98459b62b7"><code>4dfc3d6</code></a>
build(deps): bump actions/checkout from 4 to 5</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/af1b253b8dc984466d22633f04ef341c1520ed2f"><code>af1b253</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-buildx-action/issues/440">#440</a>
from crazy-max/k3s-build</li>
<li><a
href="https://github.com/docker/setup-buildx-action/commit/3c6ab92b04d9f3e63233e0e0168ba114c6b448bc"><code>3c6ab92</code></a>
ci: k3s test with latest buildx</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/setup-buildx-action/compare/e468171a9de216ec08956ac3ada2f0791b6bd435...8d2750c68a42422c14e847fe6c8ac0403b4cbd6f">compare
view</a></li>
</ul>
</details>
<br />


Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
… index (#2168)

### Summary

- Correct relationship direction in schema docs:
`(:TrivyImageFinding)-[:AFFECTS]->(:Package)` (was reversed)
- Correct relationship direction in schema docs:
`(Package)-[SHOULD_UPDATE_TO]->(TrivyFix)` (was reversed)
- Add `extra_index=True` on `KubernetesContainer.status_state` for
vulnerability management query performance

### Checklist

- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
docs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary

This PR adds two new intel modules to Cartography with production-grade
quality:

1. **GitLab Module** - Syncs repositories, groups, and programming
languages from any GitLab instance
2. **Workday Module** - Syncs employee and organization data from
Workday HR system

Both modules have been **live tested at production scale** and include
comprehensive documentation, testing, and zero limitations.

### Features

**GitLab Module:**
- Production-tested against a real GitLab instance with thousands of
repositories
- Group (namespace) support with OWNER relationships
- Programming language detection with percentage tracking
- Complete language analysis for ALL repos (NO sampling or limits)
- Multi-instance support - URL-prefixed IDs prevent collisions across
multiple GitLab instances
- Parallel execution - 10 concurrent workers for language detection
- 48 repository properties - visibility, URLs, stats, features,
timestamps
- Shared ProgrammingLanguage nodes with GitHub module

**Workday Module:**
- Production-tested against a real Workday instance with
enterprise-scale employee data
- Organization hierarchical structure support
- Complete manager relationship graphs (REPORTS_TO)
- Human label integration - Enables cross-module identity queries with
Duo, Okta, etc.
- 17 employee properties - name, email, title, location, team, etc.
- Clean field mapping from Workday API (handles hyphens in field names)

### Related issues or links

N/A - New feature contribution

### Checklist

**Tests:**
- [x] Added 37 comprehensive tests (25 unit + 12 integration)
  - GitLab: 13 unit tests + 6 integration tests
  - Workday: 12 unit tests + 6 integration tests
- [x] All tests passing
- [x] Live production validation completed for both modules

**Schema documentation:**
- [x] Created comprehensive schema documentation:
  - docs/root/modules/gitlab/ (config.md, schema.md, index.md)
  - docs/root/modules/workday/ (config.md, schema.md, index.md)
- [x] Includes Mermaid diagrams, property tables, and sample Cypher
queries
- [x] Added to docs/root/usage/schema.md index

**New intel module requirements:**
- [x] Uses NodeSchema data model (CartographyNodeSchema throughout)
- [x] Linter passes (isort, black, flake8, mypy, pyupgrade)
  - All 14 pre-commit hooks passing
  - Zero linting errors or warnings

### Implementation Details

**Code Quality:**
- Modern CartographyNodeSchema pattern (follows latest best practices)
- Complete type annotations (mypy validated)
- Comprehensive docstrings on all functions
- Proper error handling with timeouts (60s)
- Secure credential handling via environment variables only

**Graph Schema:**
```
GitLab:
(:GitLabGroup)-[:OWNER]->(:GitLabRepository)-[:LANGUAGE{percentage}]->(:ProgrammingLanguage)

Workday:
(:WorkdayHuman:Human)-[:MEMBER_OF_ORGANIZATION]->(:WorkdayOrganization)
(:WorkdayHuman)-[:REPORTS_TO]->(:WorkdayHuman)
```

**Dependencies:**
- Added python-gitlab>=3.0.0 (GitLab API client)
- Uses existing requests library for Workday

**Performance:**
- GitLab: Parallel language fetching with ThreadPoolExecutor (10
workers)
- Workday: Single API call, efficient batch loading
- Both include cleanup jobs for stale data removal

**Security:**
- No hardcoded credentials
- All secrets via environment variables
- HTTPS enforced for API calls
- Proper timeout values to prevent hangs
- PII handling documented for Workday module

### Files Changed

```
35 files changed, 3,756 insertions(+)

New modules:
- cartography/intel/gitlab/ (repositories.py, __init__.py)
- cartography/intel/workday/ (people.py, __init__.py)
- cartography/models/gitlab/ (repositories.py, groups.py)
- cartography/models/workday/ (human.py, organization.py)
- cartography/models/common/ (programming_language.py - shared model)

Configuration:
- cartography/config.py (added GitLab and Workday parameters)
- cartography/cli.py (added CLI arguments)
- cartography/sync.py (registered both modules)

Documentation:
- docs/root/modules/gitlab/ (3 files)
- docs/root/modules/workday/ (3 files)
- docs/root/usage/schema.md (added module includes)

Tests:
- tests/unit/cartography/intel/gitlab/ (13 tests)
- tests/unit/cartography/intel/workday/ (12 tests)
- tests/integration/cartography/intel/gitlab/ (6 tests)
- tests/integration/cartography/intel/workday/ (6 tests)
- tests/data/gitlab/ (test fixtures)
- tests/data/workday/ (test fixtures)

Cleanup:
- cartography/data/jobs/cleanup/gitlab_repos_cleanup.json

Other:
- README.md (added Superhuman to users list)
```

### Breaking Changes

None - these are new modules with no impact on existing functionality.

### Additional Context

This contribution brings Cartography's GitLab support on par with its
GitHub support, and adds HR data integration capabilities for
organizational visibility and access reviews.

Both modules follow the latest Cartography patterns
(CartographyNodeSchema) and have been thoroughly tested with real
production data at scale.

---------

Signed-off-by: Sacha Faust <sacha.faust@gmail.com>
Co-authored-by: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
…#2187)

### Summary
> Clone from #2180
created by @AdiLyft
Adds support for osv.dev references to vulnerabilities (e.g.
https://osv.dev/vulnerability/MAL-2023-462) as [included by
Semgrep](https://semgrep.dev/blog/2025/block-malicious-dependencies-with-semgrep-supply-chain/#:~:text=We%20start%20by%20integrating%20data%20from%20OSV.dev)
and handles any future unknown vulnerability ID formats crashing Semgrep
sync.


### Related issues or links
- N/A
…or-and-patch group (#2194)

Bumps the minor-and-patch group with 1 update:
[docker/setup-docker-action](https://github.com/docker/setup-docker-action).

Updates `docker/setup-docker-action` from 4.6.0 to 4.7.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/setup-docker-action/releases">docker/setup-docker-action's
releases</a>.</em></p>
<blockquote>
<h2>v4.7.0</h2>
<ul>
<li>Bump <code>@​actions/core</code> from 1.11.1 to 2.0.1 in <a
href="https://redirect.github.com/docker/setup-docker-action/pull/192">docker/setup-docker-action#192</a></li>
<li>Bump <code>@​docker/actions-toolkit</code> from 0.68.0 to 0.71.0 in
<a
href="https://redirect.github.com/docker/setup-docker-action/pull/190">docker/setup-docker-action#190</a>
<a
href="https://redirect.github.com/docker/setup-docker-action/pull/193">docker/setup-docker-action#193</a></li>
<li>Bump js-yaml from 3.14.1 to 3.14.2 in <a
href="https://redirect.github.com/docker/setup-docker-action/pull/196">docker/setup-docker-action#196</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/setup-docker-action/compare/v4.6.0...v4.7.0">https://github.com/docker/setup-docker-action/compare/v4.6.0...v4.7.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/docker/setup-docker-action/commit/e43656e248c0bd0647d3f5c195d116aacf6fcaf4"><code>e43656e</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-docker-action/issues/193">#193</a>
from docker/dependabot/npm_and_yarn/docker/actions-to...</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/51b16473d8a93194c4956fdd324bf03fd18f9592"><code>51b1647</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/34fbc53a71fad66a82efeb377d279415fa6cc9ab"><code>34fbc53</code></a>
build(deps): bump <code>@​docker/actions-toolkit</code> from 0.69.0 to
0.71.0</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/ec52bdf18dc0dc42a45824961a91fb29b4807978"><code>ec52bdf</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-docker-action/issues/196">#196</a>
from docker/dependabot/npm_and_yarn/js-yaml-3.14.2</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/c2e06996eaca649c8f929a85abfa6f364820e01c"><code>c2e0699</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-docker-action/issues/192">#192</a>
from docker/dependabot/npm_and_yarn/actions/core-2.0.1</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/02a35a12bc2f6d99b5abb6ee7aba61779592030d"><code>02a35a1</code></a>
chore: update generated content</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/1d30751f7d51837b530a4f9b4320aaac8c5c725a"><code>1d30751</code></a>
build(deps): bump js-yaml from 3.14.1 to 3.14.2</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/20e0c03a8de752d0737f3f65adf0e8d19a2d0f55"><code>20e0c03</code></a>
build(deps): bump <code>@​actions/core</code> from 1.11.1 to 2.0.1</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/069eb67b1ba7defc8ee54442d019a1ce7225f725"><code>069eb67</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/setup-docker-action/issues/194">#194</a>
from crazy-max/update-dev-deps</li>
<li><a
href="https://github.com/docker/setup-docker-action/commit/c17c6939aea6ccb47803a3db1930e24fdf155709"><code>c17c693</code></a>
chore: update generated content</li>
<li>Additional commits viewable in <a
href="https://github.com/docker/setup-docker-action/compare/e61617a16c407a86262fb923c35a616ddbe070b3...e43656e248c0bd0647d3f5c195d116aacf6fcaf4">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=docker/setup-docker-action&package-manager=github_actions&previous-version=4.6.0&new-version=4.7.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps python from `fb1feae` to `7b68a5f`.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=python&package-manager=docker&previous-version=3.10.19-slim&new-version=3.10.19-slim)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jeremy Chapeau <113923302+jychp@users.noreply.github.com>
### Summary
> Add support for ingesting AWS SageMaker resources into Cartography.
Amazon SageMaker is AWS's fully managed machine learning platform for
building, training, and deploying ML models. This feature would allow
Cartography to track SageMaker notebooks, training jobs, models,
endpoints, and associated infrastructure.




### Related issues or links
> Include links to relevant issues or other pages.

- #2123


### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:

- [x] Include a screenshot showing what the graph looked like before and
after your changes.
<img width="1909" height="1071" alt="image"
src="https://github.com/user-attachments/assets/b38070a4-9566-480a-8ab7-3eeda6b26b36"
/>




If you are changing a node or relationship:
- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: shyammukund <shyam@subimage.io>
Co-authored-by: Alex Chantavy <alex@subimage.io>
### Summary
> support for ingesting GCP Vertex AI resources into Cartography. Vertex
AI is Google Cloud's unified machine learning platform.

**New Nodes:**

GCPVertexAIModel - Trained models

GCPVertexAIEndpoint - Model serving endpoints

GCPVertexAIDeployedModel - Models deployed to endpoints

GCPVertexAIWorkbenchInstance - Workbench notebook instances

GCPVertexAITrainingPipeline - Training pipelines

GCPVertexAIFeatureGroup - Feature stores

GCPVertexAIDataset - Training datasets

**New Relationships:**

(:GCPProject)-[:RESOURCE]->(:GCPVertexAIModel)

(:GCPVertexAIEndpoint)-[:SERVES]->(:GCPVertexAIDeployedModel)

(:GCPVertexAIDeployedModel)-[:INSTANCE_OF]->(:GCPVertexAIModel)


(:GCPVertexAIWorkbenchInstance)-[:USES_SERVICE_ACCOUNT]->(:GCPServiceAccount)

((:GCPVertexAITrainingPipeline)-[:READS_FROM]->(:GCPVertexAIDataset)

(:GCPVertexAITrainingPipeline)-[:PRODUCES]->(:GCPVertexAIModel)

(:GCPVertexAIModel)-[:STORED_IN]->(:GCSBucket)





### Related issues or links
> Include links to relevant issues or other pages.

- #2124


### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
<img width="1684" height="928" alt="image"
src="https://github.com/user-attachments/assets/499febc2-76ca-406d-b823-b3e7c9cd8e15"
/>

If you are changing a node or relationship: 
- [ ] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).

- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: shyammukund <shyam@subimage.io>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
### Summary

Add 20 CIS AWS Foundations Benchmark v5.0 compliance checks as
Cartography rules.

**New rules by section:**

| Section | CIS Check | Description |
|---------|-----------|-------------|
| IAM | 1.11 | Access keys unused for 45+ days |
| IAM | 1.12 | Users with multiple active access keys |
| IAM | 1.13 | Access keys not rotated in 90 days |
| IAM | 1.14 | IAM users with directly attached policies |
| IAM | 1.18 | Expired SSL/TLS certificates |
| Storage | 2.1.1 | S3 buckets without versioning |
| Storage | 2.1.2 | S3 buckets without MFA Delete |
| Storage | 2.1.4 | S3 buckets without Block Public Access |
| Storage | 2.1.5 | S3 buckets without access logging |
| Storage | 2.1.6 | S3 buckets without default encryption |
| Storage | 2.2.1 | RDS instances without encryption at rest |
| Storage | 2.3.1 | EBS volumes without encryption |
| Logging | 3.1 | CloudTrail not multi-region |
| Logging | 3.4 | CloudTrail log file validation disabled |
| Logging | 3.5 | CloudTrail not integrated with CloudWatch |
| Logging | 3.7 | CloudTrail logs not encrypted with KMS |
| Networking | 5.1 | Security groups with unrestricted SSH |
| Networking | 5.2 | Security groups with unrestricted RDP |
| Networking | 5.4 | Default security group allows traffic |
| Networking | - | Unrestricted access to all ports |

All rules are tagged with `cis`, `compliance`, `cis_aws_5.0` for easy
filtering and compliance reporting.

### Related issues or links

- [CIS AWS Foundations Benchmark
v5.0](https://www.cisecurity.org/benchmark/amazon_web_services)
- #2158 - Feature request for additional IAM data needed to complete
remaining CIS checks

---------

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary

Adds a `cascade_delete` parameter to `build_cleanup_queries()` and
`GraphJob.from_node_schema()` that, when enabled, also deletes child
nodes that the stale parent points to via RESOURCE relationships.

This is useful for hierarchical data like GCP and GitLab
organizations/groups where deleting a stale parent should also clean up
its children.

### Query Behavior

In Cartography, RESOURCE relationships point from parent to child:
`(Parent)-[:RESOURCE]->(Child)`

When `cascade_delete=True`, the cleanup query becomes:
```python
cascade_rel_label = node_schema.sub_resource_relationship.rel_label
if node_schema.sub_resource_relationship.direction == LinkDirection.INWARD:
    cascade_rel_clause = f"<-[:{cascade_rel_label}]-"
else:
    cascade_rel_clause = f"-[:{cascade_rel_label}]->"
delete_action_clauses = [
    f"""
WHERE n.lastupdated <> $UPDATE_TAG
WITH n LIMIT $LIMIT_SIZE
CALL {{
    WITH n
    OPTIONAL MATCH (n){cascade_rel_clause}(child)
    WITH child WHERE child IS NOT NULL AND child.lastupdated <> $UPDATE_TAG
    DETACH DELETE child
}}
DETACH DELETE n;
""",
]
```
We use a unit subquery to delete children so we don’t have to collect()
a potentially huge child list, and to ensure the parent row is always
preserved for deletion. An OPTIONAL MATCH + WHERE on the child can
unintentionally drop the parent row or force list materialization when
fan‑out is large. The subquery does the child deletes as a side effect
and then reliably deletes the stale parent.

When `cascade_delete=False` (default), the standard query is used:
```cypher
WHERE n.lastupdated <> $UPDATE_TAG
WITH n LIMIT $LIMIT_SIZE
DETACH DELETE n;
```

### Backward Compatibility
The default is `False` to maintain backward compatibility - existing
behavior is unchanged.

## Test Plan

- [x] integration tests verify actual cascade behavior in Neo4j

## Use Case

This feature is needed for the GitLab module (PR #2182) which has
hierarchical data:
- GitLab Organization → Groups → Projects

It will also be needed in the GCP module to fix a bug where project
resource nodes get orphaned

---------

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary

- Updates all CIS AWS Foundations Benchmark rule names from `CIS X.X:
...` to `CIS AWS X.X: ...`
- Makes rule names self-documenting and unambiguous when viewed in
isolation (alerts, reports, dashboards)
- Follows official CIS naming convention ("CIS AWS Foundations
Benchmark")

## Why this matters

CIS control numbers don't map 1:1 across cloud providers. For example,
CIS AWS 1.18 (Expired SSL/TLS Certificates) has no equivalent in CIS
GCP. Including the provider in the rule name prevents confusion and
ensures security engineers immediately know which benchmark a finding
references.
## Related
Fixes naming in
#2157

## References

- [CIS AWS Foundations
Benchmark](https://www.cisecurity.org/benchmark/amazon_web_services)
- [AWS Security Hub CIS
Documentation](https://docs.aws.amazon.com/securityhub/latest/userguide/cis-aws-foundations-benchmark.html)
- [Steampipe AWS Compliance
Mod](https://github.com/turbot/steampipe-mod-aws-compliance)


🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary

This PR adds comprehensive GitLab support with significant architectural
improvements.

### Features Added
- **GitLabOrganization** - Top-level groups (the root of your GitLab
hierarchy)
- **GitLabGroup** - Nested subgroups within organizations
- **GitLabProject** - Repositories (renamed from `GitLabRepository` to
align with [GitLab's official
terminology](https://docs.gitlab.com/api/projects/), though we've added
an extra node label `GitLabRepository` for backwards compat)
- **GitLabBranch** - Branches within projects
- **GitLabDependencyFile** - Manifest files (package.json,
requirements.txt, etc.)
- **GitLabDependency** - Dependencies extracted from manifest files
- **Languages** - Stored as a JSON property on GitLabProject (e.g.,
`{"Python": 65.5, "JavaScript": 34.5}`)

### Key Architectural Improvements

#### 1. Replaced ThreadPoolExecutor with asyncio + httpx
Following the established Entra module pattern, language fetching now
uses:
- `httpx.AsyncClient` with `asyncio.Semaphore` for rate limiting
- Single connection pool instead of 10 separate GitLab client instances
- Reference: `cartography/intel/entra/__init__.py`

#### 2. Replaced raw Cypher with standard schema
The original PR used raw Cypher for LANGUAGE relationships. This PR:
- Stores languages as a JSON property on `GitLabProject` instead of
separate `GitLabLanguage` nodes
- Follows the GitHub module pattern (languages as property, not separate
nodes)
- Eliminates the need for `gitlab_repos_cleanup.json`
- Single `load()` call handles everything

#### 3. Two-tier sub_resource_relationship hierarchy
Implemented proper cleanup scoping with cascade delete:

```
GitLabOrganization (root tenant)
    └── RESOURCE → GitLabGroup
    └── RESOURCE → GitLabProject
                       └── RESOURCE → GitLabBranch
                       └── RESOURCE → GitLabDependencyFile
                       └── REQUIRES → GitLabDependency
```

**Why cascade delete was needed:**

Without cascade delete, when a GitLab project is deleted from GitLab:
1. Project node gets cleaned up (scoped to org)
2. But branches/dependencies (scoped to project) are never cleaned
because the project wasn't in the sync
3. Results in orphaned nodes with zero relationships

This is the same problem that exists in GCP (we've seen 740+ orphaned
buckets in production in a large environment). The cascade delete
solution:
```python
GraphJob.from_node_schema(GitLabProjectSchema(), params, cascade_delete=True)
```

This deletes all children with `RESOURCE` relationships before deleting
the stale parent node.

#### 4. Renamed GitLabRepository → GitLabProject
Aligns with [GitLab's official API
terminology](https://docs.gitlab.com/api/projects/) where "projects" is
the correct term (not "repositories").
**However** we've added an extra node label `GitLabRepository` to the
`GitLabProject` node so that people can query with either phrase.

#### 5. GitLab-specific language storage (not shared
ProgrammingLanguage)
Unlike the original PR which reused GitHub's `ProgrammingLanguage` node,
this stores languages as a JSON property on each project. Percentage
data preserved: `{"Python": 65.5, "JavaScript": 34.5}`

Sample query to find languages:
```cypher
MATCH (p:GitLabProject)
WHERE p.languages CONTAINS '"Python"'
RETURN p.name, p.languages
```

#### 6. Multi-instance support via web_url IDs
All node IDs use GitLab's `web_url` which inherently includes the
instance URL, supporting multiple GitLab instances in the same Neo4j
database without ID collisions:
- `https://gitlab.com/myorg/project`
- `https://gitlab.example.com/myorg/project`

### Configuration
```bash
cartography \
  --gitlab-url "https://gitlab.com" \
  --gitlab-organization-id 12345678 \
  --gitlab-token-env-var "GITLAB_TOKEN"
```

Required PAT scopes: `read_user`, `read_repository`, `read_api`

## Related issues or links

- Depends on #2181 (cascade_delete feature)
- GitLab API docs: https://docs.gitlab.com/api/projects/

## Checklist

- [x] Update/add unit or integration tests
- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
documentation
- [x] Uses the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node)
- [x] Linter passes
<img width="1345" height="748" alt="Screenshot 2025-12-24 at 6 29 58 PM"
src="https://github.com/user-attachments/assets/9a533b04-147c-4804-9f4f-003f277a7554"
/>

---------

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary
> Adds Coverage for AWS Bedrock for the following nodes and rels 

- **New Nodes**

- AWSBedrockFoundationModel
- AWSBedrockCustomModel 
- AWSBedrockProvisionedModelThroughput
- AWSBedrockGuardrail
- AWSBedrockAgent
- AWSBedrockKnowledgeBase

- **Key Relationships**

- (:AWSBedrockCustomModel)-[:BASED_ON]->(:AWSBedrockFoundationModel)
- (:AWSBedrockCustomModel)-[:TRAINED_FROM]->(:S3Bucket)
-
(:AWSBedrockProvisionedModelThroughput)-[:PROVIDES_CAPACITY_FOR]->(:AWSBedrockFoundationModel)
-
(:AWSBedrockProvisionedModelThroughput)-[:PROVIDES_CAPACITY_FOR]->(:AWSBedrockCustomModel)
- (:AWSBedrockGuardrail)-[:APPLIED_TO]->(:AWSBedrockFoundationModel)
- (:AWSBedrockGuardrail)-[:APPLIED_TO]->(:AWSBedrockCustomModel)
- (:AWSBedrockGuardrail)-[:APPLIED_TO]->(:AWSBedrockAgent)
- (:AWSBedrockAgent)-[:USES_MODEL]->(:AWSBedrockFoundationModel)
- (:AWSBedrockAgent)-[:USES_MODEL]->(:AWSBedrockCustomModel)
- (:AWSBedrockAgent)-[:USES_KNOWLEDGE_BASE]->(:AWSBedrockKnowledgeBase)
- (:AWSBedrockAgent)-[:INVOKES]->(:AWSLambda)
- (:AWSBedrockAgent)-[:HAS_ROLE]->(:AWSRole)
- (:AWSBedrockKnowledgeBase)-[:SOURCES_DATA_FROM]->(:S3Bucket)
-
(:AWSBedrockKnowledgeBase)-[:USES_EMBEDDING_MODEL]->(:AWSBedrockFoundationModel)





### Related issues or links
> Include links to relevant issues or other pages.

-#2122


### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
<img width="1909" height="1071" alt="image"
src="https://github.com/user-attachments/assets/6f196600-ef4b-4c23-91e8-b4109b86b52d"
/>


If you are changing a node or relationship:
- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: shyammukund <shyam@subimage.io>
Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
A tenant represents the top-level organizational boundary or billing
entity within a cloud provider or SaaS platform.
Tenants serve as the root container for all resources, users, and
configurations within a given service.
We add a Tenant semantic label to all nodes that have outward 'RESOURCE'
relationships.

---------

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
### Summary
> Describe your changes.
- This PR takes the work done in a previous PR by @janithashri and adds
coverage for Backup Configurations in Cloud SQL.


### Related issues or links
> Include links to relevant issues or other pages.

- #2038

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
<img width="1778" height="473" alt="image"
src="https://github.com/user-attachments/assets/3bc625e4-ff21-4a7d-ac7c-39a3a0ac4534"
/>


If you are changing a node or relationship:
- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: Admin <janithashri@gmail.com>
Signed-off-by: shyammukund <shyam@subimage.io>
Co-authored-by: Admin <janithashri@gmail.com>
Co-authored-by: Janithashri G <86554502+janithashri@users.noreply.github.com>
…ambda, alb) (#2166)

### Summary

Extends ELBv2 target group modeling to support all four AWS target
types, completing the EXPOSE relationship graph for load balancers:

- **`instance`** - Existing support (unchanged)
- **`ip`** - NEW: Creates `(LoadBalancerV2)-[EXPOSE]->(EC2PrivateIp)`
relationships
- **`lambda`** - NEW: Creates `(LoadBalancerV2)-[EXPOSE]->(AWSLambda)`
relationships
- **`alb`** - NEW: Creates `(LoadBalancerV2)-[EXPOSE]->(LoadBalancerV2)`
relationships for ALB-to-ALB chaining

Additionally:
- Updates schema documentation with new property and relationships
- Stores `LoadBalancerArn` as `arn` property on `LoadBalancerV2` nodes
(required for ALB target matching)

**Why store ARN on LoadBalancerV2?**

The `alb` target type returns the target ALB's ARN from
`describe_target_health`. To create the EXPOSE relationship, we need to
match by ARN, so we now store it on the node.


### Related issues or links

- Closes #2105
- AWS ELBv2 Target Types:
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/elbv2/client/describe_target_groups.html

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

If you are changing a node or relationship:
- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

Screenshot:
<img width="1203" height="607" alt="Screenshot 2026-01-06 at 6 04 41 PM"
src="https://github.com/user-attachments/assets/44b54523-fe9f-4da3-a9d7-eaa0b02b4acf"
/>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Jeremy Chapeau <113923302+jychp@users.noreply.github.com>
…on bug (#2201)

### Summary

Fix a bug introduced in PR #1747 where the `ECSServiceToECSTaskRel`
relationship was matching services to tasks using only `serviceName`.
Since service names are not globally unique (they can be duplicated
across AWS accounts, regions, and clusters), this caused all services
with a given name to incorrectly connect to all tasks with that same
service name, creating spurious cross-account/cross-cluster
relationships.

The fix adds `cluster_arn` to the target node matcher, so services only
connect to tasks that share **both** the same service name AND cluster
ARN. Since cluster ARNs are globally unique (format:
`arn:aws:ecs:{region}:{account}:cluster/{cluster-name}`), this ensures
relationships are scoped correctly.

### Related issues or links

- Original PR that introduced the bug:
#1747

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests. *(Existing tests in
`test_ecs.py` verify the correct relationship is created; the fix uses
the same `clusterArn` that's already present in both service and task
test data)*
- [ ] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

If you are changing a node or relationship:
- [ ] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).
*(No schema change needed - the `HAS_TASK` relationship still exists,
just with more precise matching)*

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
…2206)

### Summary

Adds a `.python-version` file pinned to Python 3.10 to ensure all
developers use the same Python version that matches CI and Docker.

**Changes:**
- Add `.python-version` file with `3.10`
- Remove `.python-version` from `.gitignore` so it can be tracked

This helps avoid issues like `pymsalruntime` not having wheels for
Python 3.13, which causes `uv sync` to fail when developers use newer
Python versions.

### Related issues or links

- #2205

### Checklist

- [x] Include console log trace showing what happened before and after
your changes.

**Before (Python 3.13):**
```
$ uv sync
Using CPython 3.13.2
Creating virtual environment at: .venv
Resolved 214 packages in 4ms
error: Distribution `pymsalruntime==0.17.1 @ registry+https://pypi.org/simple` can't be installed because it doesn't have a source distribution or wheel for the current platform

hint: You're using CPython 3.13 (`cp313`), but `pymsalruntime` (v0.17.1) only has wheels with the following Python ABI tags: `cp310`, `cp311`, `cp312`
```

**After (with `.python-version` pinning 3.10):**
```
$ uv sync
Using CPython 3.10
# Works successfully
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary
> Describe your changes.

This PR just modifies the docs so that GCP Vertex and CloudSQL appear
under the GCP Schema instead of having their own tab on the side bar.
Also makes sure AWS BedRock and Sagemaker appear under AWS Schema
instead of having own tab on sidebar.

Before: 
<img width="309" height="1029" alt="image"
src="https://github.com/user-attachments/assets/f661afd5-3d2c-46a6-8f2e-1185970dfe9c"
/>

After:
<img width="295" height="656" alt="image"
src="https://github.com/user-attachments/assets/c8b92f06-8361-498f-8ea7-90ad0c191efb"
/>

---------

Signed-off-by: shyammukund <shyam@subimage.io>
Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
Co-authored-by: Kunaal Sikka <kunaal@subimage.io>
### Summary

Just fix a typo

Co-authored-by: Alex Chantavy <alex@subimage.io>
## Summary

Adds comprehensive AWS VPC endpoint support to cartography, enabling
ingestion and relationship mapping for Interface, Gateway, and
GatewayLoadBalancer endpoint types.

## Changes

### Core Implementation
- **Intel Module** (`cartography/intel/aws/ec2/vpc_endpoint.py`):
Fetches and transforms VPC endpoints via AWS API
- **Data Models** (`cartography/models/aws/ec2/vpc_endpoint.py`): Schema
for VPC endpoint nodes and relationships
- **Routes Extension** (`cartography/models/aws/ec2/routes.py`): Added
`vpc_endpoint_id` property and `ROUTES_TO_VPC_ENDPOINT` relationship
- **Resource Registration** (`cartography/intel/aws/resources.py`):
Registered as `ec2:vpc_endpoint` sync resource

### Graph Relationships Created
- VPC Endpoint → AWS Account (`RESOURCE`)
- VPC Endpoint → VPC (`MEMBER_OF_AWS_VPC`)
- VPC Endpoint → Subnet (`USES_SUBNET`) - Interface/GWLB endpoints
- VPC Endpoint → Security Group (`MEMBER_OF_SECURITY_GROUP`) -
Interface/GWLB endpoints
- VPC Endpoint → Route Table (`ROUTES_THROUGH`) - Gateway endpoints
- Route → VPC Endpoint (`ROUTES_TO_VPC_ENDPOINT`)

### Key Features
- **All endpoint types supported**: Interface, Gateway,
GatewayLoadBalancer
- **Sync order independence**: Uses `MERGE` pattern to create stub nodes
for referenced resources
- **Graceful error handling**: ClientError exceptions caught with
warning logs
- **Comprehensive properties**: Service name, type, state, policy
documents, DNS entries, timestamps
- **Automatic cleanup**: Removes stale nodes and relationships on each
sync
- **Well documented**: Clear comments explaining MERGE vs MATCH usage

## Test Coverage

### Unit Tests (9 tests)
- Interface endpoint transformation
- Gateway endpoint transformation
- GatewayLoadBalancer endpoint transformation
- Policy document handling (string, dict, None)
- Empty list handling
- Multiple endpoints
- Route VPC endpoint ID extraction
- Route transform without VPC endpoints
- Route transform edge cases

### Integration Tests (10 tests)
- VPC endpoint node loading
- Account relationship
- VPC relationship
- Subnet relationships
- Security group relationships
- Route table relationships
- Property storage verification
- Full sync with mocked API
- Cleanup of stale nodes
- Cleanup of stale manual relationships

**Total**: 19 tests providing complete coverage

## Usage

VPC endpoints are synced automatically as part of the default AWS sync.
To sync only specific AWS resources:

```bash
cartography --aws-requested-syncs "ec2:vpc,ec2:subnet,ec2:vpc_endpoint"
```

Query examples:
```cypher
// Find all Interface endpoints and their subnets
MATCH (vpce:AWSVpcEndpoint {vpc_endpoint_type: 'Interface'})-[:USES_SUBNET]->(subnet:EC2Subnet)
RETURN vpce.vpc_endpoint_id, vpce.service_name, collect(subnet.subnetid) as subnets

// Find Gateway endpoints and their route tables
MATCH (vpce:AWSVpcEndpoint {vpc_endpoint_type: 'Gateway'})-[:ROUTES_THROUGH]->(rtb:AWSRouteTable)
RETURN vpce.vpc_endpoint_id, vpce.service_name, collect(rtb.id) as route_tables

// Find routes targeting VPC endpoints
MATCH (route:EC2Route)-[:ROUTES_TO_VPC_ENDPOINT]->(vpce:AWSVpcEndpoint)
RETURN route.id, vpce.service_name

// Find all private AWS service access paths
MATCH (account:AWSAccount)-[:RESOURCE]->(vpc:AWSVpc)-[:MEMBER_OF_AWS_VPC]-(vpce:AWSVpcEndpoint)
WHERE vpce.service_name CONTAINS 'amazonaws'
RETURN account.id, vpc.vpcid, vpce.service_name, vpce.vpc_endpoint_type
```

## Code Quality

- ✅ Follows all cartography conventions
- ✅ Modern Python 3.9+ type hints
- ✅ Proper error handling with graceful degradation
- ✅ Comprehensive test coverage (19 tests)
- ✅ Clear documentation
- ✅ No breaking changes
- ✅ Cleanup flow fully tested

## Checklist

- [x] All tests passing (9 unit + 10 integration)
- [x] Code follows project style guidelines
- [x] Error handling implemented
- [x] Documentation added
- [x] No security vulnerabilities
- [x] Graph schema consistent with existing patterns
- [x] Cleanup flow validated with E2E testing
- [x] Route linking validated with real AWS data

---------

Signed-off-by: Sacha Faust <sacha.faust@gmail.com>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
### Summary
Standardized GCP test project identifiers across all test data files to
use consistent project ID (`project-abc`) and project number
(`123456789012`). This enables proper cross-resource relationship
testing between GCP modules (CRM, Compute, Storage, IAM, Policy
Bindings, Permission Relationships) and ensures test data accurately
represents a realistic GCP environment.

**Changes made:**
- Updated all GCP test data files to use `project-abc` / `123456789012`
- Updated all integration test files that reference project identifiers
- Updated unit test assertions to match new project number
- Updated all service account emails to use
`@project-abc.iam.gserviceaccount.com`
- Updated all resource paths to use `projects/project-abc/...`

**Files modified:**
- Test data files (5): `crm.py`, `iam.py`, `storage.py`,
`policy_bindings.py`, `permission_relationships.py`
- Integration test files (7): `test_crm_projects.py`,
`test_crm_folders.py`, `test_iam.py`, `test_policy_bindings.py`,
`test_permission_relationships.py`, `test_cai.py`, `test_storage.py`
- Unit test files (1): `test_storage.py`

### Related issues or links
- #2153

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [ ] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

If you are changing a node or relationship:
- [ ] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [ ] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
  - N/A: This PR does not implement a new intel module
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: Sarthak <137189719+sdudhani@users.noreply.github.com>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
Co-authored-by: Jeremy Chapeau <113923302+jychp@users.noreply.github.com>
dependabot bot and others added 27 commits January 19, 2026 12:10
Bumps python from `7b68a5f` to `f5d029f`.


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=python&package-manager=docker&previous-version=3.10.19-slim&new-version=3.10.19-slim)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
### Summary

This pull request introduces a new intel module to ingest Azure Event
Hubs. This change adds two new node types, `:AzureEventHubsNamespace`
and `:AzureEventHub`, and connects them to the existing
`:AzureSubscription`.

The implementation follows the project's modern, schema-based pattern,
ingests both namespaces and their child event hubs, and includes full
integration test coverage and schema documentation.

### Related issues or links

- Addresses part of #1736

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
<img width="907" height="763" alt="Screenshot 2025-10-05 000254"
src="https://github.com/user-attachments/assets/3dcadd1b-c8a5-4473-9ddc-669884a13681"
/>

- [ ] Include console log trace showing what happened before and after
your changes.
 

If you are changing a node or relationship:
- [x] Update the
[schema](https://github.com/-cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/-cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://-cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).

- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: Admin <janithashri@gmail.com>
Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
Co-authored-by: Jeremy Chapeau <jeremy@subimage.io>
### Summary

This PR updates the SentinelOne CVE ingestion logic to model
vulnerabilities as specific findings per endpoint rather than shared
global vulnerability definitions. This change allows us to capture
instance-specific details (detection dates, mitigation status, endpoint
context) for each occurrence of a CVE.

#### Key Changes

1.  **Refactored `S1CVE` Node Identity**:
* **Old**: ID was constructed from `S1|{cve_id}` (one node per CVE ID
globally).
* **New**: ID is now the SentinelOne API record ID (e.g.,
`"225494730938493804"`), representing a unique finding instance.

2.  **Schema Properties Update**:
* Moved relationship properties (e.g., `mitigation_status`,
`detection_date`, `endpoint_id`) from the `AFFECTS` relationship onto
the `S1CVE` node itself.
* Added missing properties from the API response: `nvd_base_score`,
`remediation_level`, `exploit_code_maturity`, `risk_score`,
`report_confidence`, `mitigation_status_reason`, `marked_by`, etc.

3.  **Relationship Updates**:
* **New Relationship**: `(:S1CVE)-[:AFFECTS]->(:S1Agent)` linking the
finding directly to the affected endpoint.
* **Updated Relationship**: Maintained
`(:S1CVE)-[:AFFECTS]->(:S1ApplicationVersion)` to link to the vulnerable
software version.
* **Account Scope**: Maintained `(:S1CVE)<-[:RESOURCE]-(:S1Account)` to
ensure proper account-based cleanup, consistent with AWS
Inspector/GuardDuty patterns.

4.  **Integration Tests**:
    *   Updated test data to include `endpointId`.
* Updated integration tests to verify the creation of instance-specific
nodes and the new relationships to `S1Agent`.

#### Reasoning
* **Granularity**: SentinelOne provides detailed context for each
detection (when it was found, who marked it, its mitigation status on
that specific machine). Using a global CVE node forces us to store this
rich data on relationships, which is harder to query and manage.
Modeling them as individual findings (similar to `AWSInspectorFinding`)
preserves this fidelity.
* **Consistency**: Linking findings to the specific asset (`S1Agent`)
via `AFFECTS` aligns with how we model other host-based vulnerabilities
in the graph.
* **Cleanup**: Scoping findings to the `S1Account` via `RESOURCE`
ensures that stale findings are properly removed per tenant sync,
preventing data leaks across accounts.

### Related issues or links

- #1660

### Final look

<img width="1426" height="575" alt="Screenshot 2026-01-15 at 13 36 01"
src="https://github.com/user-attachments/assets/02f8c442-1c79-424a-a408-aa42f081962b"
/>

### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
- [ ] Include console log trace showing what happened before and after
your changes.

If you are changing a node or relationship:
- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: Sergio Franco <sergiof@lyft.com>
Co-authored-by: Hector Eryx Paredes Camacho <heryxpc@users.noreply.github.com>
### Summary
> Describe your changes.

- Coverage for Secrets and Secret Versions in GCP Secrets Manager

### Related issues or links
> Include links to relevant issues or other pages.

- https://github.com/cartography-cncf/cartography/issues/...


### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
<img width="1398" height="552" alt="image"
src="https://github.com/user-attachments/assets/48f9a0b0-628f-4763-b6ff-7a77883efd0b"
/>


If you are changing a node or relationship:
- [ ] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: shyammukund <shyam@subimage.io>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
#2214)

### Summary
Makes device sync optional for the Google Workspace module when using
OAuth authentication.

**Problem:** The `cloud-identity.devices.readonly` scope requires Cloud
Identity Premium or Google Workspace Enterprise. Users without these
editions get `invalid_scope` errors when trying to use the
googleworkspace module.

**Solution:**
1. Allow callers to specify a `scopes` array in the OAuth auth payload
(falls back to `OAUTH_SCOPES` if not provided)
2. Skip device sync gracefully if the devices scope is not in the
credentials, logging an info message instead of failing

This enables users to sync users, groups, and OAuth apps without needing
Cloud Identity Premium.

### Related issues or links
- Users without Cloud Identity Premium cannot use the googleworkspace
module due to hardcoded scopes

### Checklist

- [x] Include console log trace showing what happened before and after
your changes.

**Before:** Sync fails with `invalid_scope` error if refresh token
doesn't include devices.readonly scope
**After:** Sync succeeds for users/groups/oauth_apps, logs "Skipping
device sync - cloud-identity.devices.readonly scope not authorized"

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary

This PR migrate tests to new logic and does not introduction functional
changes.

This PR is needed for the upcoming migration of that intel module to the
new datamodel.

---------

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
This PR updates integration tests across multiple intel modules to
follow the testing best practices defined in `AGENTS.md`. This work
prepares the codebase for the migration to the new data model.

### Changes

**Pattern updates applied to all modules:**
- Replace raw Neo4j queries with `check_nodes()` and `check_rels()`
helpers
- Call main `sync()` functions instead of individual `load_*()`
functions
- Add proper mocking for external API functions (`get_*`, `_get_*`)
- Test outcomes (nodes and relationships created) rather than
implementation details

**Modules updated:**
- **AWS**: elasticsearch, resourcegroupstaggingapi, s3,
elastic_ip_addresses, load_balancer_v2s, reserved_instances
- **Jamf**: computers
- **OCI**: IAM (fixed missing assertions and incorrect function calls)
- **GitHub**: users, repos

**Modules verified as already compliant:**
- Okta (all test files)
- PagerDuty (all test files)
- GitHub teams, commits

### Related issue

Part of #1668

---------

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary

Completes the migration of the GCP Compute module to the Cartography
data model, eliminating all raw Cypher queries from
`cartography/intel/gcp/compute.py`.

Includes #2256.

## Changes

### New model schemas

- `GCPFirewallTargetTagSchema` - for firewall target tags with
`TARGET_TAG` relationship
- `GCPSubnetStubSchema` - for creating subnet stub nodes (preserves
legacy MERGE behavior)

### Analysis job

- `gcp_compute_instance_vpc_analysis.json` - creates derived
`MEMBER_OF_GCP_VPC` relationships

### Bug fixes

- Added missing `project_id` property to `GCPInstanceNodeProperties` and
`GCPForwardingRuleNodeProperties`
- Fixed `_zones_to_regions` to use zone's `region` URL field instead of
parsing zone names (supports AI zones like `us-south1-ai`)
- Added error handling in `get_gcp_subnets` and
`get_gcp_regional_forwarding_rules` for invalid regions
- Moved cleanup calls outside region loops for efficiency

## Design Decision: Analysis Job for MEMBER_OF_GCP_VPC

The `MEMBER_OF_GCP_VPC` relationship is a derived relationship that
traverses multiple hops (Instance → NIC → Subnet → VPC). Rather than
keeping raw Cypher in the intel module, we moved this to an analysis
job.

**Rationale:**

- Keeps `compute.py` clean with zero raw Cypher - all ingestion uses
`load()` and all cleanup uses `GraphJob.from_node_schema()`
- Follows the existing pattern for derived relationships (similar to
`aws_ec2_keypair_analysis.json`, `gsuite_human_link.json`)
- Acceptable tradeoff: while we aim to limit analysis jobs, this one is
justified to maintain code consistency pending a future rework of
derived relationship handling in the data model

## Test Plan

- [x] All 46 GCP integration tests pass
- [x] `test_sync_gcp_instances_with_vpc_relationship` updated to call
analysis job

---------

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary

This PR improves and standardizes the documentation (missing nodes,
missing fields, incorrect heading levels, etc.)

Note: I removed some sections for consistency reasons. They will be
re-added in an upcoming PR that will split the schema.doc file for the
larger modules. This PR will be opened once the ongoing refactoring is
complete.

**This PR does not introduce any functional change.**

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
This PR migrates several AWS modules to the declarative data model
pattern using Python dataclasses. This pattern replaces manually written
Cypher queries with declarative schemas, enabling model introspection
and ensuring consistency across the codebase.

### Modules migrated

| Module | Nodes | Key Changes |
|--------|-------|-------------|
| **EC2 Reserved Instances** | `EC2ReservedInstance` | New schema,
cleanup via `GraphJob.from_node_schema()` |
| **Elastic IP Addresses** | `ElasticIPAddress` | New schema with
EC2Instance/NetworkInterface relationships |
| **Internet Gateways** | `AWSInternetGateway` | New schema with
`one_to_many` VPC attachments |
| **Elasticsearch** | `ESDomain` | New schema with `one_to_many`
subnet/security group relationships |
| **S3** | `S3Bucket`, `S3Acl`, `S3PolicyStatement` | Three new schemas,
consolidated bucket property loading |
| **Load Balancer V2** | `LoadBalancerV2`, `ELBV2Listener` | New schemas
+ 4 MatchLinks for EXPOSE target relationships |

### Sync order change

Moved `ec2:subnet` before `ec2:load_balancer` and `ec2:load_balancer_v2`
in `resources.py` so that EC2Subnet nodes exist when load balancers
create SUBNET relationships.

### Related PR

- Closes #2192

### Raw Cypher remaining (justified)

1. **resourcegroupstaggingapi.py**: TAGGED relationships are dynamic
across 35+ resource types - migrating would require 35 MatchLinks with
limited benefit
2. **s3.py**: SNS notification relationships (cross-module S3Bucket ->
SNSTopic)

### Files deleted

- 8 cleanup JSON job files (replaced by `GraphJob.from_node_schema()`)

## Test plan

- [x] All 227 AWS integration tests pass
- [x] Tested on real env (see comment below)

---------

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
### Summary
> Describe your changes.

- Support for CloudRun including Services, Jobs, Executions, and
Revisions



### Checklist

Provide proof that this works (this makes reviews move faster). Please
perform one or more of the following:
- [x] Update/add unit or integration tests.
- [x] Include a screenshot showing what the graph looked like before and
after your changes.
<img width="1779" height="537" alt="image"
src="https://github.com/user-attachments/assets/d6216c92-bd5f-44f8-b1ac-2186b436d0ab"
/>


If you are changing a node or relationship:
- [x] Update the
[schema](https://github.com/cartography-cncf/cartography/tree/master/docs/root/modules)
and
[readme](https://github.com/cartography-cncf/cartography/blob/master/docs/schema/README.md).

If you are implementing a new intel module:
- [x] Use the NodeSchema [data
model](https://cartography-cncf.github.io/cartography/dev/writing-intel-modules.html#defining-a-node).
- [x] Confirm that the linter actually passes (submitting a PR where the
linter fails shows reviewers that you did not test your code and will
delay your review).

---------

Signed-off-by: shyammukund <shyam@subimage.io>
Signed-off-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Kunaal Sikka <19509280+kunaals@users.noreply.github.com>
Co-authored-by: Kunaal Sikka <kunaal@subimage.io>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
### Summary

This PR update the PR template for more complete assessment for AI slop
filtering

Signed-off-by: Jeremy Chapeau <jeremy@subimage.io>
Copilot AI review requested due to automatic review settings January 26, 2026 11:03
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR syncs the prowler-cloud/cartography fork with the upstream cartography-cncf/cartography repository, bringing in a comprehensive set of new features and improvements.

Changes:

  • Added extensive new AWS resource support including Bedrock (foundation models, custom models, agents, guardrails), SageMaker (domains, endpoints, notebooks, models), CloudFront, VPC endpoints, and IAM server certificates
  • Added new Azure resources including Event Hubs, Key Vaults, Synapse, and comprehensive tag support across all resources
  • Added new GCP resources including Cloud Run, Cloud SQL, Vertex AI, and Cloud Functions with improved retry handling
  • Enhanced data models with datetime properties for IAM resources, cascade delete for cleanup jobs, and organization/tenant labeling across platforms
  • Added GitLab and Workday intel modules, improved Kubernetes secret tracking, and fixed various bugs

Reviewed changes

Copilot reviewed 163 out of 580 changed files in this pull request and generated no comments.

Show a summary per file
File Description
cartography/models/aws/resourcegroupstaggingapi/tag.py New schema definition for AWS tags with dynamic relationships
cartography/models/aws/iam/*.py Added datetime properties for date fields across IAM resources
cartography/models/aws/ec2/*.py New schemas for VPC endpoints, elastic IPs, internet gateways, reserved instances, and route tables
cartography/models/aws/bedrock/*.py Complete Bedrock integration schemas for AI/ML resources
cartography/models/aws/sagemaker/*.py Complete SageMaker integration schemas for ML infrastructure
cartography/models/aws/cloudtrail/trail.py Added event selector properties to CloudTrail
cartography/models/aws/ecs/services.py Enhanced ECS service-to-task relationship matching
cartography/intel/aws/*.py Implementation of new AWS resource syncing modules
cartography/intel/azure/*.py Added tag support and new resources across Azure
cartography/intel/gcp/*.py Added new GCP services and retry handling utilities
cartography/intel/kubernetes/*.py Enhanced secret tracking and service-to-load-balancer matching
cartography/intel/gitlab/*.py New GitLab integration for organizations, groups, and branches
cartography/intel/workday/*.py New Workday people integration
cartography/graph/*.py Added cascade delete support for cleanup jobs
cartography/config.py, cartography/cli.py Added configuration for new integrations
.github/workflows/*.yml Updated dependency versions and workflow configurations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@josemazo josemazo merged commit 9e3dd64 into prowler-cloud:master Jan 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.