software-intake-gatekeeper 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. software_intake_gatekeeper-0.2.1/.gitignore +15 -0
  2. software_intake_gatekeeper-0.2.1/CHANGELOG.md +57 -0
  3. software_intake_gatekeeper-0.2.1/LICENSE +21 -0
  4. software_intake_gatekeeper-0.2.1/PKG-INFO +407 -0
  5. software_intake_gatekeeper-0.2.1/README.md +369 -0
  6. software_intake_gatekeeper-0.2.1/SECURITY.md +28 -0
  7. software_intake_gatekeeper-0.2.1/action-requirements.txt +38 -0
  8. software_intake_gatekeeper-0.2.1/action.yml +93 -0
  9. software_intake_gatekeeper-0.2.1/examples/demo-app-src/dist/settings.min.js +2 -0
  10. software_intake_gatekeeper-0.2.1/examples/demo-app-src/main.js +26 -0
  11. software_intake_gatekeeper-0.2.1/examples/demo-app-src/node_modules/@demo/ui-kit/package.json +5 -0
  12. software_intake_gatekeeper-0.2.1/examples/demo-app-src/node_modules/lodash/index.js +2 -0
  13. software_intake_gatekeeper-0.2.1/examples/demo-app-src/node_modules/lodash/package.json +5 -0
  14. software_intake_gatekeeper-0.2.1/examples/demo-app-src/node_modules/minimist/package.json +5 -0
  15. software_intake_gatekeeper-0.2.1/examples/demo-app-src/package.json +8 -0
  16. software_intake_gatekeeper-0.2.1/examples/demo-app-src/preload.js +2 -0
  17. software_intake_gatekeeper-0.2.1/examples/go-demo/go.mod +5 -0
  18. software_intake_gatekeeper-0.2.1/examples/go-demo/go.sum +2 -0
  19. software_intake_gatekeeper-0.2.1/examples/go-demo/main.go +16 -0
  20. software_intake_gatekeeper-0.2.1/examples/intake-policy.toml +27 -0
  21. software_intake_gatekeeper-0.2.1/examples/update-demo/v1/resources/app/main.js +4 -0
  22. software_intake_gatekeeper-0.2.1/examples/update-demo/v1/resources/app/node_modules/lodash/package.json +5 -0
  23. software_intake_gatekeeper-0.2.1/examples/update-demo/v1/resources/app/package.json +5 -0
  24. software_intake_gatekeeper-0.2.1/examples/update-demo/v2/resources/app/main.js +5 -0
  25. software_intake_gatekeeper-0.2.1/examples/update-demo/v2/resources/app/node_modules/axios/package.json +5 -0
  26. software_intake_gatekeeper-0.2.1/examples/update-demo/v2/resources/app/node_modules/fast-native/build/Release/addon.node +0 -0
  27. software_intake_gatekeeper-0.2.1/examples/update-demo/v2/resources/app/node_modules/lodash/package.json +5 -0
  28. software_intake_gatekeeper-0.2.1/examples/update-demo/v2/resources/app/package.json +5 -0
  29. software_intake_gatekeeper-0.2.1/examples/vulnerable-demo/dotnet/IntakeDemo.deps.json +41 -0
  30. software_intake_gatekeeper-0.2.1/examples/vulnerable-demo/dotnet/IntakeDemo.runtimeconfig.json +9 -0
  31. software_intake_gatekeeper-0.2.1/examples/vulnerable-demo/resources/app.asar +0 -0
  32. software_intake_gatekeeper-0.2.1/pyproject.toml +90 -0
  33. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/__init__.py +3 -0
  34. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/__main__.py +3 -0
  35. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/asar.py +117 -0
  36. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/cli.py +149 -0
  37. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/diff.py +154 -0
  38. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/electron.py +190 -0
  39. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/engine.py +93 -0
  40. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/golang.py +143 -0
  41. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/model.py +207 -0
  42. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/osv.py +302 -0
  43. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/output.py +618 -0
  44. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/policy.py +192 -0
  45. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/py.typed +0 -0
  46. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/rules.py +156 -0
  47. software_intake_gatekeeper-0.2.1/src/intake_gatekeeper/scanner.py +477 -0
  48. software_intake_gatekeeper-0.2.1/tests/conftest.py +56 -0
  49. software_intake_gatekeeper-0.2.1/tests/test_asar.py +106 -0
  50. software_intake_gatekeeper-0.2.1/tests/test_cli.py +122 -0
  51. software_intake_gatekeeper-0.2.1/tests/test_diff.py +161 -0
  52. software_intake_gatekeeper-0.2.1/tests/test_electron.py +84 -0
  53. software_intake_gatekeeper-0.2.1/tests/test_golang.py +109 -0
  54. software_intake_gatekeeper-0.2.1/tests/test_live_osv.py +29 -0
  55. software_intake_gatekeeper-0.2.1/tests/test_osv.py +193 -0
  56. software_intake_gatekeeper-0.2.1/tests/test_output.py +113 -0
  57. software_intake_gatekeeper-0.2.1/tests/test_policy.py +167 -0
  58. software_intake_gatekeeper-0.2.1/tests/test_scanner.py +148 -0
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ /build/
5
+ /dist/
6
+ *.egg-info/
7
+ .pytest_cache/
8
+ .ruff_cache/
9
+ .mypy_cache/
10
+ .coverage
11
+ # Built in CI/tests from examples/go-demo; never committed.
12
+ examples/vulnerable-demo/bin/
13
+ tests/.go-fixtures/
14
+ reports/
15
+ intake-gatekeeper.*
@@ -0,0 +1,57 @@
1
+ # Changelog
2
+
3
+ All notable changes are recorded here. The project follows [Semantic Versioning](https://semver.org/);
4
+ while the major version is 0, minor releases may change behaviour.
5
+
6
+ ## [0.2.1] - 2026-10-15
7
+
8
+ ### Added
9
+
10
+ - Published on PyPI: `python -m pip install software-intake-gatekeeper`. Releases are uploaded by
11
+ the release workflow through PyPI trusted publishing, without a stored token.
12
+
13
+ ### Changed
14
+
15
+ - README links are absolute so they also work on the PyPI project page.
16
+
17
+ ## [0.2.0] - 2026-10-14
18
+
19
+ ### Added
20
+
21
+ - `intake-gatekeeper diff OLD NEW`: compares two versions and decides on what the update adds.
22
+ It reports new and resolved findings, component changes, Electron version and fuse changes
23
+ (flagging weakened fuses), new or removed network endpoints and new, removed or changed
24
+ executables and native modules. SARIF contains only the new findings.
25
+ - `compare-to` input for the GitHub Action to run the update check.
26
+ - Scan reports now list network endpoints referenced by app code and SHA-256 fingerprints of
27
+ executables and native modules.
28
+ - Fictional two-version update demo in `examples/update-demo`.
29
+
30
+ ### Changed
31
+
32
+ - The CLI shares its output options between `scan` and `diff`.
33
+
34
+ ## [0.1.0] - 2026-10-14
35
+
36
+ First public release and first GitHub Marketplace listing.
37
+
38
+ ### Added
39
+
40
+ - Read-only scanner for directories, Electron `.asar` archives and executables (PE, ELF, Mach-O).
41
+ - Inventories: Go build info (Go 1.18+), npm packages on disk and inside ASAR, NuGet `.deps.json`
42
+ packages and runtime packs, .NET `runtimeconfig.json` frameworks, Electron runtime version.
43
+ - Electron hardening: fuse-wire decoding (9 fuses) and `webPreferences` rules with line, column and snippet evidence.
44
+ - Opt-in OSV.dev lookup: batching, pagination, retries, alias grouping, GHSA severity resolution and nearest fixed version.
45
+ - Policy file with thresholds, rule overrides and expiring, component-scoped waivers. APPROVE / REVIEW / REJECT decision; blocking coverage gaps prevent APPROVE.
46
+ - Reports: JSON, CycloneDX 1.6, SARIF 2.1.0 (paths relative to the working directory for code scanning) and Markdown.
47
+ - Composite GitHub Action with hash-pinned dependencies, job summary and `decision`, `sarif` and `sbom` outputs.
48
+
49
+ ### Known limitations
50
+
51
+ - Version-level matching, not reachability analysis.
52
+ - No Rust `cargo auditable`, Python wheel, Java or native C/C++ inventories yet.
53
+ - Electron code rules detect literal settings only.
54
+
55
+ [0.2.1]: https://github.com/Sushant-Nemade/software-intake-gatekeeper/releases/tag/v0.2.1
56
+ [0.2.0]: https://github.com/Sushant-Nemade/software-intake-gatekeeper/releases/tag/v0.2.0
57
+ [0.1.0]: https://github.com/Sushant-Nemade/software-intake-gatekeeper/releases/tag/v0.1.0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sushant Nemade
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,407 @@
1
+ Metadata-Version: 2.5
2
+ Name: software-intake-gatekeeper
3
+ Version: 0.2.1
4
+ Summary: Local, evidence-first intake checks for third-party apps and binaries: SBOM, known vulnerabilities and Electron hardening.
5
+ Project-URL: Homepage, https://github.com/Sushant-Nemade/software-intake-gatekeeper
6
+ Project-URL: Source, https://github.com/Sushant-Nemade/software-intake-gatekeeper
7
+ Project-URL: Changelog, https://github.com/Sushant-Nemade/software-intake-gatekeeper/blob/main/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/Sushant-Nemade/software-intake-gatekeeper/issues
9
+ Project-URL: GitHub Marketplace, https://github.com/marketplace/actions/software-intake-gatekeeper
10
+ Author: Sushant Nemade
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Keywords: cyclonedx,electron,osv,sarif,sbom,security,supply-chain
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Information Technology
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Topic :: Security
24
+ Classifier: Topic :: Software Development :: Quality Assurance
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.11
27
+ Requires-Dist: httpx<1,>=0.28
28
+ Requires-Dist: truststore>=0.10
29
+ Provides-Extra: dev
30
+ Requires-Dist: build>=1.2; extra == 'dev'
31
+ Requires-Dist: cyclonedx-python-lib[json-validation]>=9; extra == 'dev'
32
+ Requires-Dist: mypy>=1.13; extra == 'dev'
33
+ Requires-Dist: pip-audit>=2.7; extra == 'dev'
34
+ Requires-Dist: pytest>=8.3; extra == 'dev'
35
+ Requires-Dist: ruff>=0.8; extra == 'dev'
36
+ Requires-Dist: twine>=6; extra == 'dev'
37
+ Description-Content-Type: text/markdown
38
+
39
+ # Software Intake Gatekeeper
40
+
41
+ [![CI](https://github.com/Sushant-Nemade/software-intake-gatekeeper/actions/workflows/ci.yml/badge.svg)](https://github.com/Sushant-Nemade/software-intake-gatekeeper/actions/workflows/ci.yml)
42
+ [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-Software%20Intake%20Gatekeeper-blue?logo=github)](https://github.com/marketplace/actions/software-intake-gatekeeper)
43
+ [![PyPI](https://img.shields.io/pypi/v/software-intake-gatekeeper)](https://pypi.org/project/software-intake-gatekeeper/)
44
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/Sushant-Nemade/software-intake-gatekeeper/blob/main/LICENSE)
45
+
46
+ **Before you install, approve or ship a third-party app, find out what is inside it.**
47
+
48
+ Software Intake Gatekeeper reads an installed application, an Electron `.asar` archive or a
49
+ compiled binary. It never runs or unpacks it. It produces:
50
+
51
+ - a **CycloneDX 1.6 SBOM** of the components that are actually bundled,
52
+ - **known vulnerabilities** for those exact versions from [OSV.dev](https://osv.dev) (only when you opt in),
53
+ - **Electron hardening checks** for the fuse wire inside the executable and risky `BrowserWindow`
54
+ settings in the app code,
55
+ - an **APPROVE / REVIEW / REJECT** decision from a versioned policy, with expiring waivers,
56
+ - an **update check** that compares two versions and gates on what the update *adds*: new
57
+ vulnerabilities, weakened Electron fuses, new network endpoints, new native modules,
58
+ - **SARIF** for GitHub code scanning, a **Markdown** summary for pull requests and a full **JSON** evidence report.
59
+
60
+ Every finding names the file and, for scripts, the line, column and snippet that produced it.
61
+ Anything the scanner could not verify is reported as a **coverage gap**. A blocking gap can
62
+ never lead to APPROVE: an unknown result is not treated as safe.
63
+
64
+ > Status: [v0.2.1](https://github.com/Sushant-Nemade/software-intake-gatekeeper/releases/tag/v0.2.1),
65
+ > an alpha release on [PyPI](https://pypi.org/project/software-intake-gatekeeper/) and the
66
+ > [GitHub Marketplace](https://github.com/marketplace/actions/software-intake-gatekeeper). The CLI is
67
+ > tested on Windows and Linux with real Go binaries in three object formats, an ASAR archive packed
68
+ > by the official `@electron/asar` tool and the live OSV API; the action also runs on macOS. The
69
+ > results are static, version-level evidence, not proof of exploitability.
70
+
71
+ Part of a small **software trust toolkit** with
72
+ [Privacy Flow Inspector](https://github.com/Sushant-Nemade/privacy-flow-inspector): this tool checks
73
+ what is **inside** an app; the inspector checks which personal data the app **sends out**.
74
+
75
+ ![Update check summary for the fictional demo: REJECT, 25 new findings, 1 new endpoint and 1 new native module](https://raw.githubusercontent.com/Sushant-Nemade/software-intake-gatekeeper/main/docs/images/update-check-summary.png)
76
+
77
+ ## Where it helps
78
+
79
+ | Who | Situation | What they get |
80
+ |---|---|---|
81
+ | IT / security intake | An employee requests a desktop tool (an Electron or Go CLI) | An SBOM, known CVEs and Electron hardening issues before approval, with a decision a reviewer can sign off |
82
+ | Product teams shipping Electron | A release candidate is ready | A CI gate that fails when `contextIsolation` is off, `RunAsNode` is enabled or bundled packages have critical advisories |
83
+ | Supply-chain / compliance (EU CRA, medical-device SBOM expectations) | A vendor delivers a binary without an SBOM | A CycloneDX SBOM built from evidence inside the binary, with occurrences pointing to the source files |
84
+ | Procurement / vendor review | Comparing two vendor builds | Reproducible JSON and SBOM output that can be compared across versions |
85
+
86
+ ## Quick start
87
+
88
+ Install from [PyPI](https://pypi.org/project/software-intake-gatekeeper/) (Python 3.11+):
89
+
90
+ ```powershell
91
+ python -m pip install software-intake-gatekeeper
92
+ ```
93
+
94
+ To verify build provenance first, install the wheel from the GitHub release instead:
95
+
96
+ ```powershell
97
+ gh release download v0.2.1 -R Sushant-Nemade/software-intake-gatekeeper -p "*.whl"
98
+ gh attestation verify software_intake_gatekeeper-0.2.1-py3-none-any.whl -R Sushant-Nemade/software-intake-gatekeeper
99
+ python -m pip install software_intake_gatekeeper-0.2.1-py3-none-any.whl
100
+ ```
101
+
102
+ Or install from a clone (needed for the demo below):
103
+
104
+ ```powershell
105
+ git clone https://github.com/Sushant-Nemade/software-intake-gatekeeper
106
+ cd software-intake-gatekeeper
107
+ python -m pip install .
108
+ ```
109
+
110
+ Then scan:
111
+
112
+ ```powershell
113
+ # Offline inventory and Electron checks (no network):
114
+ intake-gatekeeper scan "C:\Program Files\SomeApp"
115
+
116
+ # Add known-vulnerability lookup and write every report:
117
+ intake-gatekeeper scan "C:\Program Files\SomeApp" --osv `
118
+ --json reports/report.json --sarif reports/report.sarif `
119
+ --cyclonedx reports/sbom.cdx.json --markdown reports/summary.md
120
+ ```
121
+
122
+ Exit status: `0` the decision passed the `--fail-on` threshold (default `reject`), `1` the gate
123
+ failed, `2` usage or input error. Run `intake-gatekeeper rules` to list the configuration rules.
124
+
125
+ ### Try the fictional vulnerable demo
126
+
127
+ `examples/vulnerable-demo` is a deliberately insecure, **fictional** target. It contains an ASAR
128
+ archive packed by the official `@electron/asar` tool, a `.deps.json` file and, after the build
129
+ step, a real Go binary and a synthetic Electron executable stand-in.
130
+
131
+ ```powershell
132
+ python scripts/build_demo.py # Go is optional; it builds the real Go demo binary
133
+ intake-gatekeeper scan examples/vulnerable-demo --osv --policy examples/intake-policy.toml
134
+ ```
135
+
136
+ Real output (2026-10-14, live OSV):
137
+
138
+ ```text
139
+ Decision: REJECT
140
+ - 19 finding(s) at or above high.
141
+ - 41 finding(s) between low and high.
142
+ Target: vulnerable-demo | files 5 | archive entries 8 | lookup osv
143
+ Components: Go 3, NuGet 2, npm 5
144
+ Findings: critical 1, high 18, medium 31, low 10, info 0
145
+ Electron 28.0.0 at bin/electron-runtime-stand-in.bin
146
+ [CRITICAL] GHSA-xvch-5gv4-984h minimist 1.2.5: Prototype Pollution in minimist @ resources/app.asar!/node_modules/minimist/package.json
147
+ [HIGH ] EGK-FUSE-RUN-AS-NODE RunAsNode fuse is enabled @ bin/electron-runtime-stand-in.bin
148
+ [HIGH ] EGK-JS-CONTEXT-ISOLATION-OFF Context isolation is disabled @ resources/app.asar!/main.js:12
149
+ [HIGH ] EGK-JS-NODE-INTEGRATION Renderer has Node.js integration enabled @ resources/app.asar!/main.js:11
150
+ [HIGH ] GHSA-5crp-9r3c-p9vr Newtonsoft.Json 12.0.1: Improper Handling of Exceptional Conditions in Newtonsoft.Json @ dotnet/IntakeDemo.deps.json
151
+ [HIGH ] GHSA-69ch-w2m2-3vjp golang.org/x/text v0.3.7: golang.org/x/text/language Denial of service via crafted Accept-Languag... @ bin/intake-demo-tool.exe
152
+ ...
153
+ ```
154
+
155
+ The Markdown summary also includes a table of components with known vulnerabilities and the
156
+ smallest listed fixed version above the current one (for example `minimist 1.2.6`,
157
+ `Newtonsoft.Json 13.0.1`). One lodash advisory shows as *waived* because the example policy
158
+ accepts it until 2026-12-31 with a written reason.
159
+
160
+ ### Check an update before rolling it out
161
+
162
+ `diff` scans the version you run today and the new one, then decides on **what the update adds**.
163
+ Persisting issues are listed but do not block the update; run `scan` for an absolute assessment.
164
+
165
+ ```powershell
166
+ intake-gatekeeper diff examples/update-demo/v1 examples/update-demo/v2 --osv `
167
+ --json reports/update.json --markdown reports/update.md --sarif reports/update.sarif
168
+ ```
169
+
170
+ Real output for the fictional [update demo](https://github.com/Sushant-Nemade/software-intake-gatekeeper/tree/main/examples/update-demo) (2026-10-14, live OSV). Version 2
171
+ fixes a `nodeIntegration` setting and upgrades lodash, but adds axios 0.21.1, a telemetry endpoint and
172
+ a native module:
173
+
174
+ ```text
175
+ Update decision: REJECT
176
+ - 12 new finding(s) at or above high.
177
+ - 13 new finding(s) between low and high.
178
+ - 1 new network endpoint(s) referenced by app code.
179
+ - 1 new executable(s) or native module(s).
180
+ - 1 new component(s).
181
+ Findings: 25 new, 4 resolved, 1 persisting
182
+ Components changed: 2 | endpoints +1/-0 | binaries +1/-0/~0
183
+ NEW [HIGH ] GHSA-cph5-m8f7-6c5x axios 0.21.1: axios Inefficient Regular Expression Complexity vulnerability
184
+ ...
185
+ NEW endpoint collect.metrics-collector.example
186
+ ```
187
+
188
+ | The update check reports | How it is matched |
189
+ |---|---|
190
+ | New and resolved findings | Advisory id plus package name (so a version bump that keeps the bug counts as persisting), or rule plus file |
191
+ | Component changes | Added, removed or changed versions per ecosystem and name |
192
+ | Electron | Runtime version change and every fuse change; a fuse moving into its risky state is **weakened** |
193
+ | Network endpoints | Hosts in `http(s)://` and `ws(s)://` URLs in app code (outside `node_modules`), without XML namespaces or local addresses |
194
+ | Executables and native modules | Added, removed or changed (SHA-256) PE, ELF and Mach-O files, including `.node` modules |
195
+
196
+ **REJECT** if a new finding reaches `reject_at`. **REVIEW** for new findings at `review_at`, weakened
197
+ fuses, new endpoints, new binaries, new components or blocking gaps in the new version.
198
+ **APPROVE** otherwise. The SARIF output contains only the new findings.
199
+
200
+ ## What it inspects
201
+
202
+ | Evidence | Source inside the target | Output |
203
+ |---|---|---|
204
+ | Go modules and toolchain | Build info embedded by the Go linker (Go 1.18+) in PE, ELF and Mach-O executables | `pkg:golang/...` components, including `stdlib` and `replace` directives |
205
+ | npm packages | `node_modules/**/package.json` on disk and inside `.asar` archives | `pkg:npm/...` components; the app's own manifest is recorded but not queried |
206
+ | NuGet packages | `*.deps.json` (`package` and self-contained `runtimepack` entries) | `pkg:nuget/...` components |
207
+ | .NET shared framework | `*.runtimeconfig.json` | Minimum framework version, plus a note that the host runtime decides the patch level |
208
+ | Electron runtime | The fuse sentinel and `Electron/x.y.z` string in the executable | Electron version (queried as npm `electron`) and the fuse states |
209
+ | Electron app code | `.js/.cjs/.mjs/.ts` files outside `node_modules`, on disk or in `.asar` | `webPreferences` rule findings with line, column and snippet |
210
+ | Network endpoints | `http(s)://` and `ws(s)://` hosts referenced by that app code | Host list with up to three source files each (used by the update check) |
211
+ | Executables and native modules | PE, ELF and Mach-O files, including `.node` add-ons | Path, size, SHA-256 and kind (Go, Electron, native) |
212
+
213
+ ### Electron rules
214
+
215
+ | Rule | Default | Detects |
216
+ |---|---|---|
217
+ | `EGK-JS-NODE-INTEGRATION` | high | `nodeIntegration: true` (also minified `!0`) |
218
+ | `EGK-JS-CONTEXT-ISOLATION-OFF` | high | `contextIsolation: false` |
219
+ | `EGK-JS-WEB-SECURITY-OFF` | high | `webSecurity: false` |
220
+ | `EGK-JS-INSECURE-CONTENT` | high | `allowRunningInsecureContent: true` |
221
+ | `EGK-JS-SANDBOX-OFF` | medium | `sandbox: false` within a `webPreferences` object |
222
+ | `EGK-JS-NODE-INTEGRATION-EXTENDED` | medium | Node.js in sub-frames or workers |
223
+ | `EGK-JS-REMOTE-MODULE` | medium | `enableRemoteModule: true` |
224
+ | `EGK-JS-WEBVIEW-TAG` / `EGK-JS-EXPERIMENTAL-FEATURES` | low | `<webview>` or experimental features enabled |
225
+ | `EGK-JS-OPEN-EXTERNAL` | info | `shell.openExternal(` call sites to review |
226
+ | `EGK-FUSE-RUN-AS-NODE`, `-NODE-OPTIONS`, `-NODE-INSPECT` | medium | Fuses that let a trusted binary run arbitrary Node.js code |
227
+ | `EGK-FUSE-ASAR-INTEGRITY-OFF`, `-LOAD-OUTSIDE-ASAR`, `-COOKIE-ENCRYPTION-OFF`, `-FILE-PROTOCOL-PRIVILEGES` | low | Integrity and hardening fuses left at their defaults |
228
+
229
+ Each rule links to the matching section of Electron's
230
+ [security checklist](https://www.electronjs.org/docs/latest/tutorial/security) or
231
+ [fuses guide](https://www.electronjs.org/docs/latest/tutorial/fuses).
232
+
233
+ ## Decision model
234
+
235
+ ```mermaid
236
+ flowchart LR
237
+ T[Target: folder / .asar / binary] --> S[Read-only scanner]
238
+ S --> C[Components + evidence]
239
+ S --> F[Electron findings]
240
+ S --> G[Coverage gaps]
241
+ C -->|--osv, opt-in| O[OSV.dev: ecosystem, name, version only]
242
+ O --> V[Alias-grouped advisories + nearest fix]
243
+ F --> P[Policy: thresholds, overrides, expiring waivers]
244
+ V --> P
245
+ G --> P
246
+ P --> D{APPROVE / REVIEW / REJECT}
247
+ D --> R[JSON, SARIF, CycloneDX, Markdown]
248
+ ```
249
+
250
+ - **REJECT**: any unwaived finding at or above `reject_at` (default `high`).
251
+ - **REVIEW**: findings at or above `review_at` (default `low`), or any blocking coverage gap,
252
+ such as a skipped lookup, an OSV failure, a size or file limit, an unparseable artifact or no
253
+ recognised content.
254
+ - **APPROVE**: none of the above.
255
+
256
+ Advisories that describe the same issue (for example `GHSA-69ch-w2m2-3vjp` and `GO-2022-1059`) are
257
+ merged into one finding. Severity comes from the GitHub-reviewed database rating, including linked
258
+ GHSA aliases. Advisories that no database rates (common for Go) are treated as
259
+ `unrated_vulnerability` (default `medium`) and labelled as such.
260
+
261
+ ### Policy
262
+
263
+ See [examples/intake-policy.toml](https://github.com/Sushant-Nemade/software-intake-gatekeeper/blob/main/examples/intake-policy.toml). Unknown keys are rejected. Every waiver
264
+ needs an id or alias, a written reason and an expiry date, and may be limited to one package URL.
265
+ Expired or unused waivers are reported.
266
+
267
+ ## GitHub Action
268
+
269
+ Available on the [GitHub Marketplace](https://github.com/marketplace/actions/software-intake-gatekeeper).
270
+ It runs on Linux, Windows and macOS runners; CI exercises all three.
271
+
272
+ ### Gate a packaged Electron app and publish alerts to code scanning
273
+
274
+ ```yaml
275
+ name: Intake gate
276
+ on: [pull_request, workflow_dispatch]
277
+
278
+ permissions:
279
+ contents: read
280
+ security-events: write # only needed for the SARIF upload step
281
+
282
+ jobs:
283
+ intake:
284
+ runs-on: ubuntu-latest
285
+ steps:
286
+ - uses: actions/checkout@v7
287
+ # ... build or download the app you want to check into dist/linux-unpacked ...
288
+ - name: Software Intake Gatekeeper
289
+ id: intake
290
+ uses: Sushant-Nemade/software-intake-gatekeeper@v0
291
+ with:
292
+ path: dist/linux-unpacked
293
+ fail-on: reject
294
+ - name: Upload SARIF
295
+ if: always() && steps.intake.outputs.sarif != ''
296
+ uses: github/codeql-action/upload-sarif@v4
297
+ with:
298
+ sarif_file: ${{ steps.intake.outputs.sarif }}
299
+ category: software-intake-gatekeeper
300
+ - name: Keep the SBOM and evidence
301
+ if: always()
302
+ uses: actions/upload-artifact@v7
303
+ with:
304
+ name: intake-gatekeeper-reports
305
+ path: intake-gatekeeper-reports/
306
+ ```
307
+
308
+ For supply-chain hardening, pin the action to the full commit SHA of a release instead of `@v0`.
309
+
310
+ ### Inputs
311
+
312
+ | Input | Default | Description |
313
+ |---|---|---|
314
+ | `path` | (required) | Installed app directory, `.asar` archive or executable to scan. |
315
+ | `compare-to` | `""` | Previous version of the same app. When set, the action runs the update check and gates on what the update adds. |
316
+ | `osv` | `true` | Look up known vulnerabilities on OSV.dev. Sends only ecosystem, name and version. Set `false` for fully offline runs. |
317
+ | `policy` | `""` | Path to a policy TOML file (see [examples/intake-policy.toml](https://github.com/Sushant-Nemade/software-intake-gatekeeper/blob/main/examples/intake-policy.toml)). |
318
+ | `fail-on` | `reject` | Decision that fails the step: `reject`, `review` or `never`. |
319
+ | `output-dir` | `intake-gatekeeper-reports` | Where `report.json`, `report.sarif`, `sbom.cdx.json` and `summary.md` are written. |
320
+
321
+ ### Outputs
322
+
323
+ | Output | Description |
324
+ |---|---|
325
+ | `decision` | `approve`, `review` or `reject` (`error` if no report was produced). |
326
+ | `sarif` | Path to the SARIF 2.1.0 report. Paths inside it are relative to the workspace so code scanning can link them. |
327
+ | `sbom` | Path to the CycloneDX 1.6 SBOM. |
328
+
329
+ The Markdown summary is appended to the job summary. The action installs hash-pinned
330
+ dependencies into a private virtual environment under `RUNNER_TEMP`, so it does not change the
331
+ job's Python. Inputs reach the script only through environment variables and are never
332
+ interpolated into shell code. No token or secret is required.
333
+
334
+ ### Versioning
335
+
336
+ Releases follow [Semantic Versioning](https://semver.org/) and are listed in [CHANGELOG.md](https://github.com/Sushant-Nemade/software-intake-gatekeeper/blob/main/CHANGELOG.md).
337
+ `v0` always points to the latest `v0.x.y` release. Release artifacts carry
338
+ [build provenance attestations](https://github.com/Sushant-Nemade/software-intake-gatekeeper/attestations)
339
+ and a `SHA256SUMS` file.
340
+
341
+ ## Privacy and network use
342
+
343
+ - Without `--osv` the tool makes **no network requests**.
344
+ - With `--osv`, it sends only `{ecosystem, name, version}` for each queryable component to
345
+ `https://api.osv.dev` (or a mirror set with `--osv-url`). It sends no file paths, hashes or file
346
+ contents. Private package names are sent as well, so use an internal OSV mirror if those names
347
+ are sensitive.
348
+ - TLS verification uses the operating-system trust store through
349
+ [truststore](https://pypi.org/project/truststore/), so corporate TLS inspection works without
350
+ disabling verification.
351
+
352
+ ## Verification
353
+
354
+ | Check | How |
355
+ |---|---|
356
+ | Go build info decoding | Compared with `go version -m` on real binaries built in CI for Windows PE, Linux ELF and macOS Mach-O |
357
+ | ASAR parsing | Fixture packed by `@electron/asar` 4.3.1; listing matches the official tool |
358
+ | Fuse decoding | Wire layout taken from `@electron/fuses`. A read-only local check on an installed Electron app (VS Code) matched `npx @electron/fuses read` for all 9 fuses |
359
+ | Output formats | CycloneDX validated with `cyclonedx-python-lib` against the 1.6 schema in tests. SARIF validated against the OASIS 2.1.0 schema during development |
360
+ | OSV client | Mocked transport tests (batching, pagination, retries, alias grouping, withdrawn advisories) plus an opt-in live test (`INTAKE_LIVE_OSV=1`) |
361
+ | Scale | Read-only scan of a locally installed VS Code: 3,243 files and 5,451 archive entries in about 19 s with a warm file cache |
362
+ | CI | Ubuntu (Python 3.11 and 3.13) and Windows (3.13): pytest, ruff, mypy `--strict`, build, twine, pip-audit. The action itself runs on Ubuntu, Windows and macOS against the demo with live OSV, plus fail-on, invalid-input and update-check (`compare-to`) runs |
363
+
364
+ No third-party application files are committed. The local real-app checks are listed for
365
+ transparency only.
366
+
367
+ ## Limitations
368
+
369
+ - Version matching is not reachability. A vulnerable function may never be called; use waivers
370
+ with reasons when you have checked this.
371
+ - It reads Go build info only for Go 1.18+ (older binaries are reported as gaps). It does not yet
372
+ read Rust `cargo auditable` sections, Python wheels, Java JARs or native C/C++ libraries.
373
+ - Electron code rules are pattern-based. They catch literal settings, including minified ones,
374
+ but not values computed at runtime.
375
+ - Installers (`.exe`/`.msi`/`.dmg`) must be extracted or installed first. The tool does not unpack
376
+ archives to disk.
377
+ - Electron versions are detected from the `Electron/x.y.z` string; if none or several are found,
378
+ this is reported as a gap.
379
+
380
+ ## Roadmap
381
+
382
+ 1. Rust `cargo auditable`, Python `*.dist-info` and Java `pom.properties` inventories.
383
+ 2. Signature and publisher changes (Authenticode, code signing) in the update check.
384
+ 3. An optional adapter for reverse-engineering evidence tools behind an approval gate.
385
+
386
+ Shipped from earlier roadmap items: the version-to-version update check (v0.2.0) and the
387
+ PII-in-HAR inspector, released as the separate
388
+ [Privacy Flow Inspector](https://github.com/Sushant-Nemade/privacy-flow-inspector).
389
+
390
+ ## Development
391
+
392
+ ```powershell
393
+ python -m pip install uv
394
+ uv sync --frozen --extra dev
395
+ $env:INTAKE_GO = "C:\path\to\go.exe" # optional; enables real Go binary tests
396
+ uv run --frozen --extra dev pytest -q
397
+ uv run --frozen --extra dev ruff check .
398
+ uv run --frozen --extra dev mypy
399
+ ```
400
+
401
+ ## Background and license
402
+
403
+ The idea came from studying evidence-first reverse-engineering tools, which show the evidence for
404
+ every conclusion and state what they could not determine. This project applies that approach to
405
+ software intake. All code here is original; no third-party tool source is included.
406
+
407
+ [MIT](https://github.com/Sushant-Nemade/software-intake-gatekeeper/blob/main/LICENSE) © 2026 Sushant Nemade. See [SECURITY.md](https://github.com/Sushant-Nemade/software-intake-gatekeeper/blob/main/SECURITY.md) for vulnerability reporting.