@hoanghainh/komagu 2.2.1 → 2.3.0
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.
- package/CHANGELOG.md +11 -0
- package/assess/lsa/scripts/attack_chains.py +573 -0
- package/assess/lsa/scripts/baseline.py +14 -0
- package/assess/lsa/scripts/findings_to_sarif.py +11 -0
- package/assess/lsa/scripts/forecast.py +544 -0
- package/assess/lsa/scripts/merge_findings.py +14 -0
- package/assess/lsa/scripts/render_report.py +86 -0
- package/assess/lsa/tests/test_attack_chains.py +292 -0
- package/assess/lsa/tests/test_forecast.py +160 -0
- package/contracts/schemas/api-inventory-diff.schema.json +213 -0
- package/contracts/schemas/attack-chain.schema.json +181 -0
- package/contracts/schemas/bas-scenario.schema.json +217 -0
- package/contracts/schemas/evidence-manifest.schema.json +117 -0
- package/contracts/schemas/finding.schema.json +7 -0
- package/contracts/schemas/forecast.schema.json +172 -0
- package/governance/scs/__init__.py +21 -0
- package/governance/scs/mapping.py +133 -0
- package/governance/scs/pack.py +354 -0
- package/operate/cli/__init__.py +1 -1
- package/operate/cli/commands/evidence.py +138 -0
- package/operate/cli/commands/inventory.py +187 -0
- package/operate/cli/commands/simulate.py +175 -58
- package/operate/cli/main.py +7 -3
- package/operate/inventory/__init__.py +22 -0
- package/operate/inventory/api_inventory.py +566 -0
- package/operate/simulate/__init__.py +16 -0
- package/operate/simulate/engine.py +370 -0
- package/operate/simulate/loader.py +158 -0
- package/operate/simulate/scenarios/idc-frontier-ransomware.json +47 -0
- package/operate/simulate/scenarios/metabase-cve-2026-72898.json +84 -0
- package/operate/simulate/scenarios/times-car-breach.json +74 -0
- package/operate/simulate/scenarios.py +52 -0
- package/operate/tests/test_api_inventory.py +239 -0
- package/operate/tests/test_declarative_scenarios.py +169 -0
- package/operate/tests/test_evidence_pack.py +128 -0
- package/package.json +1 -1
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Comprehensive unit tests for METI SCS Evidence Pack and Gap Report (#271).
|
|
3
|
+
|
|
4
|
+
Validates:
|
|
5
|
+
1. evidence-manifest.schema.json schema conformity.
|
|
6
|
+
2. Control mapping evaluation and readiness rating logic (★3, ★4, GAP).
|
|
7
|
+
3. ZIP archive bundling, SHA-256 cryptographic digests, and manifest structure.
|
|
8
|
+
4. Bilingual gap report generation (gap-report.ja.md and gap-report.md).
|
|
9
|
+
5. CLI execution `komagu evidence`, argument parsing, and quality gating (--require-tier).
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
import os
|
|
16
|
+
import sys
|
|
17
|
+
import tempfile
|
|
18
|
+
import unittest
|
|
19
|
+
import zipfile
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
PROJECT_ROOT = Path(__file__).resolve().parents[2]
|
|
23
|
+
if str(PROJECT_ROOT) not in sys.path:
|
|
24
|
+
sys.path.insert(0, str(PROJECT_ROOT))
|
|
25
|
+
|
|
26
|
+
from assess.lsa.scripts.merge_findings import load_validator
|
|
27
|
+
from governance.scs.mapping import SCS_CONTROLS
|
|
28
|
+
from governance.scs.pack import EvidencePackBuilder
|
|
29
|
+
from operate.cli.main import main as cli_main
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TestEvidencePack(unittest.TestCase):
|
|
33
|
+
def setUp(self) -> None:
|
|
34
|
+
self.validate_schema = load_validator("evidence-manifest.schema.json")
|
|
35
|
+
|
|
36
|
+
def test_schema_conformity_on_evaluated_manifest(self) -> None:
|
|
37
|
+
"""Generated evidence manifest must strictly conform to evidence-manifest.schema.json."""
|
|
38
|
+
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
39
|
+
# Create synthetic audit artifacts
|
|
40
|
+
audit_dir = Path(tmp_dir) / "audit"
|
|
41
|
+
audit_dir.mkdir()
|
|
42
|
+
(audit_dir / "findings.sarif").write_text("{}", encoding="utf-8")
|
|
43
|
+
(audit_dir / "sbom-cyclonedx.json").write_text("{}", encoding="utf-8")
|
|
44
|
+
(audit_dir / "api-inventory-diff.json").write_text("{}", encoding="utf-8")
|
|
45
|
+
(audit_dir / "coraza.conf").write_text("SecRuleEngine On", encoding="utf-8")
|
|
46
|
+
(audit_dir / "bas-evidence.json").write_text("{}", encoding="utf-8")
|
|
47
|
+
|
|
48
|
+
builder = EvidencePackBuilder(
|
|
49
|
+
audit_dirs=[audit_dir],
|
|
50
|
+
project_name="Test Enterprise Portal",
|
|
51
|
+
target_system="Production-Kubernetes",
|
|
52
|
+
)
|
|
53
|
+
arts = builder.discover_artifacts()
|
|
54
|
+
ctrls, readiness = builder.evaluate_controls(arts)
|
|
55
|
+
manifest = builder.generate_manifest(ctrls, readiness, arts)
|
|
56
|
+
|
|
57
|
+
errs = self.validate_schema(manifest)
|
|
58
|
+
self.assertEqual(errs, [], f"Schema validation errors: {errs}")
|
|
59
|
+
self.assertEqual(manifest["project_name"], "Test Enterprise Portal")
|
|
60
|
+
self.assertEqual(manifest["overall_readiness"]["rating"], "SCS-★4-READY")
|
|
61
|
+
|
|
62
|
+
def test_pack_builder_generates_zip_and_reports(self) -> None:
|
|
63
|
+
"""build_pack must package evidence-pack.zip, manifest JSON, and bilingual reports."""
|
|
64
|
+
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
65
|
+
audit_dir = Path(tmp_dir) / "audit"
|
|
66
|
+
audit_dir.mkdir()
|
|
67
|
+
(audit_dir / "findings.sarif").write_text('{"runs": []}', encoding="utf-8")
|
|
68
|
+
(audit_dir / "sbom-cyclonedx.json").write_text('{"bomFormat": "CycloneDX"}', encoding="utf-8")
|
|
69
|
+
|
|
70
|
+
out_dir = Path(tmp_dir) / "output"
|
|
71
|
+
|
|
72
|
+
builder = EvidencePackBuilder(
|
|
73
|
+
audit_dirs=[audit_dir],
|
|
74
|
+
project_name="Tokyo Logistics Monolith",
|
|
75
|
+
)
|
|
76
|
+
zip_p, manifest_p, ja_p, en_p = builder.build_pack(out_dir)
|
|
77
|
+
|
|
78
|
+
self.assertTrue(zip_p.is_file())
|
|
79
|
+
self.assertTrue(manifest_p.is_file())
|
|
80
|
+
self.assertTrue(ja_p.is_file())
|
|
81
|
+
self.assertTrue(en_p.is_file())
|
|
82
|
+
|
|
83
|
+
# Verify Japanese report content
|
|
84
|
+
ja_content = ja_p.read_text(encoding="utf-8")
|
|
85
|
+
self.assertIn("サプライチェーン・サイバーセキュリティ", ja_content)
|
|
86
|
+
self.assertIn("NIST CSF 2.0", ja_content)
|
|
87
|
+
self.assertIn("Tokyo Logistics Monolith", ja_content)
|
|
88
|
+
|
|
89
|
+
# Verify English report content
|
|
90
|
+
en_content = en_p.read_text(encoding="utf-8")
|
|
91
|
+
self.assertIn("METI Supply Chain Security", en_content)
|
|
92
|
+
self.assertIn("Tokyo Logistics Monolith", en_content)
|
|
93
|
+
|
|
94
|
+
# Verify ZIP contents
|
|
95
|
+
with zipfile.ZipFile(zip_p, "r") as zf:
|
|
96
|
+
names = zf.namelist()
|
|
97
|
+
self.assertIn("evidence-manifest.json", names)
|
|
98
|
+
self.assertIn("gap-report.ja.md", names)
|
|
99
|
+
self.assertIn("gap-report.md", names)
|
|
100
|
+
self.assertIn("artifacts/findings.sarif", names)
|
|
101
|
+
self.assertIn("artifacts/sbom-cyclonedx.json", names)
|
|
102
|
+
|
|
103
|
+
def test_cli_evidence_command_execution_and_gating(self) -> None:
|
|
104
|
+
"""Test `komagu evidence` CLI invocation and tier requirements."""
|
|
105
|
+
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
106
|
+
audit_dir = Path(tmp_dir) / "audit"
|
|
107
|
+
audit_dir.mkdir()
|
|
108
|
+
(audit_dir / "findings.sarif").write_text("{}", encoding="utf-8")
|
|
109
|
+
|
|
110
|
+
out_dir = Path(tmp_dir) / "pack"
|
|
111
|
+
|
|
112
|
+
# Execute without gate -> should succeed
|
|
113
|
+
code = cli_main(["evidence", "--audit-dir", str(audit_dir), "--output-dir", str(out_dir)])
|
|
114
|
+
self.assertEqual(code, 0)
|
|
115
|
+
self.assertTrue((out_dir / "evidence-pack.zip").is_file())
|
|
116
|
+
|
|
117
|
+
# Require tier 4 with only 1 artifact -> should fail quality gate
|
|
118
|
+
code_gate = cli_main([
|
|
119
|
+
"evidence",
|
|
120
|
+
"--audit-dir", str(audit_dir),
|
|
121
|
+
"--output-dir", str(out_dir),
|
|
122
|
+
"--require-tier", "4",
|
|
123
|
+
])
|
|
124
|
+
self.assertEqual(code_gate, 1)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
if __name__ == "__main__":
|
|
128
|
+
unittest.main()
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hoanghainh/komagu",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "Security-First Legacy Modernization Platform CLI (LSA Kit, IAM Perimeter, Cross-User Testing)",
|
|
5
5
|
"main": "remediate/authz/nodejs/src/index.js",
|
|
6
6
|
"types": "remediate/authz/nodejs/src/index.d.ts",
|