sec-report-kit 0.2.3__tar.gz → 0.2.4__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 (97) hide show
  1. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/.gitignore +1 -0
  2. sec_report_kit-0.2.4/CHANGELOG.md +46 -0
  3. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/PKG-INFO +26 -1
  4. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/README.md +25 -0
  5. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/pyproject.toml +1 -1
  6. sec_report_kit-0.2.4/requirements.txt +84 -0
  7. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/install_external_clis.py +85 -29
  8. sec_report_kit-0.2.4/scripts/run_codeql.bat +81 -0
  9. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_codeql.sh +7 -0
  10. sec_report_kit-0.2.4/scripts/run_osv_scanner.bat +80 -0
  11. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_tfsec.bat +13 -3
  12. sec_report_kit-0.2.4/scripts/run_trufflehog.bat +53 -0
  13. sec_report_kit-0.2.3/CHANGELOG.md +0 -28
  14. sec_report_kit-0.2.3/scripts/run_codeql.bat +0 -30
  15. sec_report_kit-0.2.3/scripts/run_osv_scanner.bat +0 -27
  16. sec_report_kit-0.2.3/scripts/run_trufflehog.bat +0 -27
  17. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/.gitattributes +0 -0
  18. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/.github/workflows/pip-audit.yml +0 -0
  19. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/.github/workflows/publish-pypi.yml +0 -0
  20. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/.github/workflows/publish-testpypi.yml +0 -0
  21. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/.github/workflows/trivy-fs-audit.yml +0 -0
  22. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/.github/workflows/unit-test-coverage-gate.yml +0 -0
  23. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/bandit-gaps-vs-sast-open-source-tools.md +0 -0
  24. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/check_assets.py +0 -0
  25. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/download_safety_db.bat +0 -0
  26. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/download_safety_db.py +0 -0
  27. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/download_safety_db.sh +0 -0
  28. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/install_tools.bat +0 -0
  29. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/install_tools.sh +0 -0
  30. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_bandit_html.bat +0 -0
  31. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_bandit_html.sh +0 -0
  32. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_checkov_html.bat +0 -0
  33. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_checkov_html.sh +0 -0
  34. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_codeql_html.bat +0 -0
  35. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_codeql_html.sh +0 -0
  36. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_gitleaks_html.bat +0 -0
  37. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_gitleaks_html.sh +0 -0
  38. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_osv_scanner_html.bat +0 -0
  39. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_osv_scanner_html.sh +0 -0
  40. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_pip_audit_html.bat +0 -0
  41. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_pip_audit_html.sh +0 -0
  42. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_safety_html.bat +0 -0
  43. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_safety_html.sh +0 -0
  44. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_semgrep_html.bat +0 -0
  45. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_semgrep_html.sh +0 -0
  46. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_tfsec_html.bat +0 -0
  47. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_tfsec_html.sh +0 -0
  48. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_trivy_html.bat +0 -0
  49. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_trivy_html.sh +0 -0
  50. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_trufflehog_html.bat +0 -0
  51. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/render_trufflehog_html.sh +0 -0
  52. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_bandit.bat +0 -0
  53. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_bandit.sh +0 -0
  54. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_checkov.bat +0 -0
  55. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_checkov.sh +0 -0
  56. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_gitleaks.bat +0 -0
  57. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_gitleaks.sh +0 -0
  58. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_osv_scanner.sh +0 -0
  59. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_pip_audit.bat +0 -0
  60. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_pip_audit.sh +0 -0
  61. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_safety.bat +0 -0
  62. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_safety.sh +0 -0
  63. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_semgrep.bat +0 -0
  64. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_semgrep.sh +0 -0
  65. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_tfsec.sh +0 -0
  66. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_trivy.bat +0 -0
  67. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_trivy.sh +0 -0
  68. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_trufflehog.sh +0 -0
  69. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_unit_tests_with_coverage.bat +0 -0
  70. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/scripts/run_unit_tests_with_coverage.sh +0 -0
  71. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/__init__.py +0 -0
  72. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/__main__.py +0 -0
  73. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/cli.py +0 -0
  74. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/mcp/__init__.py +0 -0
  75. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/mcp/server.py +0 -0
  76. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/models.py +0 -0
  77. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/__init__.py +0 -0
  78. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/bandit.py +0 -0
  79. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/checkov.py +0 -0
  80. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/codeql.py +0 -0
  81. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/gitleaks.py +0 -0
  82. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/osv_scanner.py +0 -0
  83. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/pip_audit.py +0 -0
  84. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/safety.py +0 -0
  85. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/semgrep.py +0 -0
  86. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/tfsec.py +0 -0
  87. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/trivy.py +0 -0
  88. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/parsers/trufflehog.py +0 -0
  89. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/report/__init__.py +0 -0
  90. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/report/html_renderer.py +0 -0
  91. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/services/__init__.py +0 -0
  92. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/services/normalize.py +0 -0
  93. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/src/sec_report_kit/services/summarize.py +0 -0
  94. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/tests/test_cli.py +0 -0
  95. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/tests/test_html_renderer.py +0 -0
  96. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/tests/test_mcp_server.py +0 -0
  97. {sec_report_kit-0.2.3 → sec_report_kit-0.2.4}/tests/test_parsers.py +0 -0
@@ -93,3 +93,4 @@ data/
93
93
  logs/
94
94
  security_reports/
95
95
  .tools/
96
+ codeql-db/
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file.
4
+
5
+ ## 0.2.4 - 2026-05-14
6
+
7
+ ### Added
8
+ - `scripts/install_external_clis.py` now supports `--tool` for targeted installs.
9
+ - `scripts/install_external_clis.py` now supports `--force` to re-download tools even when already installed.
10
+ - `README.md` now documents external CLI installer options and usage examples.
11
+
12
+ ### Changed
13
+ - External CLI installer now skips already-installed tools by default.
14
+ - CodeQL install handling on Windows now uses staged extraction and merge to avoid directory lock errors during reinstall.
15
+ - `scripts/run_osv_scanner.bat` now auto-generates `requirements.txt` from installed packages when no supported lockfile is present.
16
+
17
+ ### Fixed
18
+ - `scripts/run_codeql.bat` now repairs incomplete local CodeQL installs and validates SARIF output existence.
19
+ - `scripts/run_codeql.sh` now validates SARIF output existence after analysis.
20
+ - `scripts/run_trufflehog.bat` now writes scanner output via temp files to avoid self-scan file locking.
21
+ - `scripts/run_trufflehog.bat` now writes `[]` when no findings are present.
22
+
23
+ ## 0.2.3 - 2026-05-13
24
+
25
+ ### Added
26
+ - Safety CLI parser support and HTML rendering flow.
27
+ - New CLI command: `srk render safety`.
28
+ - MCP support for `source_type="safety"`.
29
+ - Helper scripts for Safety scan and render:
30
+ - `scripts/run_safety.sh`
31
+ - `scripts/run_safety.bat`
32
+ - `scripts/render_safety_html.sh`
33
+ - `scripts/render_safety_html.bat`
34
+ - Offline Safety DB download helpers:
35
+ - `scripts/download_safety_db.py`
36
+ - `scripts/download_safety_db.sh`
37
+ - `scripts/download_safety_db.bat`
38
+
39
+ ### Changed
40
+ - Auto-detection now recognizes Safety JSON payloads.
41
+ - Tool installation scripts now install Safety CLI in the app venv.
42
+ - README updated with Safety usage and offline/local DB workflow guidance.
43
+
44
+ ### Fixed
45
+ - Safety run scripts now avoid false success when network failures occur.
46
+ - JSON output validation improved for Safety execution paths.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sec-report-kit
3
- Version: 0.2.3
3
+ Version: 0.2.4
4
4
  Summary: Generate HTML security reports from Trivy, pip-audit, Safety, Bandit, and Gitleaks JSON
5
5
  Author: Ravi Konduru
6
6
  License: MIT
@@ -100,6 +100,31 @@ scripts\install_tools.bat
100
100
 
101
101
  After cloning on a new machine, run the install script above to recreate the local `.tools/` directory and install required external CLI binaries (`codeql`, `tfsec`, `gitleaks`, `trufflehog`, `osv-scanner`) alongside Python dependencies. The `.tools/` folder is intentionally not committed to git.
102
102
 
103
+ Install or update external CLI binaries directly:
104
+
105
+ ```bash
106
+ python scripts/install_external_clis.py --repo-root .
107
+ ```
108
+
109
+ Default behavior skips tools that are already installed locally.
110
+
111
+ Force re-download/reinstall for all supported external tools:
112
+
113
+ ```bash
114
+ python scripts/install_external_clis.py --repo-root . --force
115
+ ```
116
+
117
+ Install only selected tool(s) with `--tool` (can be repeated or comma-separated):
118
+
119
+ ```bash
120
+ python scripts/install_external_clis.py --repo-root . --tool osv-scanner
121
+ python scripts/install_external_clis.py --repo-root . --tool tfsec --tool gitleaks --force
122
+ python scripts/install_external_clis.py --repo-root . --tool tfsec,gitleaks
123
+ ```
124
+
125
+ Supported `--tool` values: `codeql`, `tfsec`, `gitleaks`, `trufflehog`, `osv-scanner`.
126
+ For convenience, `ocs-scanner` is accepted as an alias for `osv-scanner`.
127
+
103
128
  Run all unit tests locally with coverage:
104
129
 
105
130
  ```bash
@@ -73,6 +73,31 @@ scripts\install_tools.bat
73
73
 
74
74
  After cloning on a new machine, run the install script above to recreate the local `.tools/` directory and install required external CLI binaries (`codeql`, `tfsec`, `gitleaks`, `trufflehog`, `osv-scanner`) alongside Python dependencies. The `.tools/` folder is intentionally not committed to git.
75
75
 
76
+ Install or update external CLI binaries directly:
77
+
78
+ ```bash
79
+ python scripts/install_external_clis.py --repo-root .
80
+ ```
81
+
82
+ Default behavior skips tools that are already installed locally.
83
+
84
+ Force re-download/reinstall for all supported external tools:
85
+
86
+ ```bash
87
+ python scripts/install_external_clis.py --repo-root . --force
88
+ ```
89
+
90
+ Install only selected tool(s) with `--tool` (can be repeated or comma-separated):
91
+
92
+ ```bash
93
+ python scripts/install_external_clis.py --repo-root . --tool osv-scanner
94
+ python scripts/install_external_clis.py --repo-root . --tool tfsec --tool gitleaks --force
95
+ python scripts/install_external_clis.py --repo-root . --tool tfsec,gitleaks
96
+ ```
97
+
98
+ Supported `--tool` values: `codeql`, `tfsec`, `gitleaks`, `trufflehog`, `osv-scanner`.
99
+ For convenience, `ocs-scanner` is accepted as an alias for `osv-scanner`.
100
+
76
101
  Run all unit tests locally with coverage:
77
102
 
78
103
  ```bash
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sec-report-kit"
7
- version = "0.2.3"
7
+ version = "0.2.4"
8
8
  description = "Generate HTML security reports from Trivy, pip-audit, Safety, Bandit, and Gitleaks JSON"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -0,0 +1,84 @@
1
+ annotated-doc==0.0.4
2
+ annotated-types==0.7.0
3
+ anyio==4.13.0
4
+ attrs==26.1.0
5
+ bandit==1.9.4
6
+ boolean.py==5.0
7
+ build==1.5.0
8
+ CacheControl==0.14.4
9
+ certifi==2026.4.22
10
+ cffi==2.0.0
11
+ charset-normalizer==3.4.7
12
+ click==8.3.3
13
+ colorama==0.4.6
14
+ coverage==7.14.0
15
+ cryptography==47.0.0
16
+ cyclonedx-python-lib==11.7.0
17
+ defusedxml==0.7.1
18
+ docutils==0.22.4
19
+ filelock==3.29.0
20
+ h11==0.16.0
21
+ httpcore==1.0.9
22
+ httpx==0.28.1
23
+ httpx-sse==0.4.3
24
+ id==1.6.1
25
+ idna==3.13
26
+ iniconfig==2.3.0
27
+ jaraco.classes==3.4.0
28
+ jaraco.context==6.1.2
29
+ jaraco.functools==4.4.0
30
+ jsonschema==4.26.0
31
+ jsonschema-specifications==2025.9.1
32
+ keyring==25.7.0
33
+ license-expression==30.4.4
34
+ markdown-it-py==4.0.0
35
+ mcp==1.27.0
36
+ mdurl==0.1.2
37
+ more-itertools==11.0.2
38
+ msgpack==1.1.2
39
+ nh3==0.3.5
40
+ packageurl-python==0.17.6
41
+ packaging==26.2
42
+ pip-api==0.0.34
43
+ pip-requirements-parser==32.0.1
44
+ pip_audit==2.10.0
45
+ platformdirs==4.9.6
46
+ pluggy==1.6.0
47
+ py-serializable==2.1.0
48
+ pycparser==3.0
49
+ pydantic==2.13.3
50
+ pydantic-settings==2.14.0
51
+ pydantic_core==2.46.3
52
+ pyfiglet==1.0.4
53
+ Pygments==2.20.0
54
+ PyJWT==2.12.1
55
+ pyparsing==3.3.2
56
+ pyproject_hooks==1.2.0
57
+ pytest==9.0.3
58
+ pytest-cov==7.1.0
59
+ python-dotenv==1.2.2
60
+ python-multipart==0.0.27
61
+ pywin32==311
62
+ pywin32-ctypes==0.2.3
63
+ PyYAML==6.0.3
64
+ readme_renderer==44.0
65
+ referencing==0.37.0
66
+ requests==2.33.1
67
+ requests-toolbelt==1.0.0
68
+ rfc3986==2.0.0
69
+ rich==15.0.0
70
+ rpds-py==0.30.0
71
+ -e git+https://github.com/ShanKonduru/sec-report-kit.git@b6d196bac687e07189e884e2fe25af5c8842da1d#egg=sec_report_kit
72
+ shellingham==1.5.4
73
+ sortedcontainers==2.4.0
74
+ sse-starlette==3.4.1
75
+ starlette==1.0.0
76
+ stevedore==5.7.0
77
+ tomli==2.4.1
78
+ tomli_w==1.2.0
79
+ twine==6.2.0
80
+ typer==0.25.1
81
+ typing-inspection==0.4.2
82
+ typing_extensions==4.15.0
83
+ urllib3==2.6.3
84
+ uvicorn==0.46.0
@@ -12,6 +12,7 @@ import re
12
12
  import shutil
13
13
  import stat
14
14
  import tarfile
15
+ import tempfile
15
16
  import urllib.error
16
17
  import urllib.request
17
18
  import zipfile
@@ -127,20 +128,26 @@ def extract_binary_from_archive(data: bytes, archive_name: str, binary_names: li
127
128
 
128
129
  def install_codeql(asset_data: bytes, asset_name: str, tools_bin: Path) -> None:
129
130
  target_dir = tools_bin / "codeql"
130
- if target_dir.exists():
131
- shutil.rmtree(target_dir)
132
-
133
- if asset_name.lower().endswith(".zip"):
134
- with zipfile.ZipFile(io.BytesIO(asset_data)) as zf:
135
- zf.extractall(tools_bin)
136
- elif asset_name.lower().endswith(".tar.gz") or asset_name.lower().endswith(".tgz"):
137
- with tarfile.open(fileobj=io.BytesIO(asset_data), mode="r:gz") as tf:
138
- tf.extractall(tools_bin)
139
- else:
140
- raise RuntimeError(f"Unsupported codeql archive format: {asset_name}")
141
-
142
- if not target_dir.exists():
143
- raise RuntimeError("CodeQL extraction failed: missing .tools/bin/codeql directory")
131
+ with tempfile.TemporaryDirectory(prefix="codeql-stage-") as staging_dir:
132
+ staging_path = Path(staging_dir)
133
+
134
+ if asset_name.lower().endswith(".zip"):
135
+ with zipfile.ZipFile(io.BytesIO(asset_data)) as zf:
136
+ zf.extractall(staging_path)
137
+ elif asset_name.lower().endswith(".tar.gz") or asset_name.lower().endswith(".tgz"):
138
+ with tarfile.open(fileobj=io.BytesIO(asset_data), mode="r:gz") as tf:
139
+ tf.extractall(staging_path)
140
+ else:
141
+ raise RuntimeError(f"Unsupported codeql archive format: {asset_name}")
142
+
143
+ extracted_dir = staging_path / "codeql"
144
+ if not extracted_dir.exists():
145
+ raise RuntimeError("CodeQL extraction failed: missing codeql directory in archive")
146
+
147
+ if target_dir.exists():
148
+ shutil.copytree(extracted_dir, target_dir, dirs_exist_ok=True)
149
+ else:
150
+ shutil.move(str(extracted_dir), str(target_dir))
144
151
 
145
152
  codeql_bin = target_dir / ("codeql.exe" if os.name == "nt" else "codeql")
146
153
  if codeql_bin.exists():
@@ -171,14 +178,34 @@ def install_tool(tool_name: str, repo: str, patterns: list[str], tools_bin: Path
171
178
 
172
179
  def has_installed_tool(tool_name: str, tools_bin: Path, dest_name: str) -> bool:
173
180
  if tool_name == "codeql":
174
- candidate = tools_bin / "codeql" / ("codeql.exe" if os.name == "nt" else "codeql")
175
- return candidate.exists()
181
+ codeql_root = tools_bin / "codeql"
182
+ codeql_bin = codeql_root / ("codeql.exe" if os.name == "nt" else "codeql")
183
+ if not codeql_bin.exists():
184
+ return False
185
+ # A healthy CodeQL bundle includes an embedded Java runtime under tools/<platform>/java/bin.
186
+ java_glob = "java.exe" if os.name == "nt" else "java"
187
+ has_embedded_java = any(codeql_root.glob(f"tools/*/java/bin/{java_glob}"))
188
+ return has_embedded_java
176
189
  return (tools_bin / dest_name).exists()
177
190
 
178
191
 
179
192
  def main() -> int:
180
193
  parser = argparse.ArgumentParser(description="Install external scanner CLIs into .tools/bin")
181
194
  parser.add_argument("--repo-root", required=True, help="Repository root path")
195
+ parser.add_argument(
196
+ "--tool",
197
+ action="append",
198
+ default=[],
199
+ help=(
200
+ "Install only selected tool(s). Can be passed multiple times or as a comma-separated list "
201
+ "(e.g. --tool tfsec --tool gitleaks or --tool tfsec,gitleaks)"
202
+ ),
203
+ )
204
+ parser.add_argument(
205
+ "--force",
206
+ action="store_true",
207
+ help="Force re-download/reinstall even when a local install already exists",
208
+ )
182
209
  args = parser.parse_args()
183
210
 
184
211
  repo_root = Path(args.repo_root).resolve()
@@ -193,8 +220,8 @@ def main() -> int:
193
220
  "repo": "github/codeql-action",
194
221
  "patterns": {
195
222
  "windows": [r"codeql-bundle-win64\.tar\.gz$", r"codeql-bundle-win64\.zip$"],
196
- "linux": [r"codeql-bundle-linux64\\.tar\\.gz$"],
197
- "darwin": [r"codeql-bundle-osx64\\.tar\\.gz$", r"codeql-bundle-osx64\\.zip$"],
223
+ "linux": [r"codeql-bundle-linux64\.tar\.gz$"],
224
+ "darwin": [r"codeql-bundle-osx64\.tar\.gz$", r"codeql-bundle-osx64\.zip$"],
198
225
  },
199
226
  "binary_names": [f"codeql{ext}"],
200
227
  "dest_name": f"codeql{ext}",
@@ -202,7 +229,7 @@ def main() -> int:
202
229
  "tfsec": {
203
230
  "repo": "aquasecurity/tfsec",
204
231
  "patterns": {
205
- "windows": [r"tfsec-windows-amd64(?:\\.exe)?$"],
232
+ "windows": [r"tfsec-windows-amd64(?:\.exe)?$", r"tfsec_.*_windows_amd64\.tar\.gz$"],
206
233
  "linux": [r"tfsec-linux-amd64$"],
207
234
  "darwin": [r"tfsec-darwin-amd64$", r"tfsec-darwin-arm64$"],
208
235
  },
@@ -212,9 +239,9 @@ def main() -> int:
212
239
  "gitleaks": {
213
240
  "repo": "gitleaks/gitleaks",
214
241
  "patterns": {
215
- "windows": [r"gitleaks_.*_windows_x64\\.zip$"],
216
- "linux": [r"gitleaks_.*_linux_x64\\.tar\\.gz$"],
217
- "darwin": [r"gitleaks_.*_darwin_arm64\\.tar\\.gz$", r"gitleaks_.*_darwin_x64\\.tar\\.gz$"],
242
+ "windows": [r"gitleaks_.*_windows_x64\.zip$"],
243
+ "linux": [r"gitleaks_.*_linux_x64\.tar\.gz$"],
244
+ "darwin": [r"gitleaks_.*_darwin_arm64\.tar\.gz$", r"gitleaks_.*_darwin_x64\.tar\.gz$"],
218
245
  },
219
246
  "binary_names": [f"gitleaks{ext}"],
220
247
  "dest_name": f"gitleaks{ext}",
@@ -222,9 +249,9 @@ def main() -> int:
222
249
  "trufflehog": {
223
250
  "repo": "trufflesecurity/trufflehog",
224
251
  "patterns": {
225
- "windows": [r"trufflehog_.*_windows_amd64\\.tar\\.gz$", r"trufflehog_.*_windows_amd64\\.zip$"],
226
- "linux": [r"trufflehog_.*_linux_amd64\\.tar\\.gz$"],
227
- "darwin": [r"trufflehog_.*_darwin_arm64\\.tar\\.gz$", r"trufflehog_.*_darwin_amd64\\.tar\\.gz$"],
252
+ "windows": [r"trufflehog_.*_windows_amd64\.tar\.gz$", r"trufflehog_.*_windows_amd64\.zip$"],
253
+ "linux": [r"trufflehog_.*_linux_amd64\.tar\.gz$"],
254
+ "darwin": [r"trufflehog_.*_darwin_arm64\.tar\.gz$", r"trufflehog_.*_darwin_amd64\.tar\.gz$"],
228
255
  },
229
256
  "binary_names": [f"trufflehog{ext}"],
230
257
  "dest_name": f"trufflehog{ext}",
@@ -232,19 +259,48 @@ def main() -> int:
232
259
  "osv-scanner": {
233
260
  "repo": "google/osv-scanner",
234
261
  "patterns": {
235
- "windows": [r"osv-scanner_windows_amd64(?:\\.exe)?(?:\\.zip)?$", r"osv-scanner_.*_windows_amd64(?:\\.exe)?(?:\\.zip)?$", r"osv-scanner-windows-amd64(?:\\.exe)?$"],
236
- "linux": [r"osv-scanner_.*_linux_amd64(?:\\.tar\\.gz)?$", r"osv-scanner-linux-amd64$"],
237
- "darwin": [r"osv-scanner_.*_darwin_amd64(?:\\.tar\\.gz)?$", r"osv-scanner_.*_darwin_arm64(?:\\.tar\\.gz)?$"],
262
+ "windows": [r"osv-scanner_windows_amd64(?:\.exe)?(?:\.zip)?$", r"osv-scanner_.*_windows_amd64(?:\.exe)?(?:\.zip)?$", r"osv-scanner-windows-amd64(?:\.exe)?$"],
263
+ "linux": [r"osv-scanner_.*_linux_amd64(?:\.tar\.gz)?$", r"osv-scanner-linux-amd64$"],
264
+ "darwin": [r"osv-scanner_.*_darwin_amd64(?:\.tar\.gz)?$", r"osv-scanner_.*_darwin_arm64(?:\.tar\.gz)?$"],
238
265
  },
239
266
  "binary_names": [f"osv-scanner{ext}"],
240
267
  "dest_name": f"osv-scanner{ext}",
241
268
  },
242
269
  }
243
270
 
271
+ tool_aliases = {
272
+ "ocs-scanner": "osv-scanner",
273
+ }
274
+
275
+ selected_tools: set[str] = set()
276
+ if args.tool:
277
+ for raw_value in args.tool:
278
+ for item in raw_value.split(","):
279
+ normalized = item.strip().lower()
280
+ if not normalized:
281
+ continue
282
+ normalized = tool_aliases.get(normalized, normalized)
283
+ if normalized not in tool_matrix:
284
+ available = ", ".join(sorted(tool_matrix.keys()))
285
+ print(f"Unknown tool: {item}")
286
+ print(f"Available tools: {available}")
287
+ return 1
288
+ selected_tools.add(normalized)
289
+
290
+ tools_to_process = [
291
+ (tool_name, cfg)
292
+ for tool_name, cfg in tool_matrix.items()
293
+ if not selected_tools or tool_name in selected_tools
294
+ ]
295
+
244
296
  failures: list[str] = []
245
297
  rate_limited = False
246
298
 
247
- for tool_name, cfg in tool_matrix.items():
299
+ for tool_name, cfg in tools_to_process:
300
+ if not args.force and has_installed_tool(tool_name, tools_bin, cfg["dest_name"]):
301
+ print(f"Skipping {tool_name}: already installed (use --force to reinstall)")
302
+ continue
303
+
248
304
  patterns = cfg["patterns"][platform_name]
249
305
  try:
250
306
  install_tool(
@@ -0,0 +1,81 @@
1
+ @echo off
2
+ setlocal
3
+
4
+ set "REPO_ROOT=%~dp0.."
5
+ set "APP_PYTHON=python"
6
+ if exist "%REPO_ROOT%\.venv\Scripts\python.exe" set "APP_PYTHON=%REPO_ROOT%\.venv\Scripts\python.exe"
7
+
8
+ set "REPORT_DIR=%~1"
9
+ if "%REPORT_DIR%"=="" set "REPORT_DIR=security_reports"
10
+
11
+ set "DATABASE_PATH=%~2"
12
+ if "%DATABASE_PATH%"=="" set "DATABASE_PATH=codeql-db"
13
+
14
+ set "QUERY_SUITE=%~3"
15
+ if "%QUERY_SUITE%"=="" set "QUERY_SUITE=codeql/python-queries"
16
+
17
+ set "OUT_JSON=%REPORT_DIR%\codeql.sarif.json"
18
+ set "CODEQL_CMD=codeql"
19
+ set "LOCAL_CODEQL_EXE=%~dp0..\.tools\bin\codeql\codeql.exe"
20
+ set "LOCAL_CODEQL_JAVA=%~dp0..\.tools\bin\codeql\tools\win64\java\bin\java.exe"
21
+
22
+ if exist "%LOCAL_CODEQL_EXE%" set "CODEQL_CMD=%LOCAL_CODEQL_EXE%"
23
+ set "CODEQL_CMD=%CODEQL_CMD:\"=%"
24
+ set "CODEQL_CMD=%CODEQL_CMD:'=%"
25
+
26
+ if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
27
+
28
+ where "%CODEQL_CMD%" >nul 2>&1
29
+ if errorlevel 1 if /I "%CODEQL_CMD%"=="codeql" (
30
+ echo codeql not found. Attempting local install into .tools\bin...
31
+ "%APP_PYTHON%" "%~dp0install_external_clis.py" --repo-root "%REPO_ROOT%" --tool codeql --force
32
+ if errorlevel 1 (
33
+ echo Failed to install CodeQL CLI.
34
+ exit /b 1
35
+ )
36
+ if exist "%LOCAL_CODEQL_EXE%" set "CODEQL_CMD=%LOCAL_CODEQL_EXE%"
37
+ set "CODEQL_CMD=%CODEQL_CMD:\"=%"
38
+ set "CODEQL_CMD=%CODEQL_CMD:'=%"
39
+ where "%CODEQL_CMD%" >nul 2>&1
40
+ if errorlevel 1 if /I "%CODEQL_CMD%"=="codeql" (
41
+ echo codeql is not installed or not on PATH.
42
+ echo Install from: https://codeql.github.com/docs/codeql-overview/codeql-changelog/
43
+ exit /b 1
44
+ )
45
+ )
46
+
47
+ if exist "%LOCAL_CODEQL_EXE%" if not exist "%LOCAL_CODEQL_JAVA%" (
48
+ echo Local CodeQL install appears incomplete ^(missing embedded Java^). Reinstalling CodeQL...
49
+ "%APP_PYTHON%" "%~dp0install_external_clis.py" --repo-root "%REPO_ROOT%" --tool codeql --force
50
+ if errorlevel 1 (
51
+ echo Failed to reinstall CodeQL CLI.
52
+ exit /b 1
53
+ )
54
+ if not exist "%LOCAL_CODEQL_JAVA%" (
55
+ echo CodeQL reinstall completed, but embedded Java is still missing:
56
+ echo %LOCAL_CODEQL_JAVA%
57
+ exit /b 1
58
+ )
59
+ )
60
+
61
+ if not exist "%DATABASE_PATH%" (
62
+ echo CodeQL database not found at %DATABASE_PATH%. Creating database...
63
+ "%CODEQL_CMD%" database create "%DATABASE_PATH%" --language=python --source-root="%REPO_ROOT%"
64
+ if errorlevel 1 (
65
+ echo Failed to create CodeQL database at %DATABASE_PATH%
66
+ exit /b 1
67
+ )
68
+ )
69
+
70
+ "%CODEQL_CMD%" database finalize "%DATABASE_PATH%" >nul 2>&1
71
+
72
+ "%CODEQL_CMD%" database analyze "%DATABASE_PATH%" "%QUERY_SUITE%" --format=sarifv2.1.0 --output="%OUT_JSON%"
73
+ if errorlevel 1 exit /b 1
74
+
75
+ if not exist "%OUT_JSON%" (
76
+ echo CodeQL analyze completed but did not produce output file:
77
+ echo %OUT_JSON%
78
+ exit /b 1
79
+ )
80
+
81
+ echo CodeQL SARIF report written to %OUT_JSON%
@@ -19,6 +19,13 @@ if ! command -v "${CODEQL_CMD}" >/dev/null 2>&1; then
19
19
  exit 1
20
20
  fi
21
21
 
22
+ "${CODEQL_CMD}" database finalize "${DATABASE_PATH}" >/dev/null 2>&1 || true
23
+
22
24
  "${CODEQL_CMD}" database analyze "${DATABASE_PATH}" "${QUERY_SUITE}" --format=sarifv2.1.0 --output="${OUT_JSON}"
23
25
 
26
+ if [[ ! -f "${OUT_JSON}" ]]; then
27
+ echo "CodeQL analyze completed but did not produce output file: ${OUT_JSON}" >&2
28
+ exit 1
29
+ fi
30
+
24
31
  echo "CodeQL SARIF report written to ${OUT_JSON}"
@@ -0,0 +1,80 @@
1
+ @echo off
2
+ setlocal
3
+
4
+ set "REPO_ROOT=%~dp0.."
5
+ set "APP_PYTHON=python"
6
+ if exist "%REPO_ROOT%\.venv\Scripts\python.exe" set "APP_PYTHON=%REPO_ROOT%\.venv\Scripts\python.exe"
7
+
8
+ set "REPORT_DIR=%~1"
9
+ if "%REPORT_DIR%"=="" set "REPORT_DIR=security_reports"
10
+
11
+ set "TARGET_PATH=%~2"
12
+ if "%TARGET_PATH%"=="" set "TARGET_PATH=."
13
+
14
+ set "OUT_JSON=%REPORT_DIR%\osv-scanner.json"
15
+ set "OSV_CMD=osv-scanner"
16
+
17
+ if exist "%~dp0..\.tools\bin\osv-scanner.exe" set "OSV_CMD=%~dp0..\.tools\bin\osv-scanner.exe"
18
+
19
+ if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
20
+
21
+ where "%OSV_CMD%" >nul 2>&1
22
+ if errorlevel 1 if /I "%OSV_CMD%"=="osv-scanner" (
23
+ echo osv-scanner not found. Attempting local install into .tools\bin...
24
+ "%APP_PYTHON%" "%~dp0install_external_clis.py" --repo-root "%REPO_ROOT%"
25
+ if exist "%~dp0..\.tools\bin\osv-scanner.exe" set "OSV_CMD=%~dp0..\.tools\bin\osv-scanner.exe"
26
+ where "%OSV_CMD%" >nul 2>&1
27
+ if errorlevel 1 if /I "%OSV_CMD%"=="osv-scanner" (
28
+ echo osv-scanner is not installed or not on PATH.
29
+ echo Install from: https://github.com/google/osv-scanner
30
+ exit /b 1
31
+ )
32
+ )
33
+
34
+ set "TMP_JSON=%TEMP%\srk-osv-%RANDOM%-%RANDOM%.json"
35
+
36
+ rem Build scan args: prefer explicit lockfile sources over bare directory walk
37
+ set "OSV_ARGS=--format json --output-file "%TMP_JSON%""
38
+
39
+ set "FOUND_SOURCE=0"
40
+ if exist "%REPO_ROOT%\requirements.txt" set "OSV_ARGS=%OSV_ARGS% --lockfile "%REPO_ROOT%\requirements.txt"" & set "FOUND_SOURCE=1"
41
+ if exist "%REPO_ROOT%\requirements-dev.txt" set "OSV_ARGS=%OSV_ARGS% --lockfile "%REPO_ROOT%\requirements-dev.txt"" & set "FOUND_SOURCE=1"
42
+ if exist "%REPO_ROOT%\poetry.lock" set "OSV_ARGS=%OSV_ARGS% --lockfile "%REPO_ROOT%\poetry.lock"" & set "FOUND_SOURCE=1"
43
+ if exist "%REPO_ROOT%\Pipfile.lock" set "OSV_ARGS=%OSV_ARGS% --lockfile "%REPO_ROOT%\Pipfile.lock"" & set "FOUND_SOURCE=1"
44
+ if exist "%REPO_ROOT%\uv.lock" set "OSV_ARGS=%OSV_ARGS% --lockfile "%REPO_ROOT%\uv.lock"" & set "FOUND_SOURCE=1"
45
+ if exist "%REPO_ROOT%\pdm.lock" set "OSV_ARGS=%OSV_ARGS% --lockfile "%REPO_ROOT%\pdm.lock"" & set "FOUND_SOURCE=1"
46
+
47
+ if "%FOUND_SOURCE%"=="0" (
48
+ echo No supported lockfile found. Generating requirements.txt from installed packages...
49
+ "%APP_PYTHON%" -m pip freeze > "%REPO_ROOT%\requirements.txt"
50
+ if errorlevel 1 (
51
+ echo Failed to generate requirements.txt. Skipping OSV scan.
52
+ echo [] > "%OUT_JSON%"
53
+ exit /b 0
54
+ )
55
+ echo Generated %REPO_ROOT%\requirements.txt
56
+ set "OSV_ARGS=%OSV_ARGS% --lockfile "%REPO_ROOT%\requirements.txt""
57
+ set "FOUND_SOURCE=1"
58
+ )
59
+
60
+ "%OSV_CMD%" scan %OSV_ARGS%
61
+ set "OSV_EXIT=%ERRORLEVEL%"
62
+
63
+ if not exist "%TMP_JSON%" echo [] > "%TMP_JSON%"
64
+ move /Y "%TMP_JSON%" "%OUT_JSON%" >nul
65
+
66
+ rem Exit code 1 = vulnerabilities found; 127 = no package sources found — both are non-error outcomes
67
+ if "%OSV_EXIT%"=="1" (
68
+ echo OSV-Scanner JSON report written to %OUT_JSON% ^(vulnerabilities found^)
69
+ exit /b 0
70
+ )
71
+ if "%OSV_EXIT%"=="127" (
72
+ echo OSV-Scanner found no scannable package sources. No supported lockfile detected.
73
+ exit /b 0
74
+ )
75
+ if "%OSV_EXIT%" NEQ "0" (
76
+ echo OSV-Scanner failed with exit code %OSV_EXIT%
77
+ exit /b %OSV_EXIT%
78
+ )
79
+
80
+ echo OSV-Scanner JSON report written to %OUT_JSON%
@@ -1,6 +1,10 @@
1
1
  @echo off
2
2
  setlocal
3
3
 
4
+ set "REPO_ROOT=%~dp0.."
5
+ set "APP_PYTHON=python"
6
+ if exist "%REPO_ROOT%\.venv\Scripts\python.exe" set "APP_PYTHON=%REPO_ROOT%\.venv\Scripts\python.exe"
7
+
4
8
  set "REPORT_DIR=%~1"
5
9
  if "%REPORT_DIR%"=="" set "REPORT_DIR=security_reports"
6
10
 
@@ -16,9 +20,15 @@ if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
16
20
 
17
21
  where "%TFSEC_CMD%" >nul 2>&1
18
22
  if errorlevel 1 if /I "%TFSEC_CMD%"=="tfsec" (
19
- echo tfsec is not installed or not on PATH.
20
- echo Install from: https://github.com/aquasecurity/tfsec
21
- exit /b 1
23
+ echo tfsec not found. Attempting local install into .tools\bin...
24
+ "%APP_PYTHON%" "%~dp0install_external_clis.py" --repo-root "%REPO_ROOT%"
25
+ if exist "%~dp0..\.tools\bin\tfsec.exe" set "TFSEC_CMD=%~dp0..\.tools\bin\tfsec.exe"
26
+ where "%TFSEC_CMD%" >nul 2>&1
27
+ if errorlevel 1 if /I "%TFSEC_CMD%"=="tfsec" (
28
+ echo tfsec is not installed or not on PATH.
29
+ echo Install from: https://github.com/aquasecurity/tfsec
30
+ exit /b 1
31
+ )
22
32
  )
23
33
 
24
34
  "%TFSEC_CMD%" "%TARGET_PATH%" --format json --out "%OUT_JSON%"
@@ -0,0 +1,53 @@
1
+ @echo off
2
+ setlocal
3
+
4
+ set "REPO_ROOT=%~dp0.."
5
+ set "APP_PYTHON=python"
6
+ if exist "%REPO_ROOT%\.venv\Scripts\python.exe" set "APP_PYTHON=%REPO_ROOT%\.venv\Scripts\python.exe"
7
+
8
+ set "REPORT_DIR=%~1"
9
+ if "%REPORT_DIR%"=="" set "REPORT_DIR=security_reports"
10
+
11
+ set "TARGET_PATH=%~2"
12
+ if "%TARGET_PATH%"=="" set "TARGET_PATH=."
13
+
14
+ set "OUT_JSON=%REPORT_DIR%\trufflehog.json"
15
+ set "OUT_LOG=%REPORT_DIR%\trufflehog.log"
16
+ set "TMP_JSON=%TEMP%\srk-trufflehog-%RANDOM%-%RANDOM%.json"
17
+ set "TMP_LOG=%TEMP%\srk-trufflehog-%RANDOM%-%RANDOM%.log"
18
+ set "TRUFFLEHOG_CMD=trufflehog"
19
+
20
+ if exist "%~dp0..\.tools\bin\trufflehog.exe" set "TRUFFLEHOG_CMD=%~dp0..\.tools\bin\trufflehog.exe"
21
+
22
+ if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
23
+
24
+ where "%TRUFFLEHOG_CMD%" >nul 2>&1
25
+ if errorlevel 1 if /I "%TRUFFLEHOG_CMD%"=="trufflehog" (
26
+ echo trufflehog not found. Attempting local install into .tools\bin...
27
+ "%APP_PYTHON%" "%~dp0install_external_clis.py" --repo-root "%REPO_ROOT%"
28
+ if exist "%~dp0..\.tools\bin\trufflehog.exe" set "TRUFFLEHOG_CMD=%~dp0..\.tools\bin\trufflehog.exe"
29
+ where "%TRUFFLEHOG_CMD%" >nul 2>&1
30
+ if errorlevel 1 if /I "%TRUFFLEHOG_CMD%"=="trufflehog" (
31
+ echo trufflehog is not installed or not on PATH.
32
+ echo Install from: https://github.com/trufflesecurity/trufflehog
33
+ exit /b 1
34
+ )
35
+ )
36
+
37
+ "%TRUFFLEHOG_CMD%" filesystem "%TARGET_PATH%" --json > "%TMP_JSON%" 2> "%TMP_LOG%"
38
+ if errorlevel 1 (
39
+ if exist "%TMP_JSON%" move /Y "%TMP_JSON%" "%OUT_JSON%" >nul
40
+ if exist "%TMP_LOG%" move /Y "%TMP_LOG%" "%OUT_LOG%" >nul
41
+ echo TruffleHog scan failed. See log: %OUT_LOG%
42
+ if exist "%OUT_LOG%" type "%OUT_LOG%"
43
+ exit /b 1
44
+ )
45
+
46
+ if exist "%TMP_JSON%" move /Y "%TMP_JSON%" "%OUT_JSON%" >nul
47
+ if exist "%TMP_LOG%" move /Y "%TMP_LOG%" "%OUT_LOG%" >nul
48
+
49
+ if exist "%OUT_JSON%" (
50
+ for %%F in ("%OUT_JSON%") do if %%~zF==0 echo [] > "%OUT_JSON%"
51
+ )
52
+
53
+ echo TruffleHog JSON report written to %OUT_JSON%
@@ -1,28 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project are documented in this file.
4
-
5
- ## 0.2.3 - 2026-05-13
6
-
7
- ### Added
8
- - Safety CLI parser support and HTML rendering flow.
9
- - New CLI command: `srk render safety`.
10
- - MCP support for `source_type="safety"`.
11
- - Helper scripts for Safety scan and render:
12
- - `scripts/run_safety.sh`
13
- - `scripts/run_safety.bat`
14
- - `scripts/render_safety_html.sh`
15
- - `scripts/render_safety_html.bat`
16
- - Offline Safety DB download helpers:
17
- - `scripts/download_safety_db.py`
18
- - `scripts/download_safety_db.sh`
19
- - `scripts/download_safety_db.bat`
20
-
21
- ### Changed
22
- - Auto-detection now recognizes Safety JSON payloads.
23
- - Tool installation scripts now install Safety CLI in the app venv.
24
- - README updated with Safety usage and offline/local DB workflow guidance.
25
-
26
- ### Fixed
27
- - Safety run scripts now avoid false success when network failures occur.
28
- - JSON output validation improved for Safety execution paths.
@@ -1,30 +0,0 @@
1
- @echo off
2
- setlocal
3
-
4
- set "REPORT_DIR=%~1"
5
- if "%REPORT_DIR%"=="" set "REPORT_DIR=security_reports"
6
-
7
- set "DATABASE_PATH=%~2"
8
- if "%DATABASE_PATH%"=="" set "DATABASE_PATH=codeql-db"
9
-
10
- set "QUERY_SUITE=%~3"
11
- if "%QUERY_SUITE%"=="" set "QUERY_SUITE=codeql/python-queries"
12
-
13
- set "OUT_JSON=%REPORT_DIR%\codeql.sarif.json"
14
- set "CODEQL_CMD=codeql"
15
-
16
- if exist "%~dp0..\.tools\bin\codeql\codeql.exe" set "CODEQL_CMD=%~dp0..\.tools\bin\codeql\codeql.exe"
17
-
18
- if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
19
-
20
- where "%CODEQL_CMD%" >nul 2>&1
21
- if errorlevel 1 if /I "%CODEQL_CMD%"=="codeql" (
22
- echo codeql is not installed or not on PATH.
23
- echo Install from: https://codeql.github.com/docs/codeql-overview/codeql-changelog/
24
- exit /b 1
25
- )
26
-
27
- "%CODEQL_CMD%" database analyze "%DATABASE_PATH%" "%QUERY_SUITE%" --format=sarifv2.1.0 --output="%OUT_JSON%"
28
- if errorlevel 1 exit /b 1
29
-
30
- echo CodeQL SARIF report written to %OUT_JSON%
@@ -1,27 +0,0 @@
1
- @echo off
2
- setlocal
3
-
4
- set "REPORT_DIR=%~1"
5
- if "%REPORT_DIR%"=="" set "REPORT_DIR=security_reports"
6
-
7
- set "TARGET_PATH=%~2"
8
- if "%TARGET_PATH%"=="" set "TARGET_PATH=."
9
-
10
- set "OUT_JSON=%REPORT_DIR%\osv-scanner.json"
11
- set "OSV_CMD=osv-scanner"
12
-
13
- if exist "%~dp0..\.tools\bin\osv-scanner.exe" set "OSV_CMD=%~dp0..\.tools\bin\osv-scanner.exe"
14
-
15
- if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
16
-
17
- where "%OSV_CMD%" >nul 2>&1
18
- if errorlevel 1 if /I "%OSV_CMD%"=="osv-scanner" (
19
- echo osv-scanner is not installed or not on PATH.
20
- echo Install from: https://github.com/google/osv-scanner
21
- exit /b 1
22
- )
23
-
24
- "%OSV_CMD%" scan --recursive "%TARGET_PATH%" --format json --output "%OUT_JSON%"
25
- if errorlevel 1 exit /b 1
26
-
27
- echo OSV-Scanner JSON report written to %OUT_JSON%
@@ -1,27 +0,0 @@
1
- @echo off
2
- setlocal
3
-
4
- set "REPORT_DIR=%~1"
5
- if "%REPORT_DIR%"=="" set "REPORT_DIR=security_reports"
6
-
7
- set "TARGET_PATH=%~2"
8
- if "%TARGET_PATH%"=="" set "TARGET_PATH=."
9
-
10
- set "OUT_JSON=%REPORT_DIR%\trufflehog.json"
11
- set "TRUFFLEHOG_CMD=trufflehog"
12
-
13
- if exist "%~dp0..\.tools\bin\trufflehog.exe" set "TRUFFLEHOG_CMD=%~dp0..\.tools\bin\trufflehog.exe"
14
-
15
- if not exist "%REPORT_DIR%" mkdir "%REPORT_DIR%"
16
-
17
- where "%TRUFFLEHOG_CMD%" >nul 2>&1
18
- if errorlevel 1 if /I "%TRUFFLEHOG_CMD%"=="trufflehog" (
19
- echo trufflehog is not installed or not on PATH.
20
- echo Install from: https://github.com/trufflesecurity/trufflehog
21
- exit /b 1
22
- )
23
-
24
- "%TRUFFLEHOG_CMD%" filesystem "%TARGET_PATH%" --json > "%OUT_JSON%"
25
- if errorlevel 1 exit /b 1
26
-
27
- echo TruffleHog JSON report written to %OUT_JSON%