threatwright 0.1.0rc1__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 (229) hide show
  1. threatwright-0.1.0rc1/.dockerignore +19 -0
  2. threatwright-0.1.0rc1/.gitattributes +6 -0
  3. threatwright-0.1.0rc1/.github/workflows/audit.yml +52 -0
  4. threatwright-0.1.0rc1/.github/workflows/ci.yml +58 -0
  5. threatwright-0.1.0rc1/.github/workflows/leakcheck.yml +26 -0
  6. threatwright-0.1.0rc1/.github/workflows/release.yml +185 -0
  7. threatwright-0.1.0rc1/.gitignore +72 -0
  8. threatwright-0.1.0rc1/.pre-commit-config.yaml +13 -0
  9. threatwright-0.1.0rc1/.pre-commit-hooks.yaml +9 -0
  10. threatwright-0.1.0rc1/Dockerfile +37 -0
  11. threatwright-0.1.0rc1/LICENSE +661 -0
  12. threatwright-0.1.0rc1/PKG-INFO +140 -0
  13. threatwright-0.1.0rc1/README.md +122 -0
  14. threatwright-0.1.0rc1/SECURITY.md +70 -0
  15. threatwright-0.1.0rc1/app/index.html +12 -0
  16. threatwright-0.1.0rc1/app/package-lock.json +1451 -0
  17. threatwright-0.1.0rc1/app/package.json +23 -0
  18. threatwright-0.1.0rc1/app/src/App.svelte +221 -0
  19. threatwright-0.1.0rc1/app/src/api.ts +61 -0
  20. threatwright-0.1.0rc1/app/src/app.css +151 -0
  21. threatwright-0.1.0rc1/app/src/branding.ts +2 -0
  22. threatwright-0.1.0rc1/app/src/fields.ts +147 -0
  23. threatwright-0.1.0rc1/app/src/i18n.ts +394 -0
  24. threatwright-0.1.0rc1/app/src/lib/Assessment.svelte +144 -0
  25. threatwright-0.1.0rc1/app/src/lib/Assistant.svelte +150 -0
  26. threatwright-0.1.0rc1/app/src/lib/Catalogs.svelte +78 -0
  27. threatwright-0.1.0rc1/app/src/lib/Controls.svelte +92 -0
  28. threatwright-0.1.0rc1/app/src/lib/Coverage.svelte +106 -0
  29. threatwright-0.1.0rc1/app/src/lib/CustomField.svelte +36 -0
  30. threatwright-0.1.0rc1/app/src/lib/CyberCauseDialog.svelte +88 -0
  31. threatwright-0.1.0rc1/app/src/lib/Documents.svelte +153 -0
  32. threatwright-0.1.0rc1/app/src/lib/MeasureBoard.svelte +76 -0
  33. threatwright-0.1.0rc1/app/src/lib/ModelMeta.svelte +124 -0
  34. threatwright-0.1.0rc1/app/src/lib/MultiSelect.svelte +69 -0
  35. threatwright-0.1.0rc1/app/src/lib/ObjectForm.svelte +252 -0
  36. threatwright-0.1.0rc1/app/src/lib/Objects.svelte +148 -0
  37. threatwright-0.1.0rc1/app/src/lib/Overview.svelte +138 -0
  38. threatwright-0.1.0rc1/app/src/lib/RiskBadge.svelte +14 -0
  39. threatwright-0.1.0rc1/app/src/lib/Settings.svelte +119 -0
  40. threatwright-0.1.0rc1/app/src/lib/Start.svelte +153 -0
  41. threatwright-0.1.0rc1/app/src/lib/Validation.svelte +62 -0
  42. threatwright-0.1.0rc1/app/src/lib/diagram/Canvas.svelte +201 -0
  43. threatwright-0.1.0rc1/app/src/lib/diagram/Diagram.svelte +166 -0
  44. threatwright-0.1.0rc1/app/src/lib/diagram/ElementNode.svelte +63 -0
  45. threatwright-0.1.0rc1/app/src/lib/diagram/ZoneNode.svelte +24 -0
  46. threatwright-0.1.0rc1/app/src/main.ts +5 -0
  47. threatwright-0.1.0rc1/app/src/state.svelte.ts +130 -0
  48. threatwright-0.1.0rc1/app/src/types.ts +113 -0
  49. threatwright-0.1.0rc1/app/svelte.config.js +3 -0
  50. threatwright-0.1.0rc1/app/tsconfig.json +13 -0
  51. threatwright-0.1.0rc1/app/vite.config.ts +14 -0
  52. threatwright-0.1.0rc1/ci/github-actions.yml +92 -0
  53. threatwright-0.1.0rc1/ci/gitlab-ci.yml +66 -0
  54. threatwright-0.1.0rc1/docs/VERIFY.md +38 -0
  55. threatwright-0.1.0rc1/docs/adr/0001-record-architecture-decisions.md +12 -0
  56. threatwright-0.1.0rc1/docs/adr/0002-licensing.md +20 -0
  57. threatwright-0.1.0rc1/docs/adr/0003-architecture-and-ui.md +21 -0
  58. threatwright-0.1.0rc1/docs/adr/0004-storage-format.md +21 -0
  59. threatwright-0.1.0rc1/docs/adr/0005-methodology-as-configuration.md +15 -0
  60. threatwright-0.1.0rc1/docs/adr/0006-oscal-import-only.md +17 -0
  61. threatwright-0.1.0rc1/docs/adr/0007-local-first-no-network.md +14 -0
  62. threatwright-0.1.0rc1/docs/adr/0008-public-repo-hygiene.md +19 -0
  63. threatwright-0.1.0rc1/docs/adr/0009-ci-integration-gitlab.md +18 -0
  64. threatwright-0.1.0rc1/docs/adr/0010-tr-method-interpretation.md +20 -0
  65. threatwright-0.1.0rc1/docs/adr/0011-library-format.md +18 -0
  66. threatwright-0.1.0rc1/docs/adr/0012-oscal-version-and-arc.md +43 -0
  67. threatwright-0.1.0rc1/docs/bibliotheksformat.md +110 -0
  68. threatwright-0.1.0rc1/docs/ci.md +86 -0
  69. threatwright-0.1.0rc1/docs/cra-self-assessment.md +66 -0
  70. threatwright-0.1.0rc1/docs/faq-cyberrisiko.md +33 -0
  71. threatwright-0.1.0rc1/docs/git-arbeitsweise.md +174 -0
  72. threatwright-0.1.0rc1/docs/methodik.md +64 -0
  73. threatwright-0.1.0rc1/docs/oscal.md +141 -0
  74. threatwright-0.1.0rc1/docs/pruefregeln.md +52 -0
  75. threatwright-0.1.0rc1/docs/schnellstart.md +54 -0
  76. threatwright-0.1.0rc1/docs/security.txt +13 -0
  77. threatwright-0.1.0rc1/docs/tutorial.md +86 -0
  78. threatwright-0.1.0rc1/docs/vorlagenreferenz.md +299 -0
  79. threatwright-0.1.0rc1/packaging/build.py +55 -0
  80. threatwright-0.1.0rc1/packaging/threatwright.spec +34 -0
  81. threatwright-0.1.0rc1/pyproject.toml +59 -0
  82. threatwright-0.1.0rc1/schemas/asset.v1.schema.json +166 -0
  83. threatwright-0.1.0rc1/schemas/custom-fields.v1.schema.json +104 -0
  84. threatwright-0.1.0rc1/schemas/diagram-layout.v1.schema.json +69 -0
  85. threatwright-0.1.0rc1/schemas/element.v1.schema.json +124 -0
  86. threatwright-0.1.0rc1/schemas/flow.v1.schema.json +139 -0
  87. threatwright-0.1.0rc1/schemas/measure.v1.schema.json +207 -0
  88. threatwright-0.1.0rc1/schemas/model.v1.schema.json +226 -0
  89. threatwright-0.1.0rc1/schemas/project.v1.schema.json +66 -0
  90. threatwright-0.1.0rc1/schemas/question.v1.schema.json +117 -0
  91. threatwright-0.1.0rc1/schemas/threat.v1.schema.json +342 -0
  92. threatwright-0.1.0rc1/scripts/check_forbidden_files.py +40 -0
  93. threatwright-0.1.0rc1/scripts/library_coverage.py +44 -0
  94. threatwright-0.1.0rc1/scripts/make_templates.py +229 -0
  95. threatwright-0.1.0rc1/src/threatwright/__init__.py +3 -0
  96. threatwright-0.1.0rc1/src/threatwright/__main__.py +3 -0
  97. threatwright-0.1.0rc1/src/threatwright/arc.py +295 -0
  98. threatwright-0.1.0rc1/src/threatwright/assistant.py +287 -0
  99. threatwright-0.1.0rc1/src/threatwright/branding.py +4 -0
  100. threatwright-0.1.0rc1/src/threatwright/catalogs/attack-ics.yaml +87 -0
  101. threatwright-0.1.0rc1/src/threatwright/catalogs/cra.yaml +107 -0
  102. threatwright-0.1.0rc1/src/threatwright/catalogs/emb3d.yaml +90 -0
  103. threatwright-0.1.0rc1/src/threatwright/catalogs/iec62443.yaml +16 -0
  104. threatwright-0.1.0rc1/src/threatwright/ci.py +158 -0
  105. threatwright-0.1.0rc1/src/threatwright/ci_templates/github-actions.yml.j2 +95 -0
  106. threatwright-0.1.0rc1/src/threatwright/ci_templates/gitlab-ci.yml.j2 +69 -0
  107. threatwright-0.1.0rc1/src/threatwright/cli.py +362 -0
  108. threatwright-0.1.0rc1/src/threatwright/diagram.py +110 -0
  109. threatwright-0.1.0rc1/src/threatwright/interop/__init__.py +11 -0
  110. threatwright-0.1.0rc1/src/threatwright/interop/export.py +196 -0
  111. threatwright-0.1.0rc1/src/threatwright/interop/importers.py +411 -0
  112. threatwright-0.1.0rc1/src/threatwright/libraries/ot/elements.yaml +468 -0
  113. threatwright-0.1.0rc1/src/threatwright/libraries/ot/library.yaml +19 -0
  114. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/data.yaml +170 -0
  115. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/identity.yaml +468 -0
  116. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/integrity.yaml +694 -0
  117. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/logging.yaml +114 -0
  118. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/network.yaml +361 -0
  119. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/organisational.yaml +328 -0
  120. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/remote.yaml +281 -0
  121. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/safety.yaml +148 -0
  122. threatwright-0.1.0rc1/src/threatwright/libraries/ot/measures/supply-chain.yaml +167 -0
  123. threatwright-0.1.0rc1/src/threatwright/libraries/ot/threats/field.yaml +1461 -0
  124. threatwright-0.1.0rc1/src/threatwright/libraries/ot/threats/host.yaml +1568 -0
  125. threatwright-0.1.0rc1/src/threatwright/libraries/ot/threats/network.yaml +1434 -0
  126. threatwright-0.1.0rc1/src/threatwright/library.py +296 -0
  127. threatwright-0.1.0rc1/src/threatwright/method.py +296 -0
  128. threatwright-0.1.0rc1/src/threatwright/methods/tr-03183-1/method.yaml +223 -0
  129. threatwright-0.1.0rc1/src/threatwright/model/__init__.py +0 -0
  130. threatwright-0.1.0rc1/src/threatwright/model/objects.py +246 -0
  131. threatwright-0.1.0rc1/src/threatwright/model/refactor.py +54 -0
  132. threatwright-0.1.0rc1/src/threatwright/model/schema.py +31 -0
  133. threatwright-0.1.0rc1/src/threatwright/model/store.py +326 -0
  134. threatwright-0.1.0rc1/src/threatwright/oscal/__init__.py +19 -0
  135. threatwright-0.1.0rc1/src/threatwright/oscal/imports.py +393 -0
  136. threatwright-0.1.0rc1/src/threatwright/oscal/project.py +22 -0
  137. threatwright-0.1.0rc1/src/threatwright/oscal/schemas/1.2.3/README.md +32 -0
  138. threatwright-0.1.0rc1/src/threatwright/oscal/schemas/1.2.3/oscal_catalog_schema.json +1295 -0
  139. threatwright-0.1.0rc1/src/threatwright/oscal/schemas/1.2.3/oscal_complete_schema.json +6022 -0
  140. threatwright-0.1.0rc1/src/threatwright/oscal/schemas/1.2.3/oscal_component_schema.json +1821 -0
  141. threatwright-0.1.0rc1/src/threatwright/oscal/schemas/1.2.3/oscal_profile_schema.json +1616 -0
  142. threatwright-0.1.0rc1/src/threatwright/oscal/validate.py +150 -0
  143. threatwright-0.1.0rc1/src/threatwright/render/__init__.py +30 -0
  144. threatwright-0.1.0rc1/src/threatwright/render/build.py +316 -0
  145. threatwright-0.1.0rc1/src/threatwright/render/context.py +579 -0
  146. threatwright-0.1.0rc1/src/threatwright/render/env.py +89 -0
  147. threatwright-0.1.0rc1/src/threatwright/render/labels.py +247 -0
  148. threatwright-0.1.0rc1/src/threatwright/render/odt.py +296 -0
  149. threatwright-0.1.0rc1/src/threatwright/render/package.py +217 -0
  150. threatwright-0.1.0rc1/src/threatwright/render/pdf.py +66 -0
  151. threatwright-0.1.0rc1/src/threatwright/render/sections.py +475 -0
  152. threatwright-0.1.0rc1/src/threatwright/render/word.py +162 -0
  153. threatwright-0.1.0rc1/src/threatwright/report.py +96 -0
  154. threatwright-0.1.0rc1/src/threatwright/rules.py +382 -0
  155. threatwright-0.1.0rc1/src/threatwright/scaffold.py +71 -0
  156. threatwright-0.1.0rc1/src/threatwright/server.py +889 -0
  157. threatwright-0.1.0rc1/src/threatwright/templates/_shared/document.html.j2 +69 -0
  158. threatwright-0.1.0rc1/src/threatwright/templates/_shared/document.md.j2 +47 -0
  159. threatwright-0.1.0rc1/src/threatwright/templates/acceptance-criteria/template.docx +0 -0
  160. threatwright-0.1.0rc1/src/threatwright/templates/acceptance-criteria/template.md +2 -0
  161. threatwright-0.1.0rc1/src/threatwright/templates/acceptance-criteria/template.odt +0 -0
  162. threatwright-0.1.0rc1/src/threatwright/templates/acceptance-criteria/template.yaml +41 -0
  163. threatwright-0.1.0rc1/src/threatwright/templates/tr-analysis/template.docx +0 -0
  164. threatwright-0.1.0rc1/src/threatwright/templates/tr-analysis/template.html +2 -0
  165. threatwright-0.1.0rc1/src/threatwright/templates/tr-analysis/template.md +2 -0
  166. threatwright-0.1.0rc1/src/threatwright/templates/tr-analysis/template.odt +0 -0
  167. threatwright-0.1.0rc1/src/threatwright/templates/tr-analysis/template.yaml +29 -0
  168. threatwright-0.1.0rc1/src/threatwright/templates/tr-analysis-compact/template.docx +0 -0
  169. threatwright-0.1.0rc1/src/threatwright/templates/tr-analysis-compact/template.yaml +47 -0
  170. threatwright-0.1.0rc1/src/threatwright/vcs.py +349 -0
  171. threatwright-0.1.0rc1/src/threatwright/web/assets/elk.bundled-BAO9aKhZ.js +24 -0
  172. threatwright-0.1.0rc1/src/threatwright/web/assets/index-CB8R456s.js +5 -0
  173. threatwright-0.1.0rc1/src/threatwright/web/assets/index-CY85z7q6.css +1 -0
  174. threatwright-0.1.0rc1/src/threatwright/web/index.html +13 -0
  175. threatwright-0.1.0rc1/tests/conftest.py +92 -0
  176. threatwright-0.1.0rc1/tests/e2e/test_a11y.py +43 -0
  177. threatwright-0.1.0rc1/tests/e2e/test_diagram.py +66 -0
  178. threatwright-0.1.0rc1/tests/e2e/test_documents.py +22 -0
  179. threatwright-0.1.0rc1/tests/e2e/test_gui.py +41 -0
  180. threatwright-0.1.0rc1/tests/fixtures/broken/custom-fields.yaml +8 -0
  181. threatwright-0.1.0rc1/tests/fixtures/broken/method-overrides.yaml +3 -0
  182. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/assets/A-0001.yaml +5 -0
  183. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/assets/A-0002.yaml +6 -0
  184. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/elements/E-0001.yaml +8 -0
  185. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/flows/F-0001.yaml +6 -0
  186. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/measures/M-0001.yaml +4 -0
  187. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/measures/M-0002.yaml +4 -0
  188. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/model.yaml +9 -0
  189. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/questions/Q-0001.yaml +4 -0
  190. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/threats/T-0001.yaml +8 -0
  191. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/threats/T-0002.yaml +11 -0
  192. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/threats/T-0003.yaml +9 -0
  193. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/threats/T-0004.yaml +9 -0
  194. threatwright-0.1.0rc1/tests/fixtures/broken/models/m/threats/T-0005.yaml +4 -0
  195. threatwright-0.1.0rc1/tests/fixtures/broken/threatwright.yaml +3 -0
  196. threatwright-0.1.0rc1/tests/fixtures/interop/threat-dragon-v2.json +187 -0
  197. threatwright-0.1.0rc1/tests/fixtures/oscal/NOTICE +29 -0
  198. threatwright-0.1.0rc1/tests/fixtures/oscal/grundschutz-excerpt.json +423 -0
  199. threatwright-0.1.0rc1/tests/fixtures/oscal/synthetic-arc-catalog.json +173 -0
  200. threatwright-0.1.0rc1/tests/fixtures/oscal/synthetic-component.json +51 -0
  201. threatwright-0.1.0rc1/tests/fixtures/oscal/synthetic-profile.json +38 -0
  202. threatwright-0.1.0rc1/tests/fixtures/project/models/main/assets/A-0001.yaml +5 -0
  203. threatwright-0.1.0rc1/tests/fixtures/project/models/main/assets/A-0002.yaml +5 -0
  204. threatwright-0.1.0rc1/tests/fixtures/project/models/main/diagram.layout.yaml +5 -0
  205. threatwright-0.1.0rc1/tests/fixtures/project/models/main/elements/E-0001.yaml +7 -0
  206. threatwright-0.1.0rc1/tests/fixtures/project/models/main/elements/E-0002.yaml +7 -0
  207. threatwright-0.1.0rc1/tests/fixtures/project/models/main/elements/E-0003.yaml +10 -0
  208. threatwright-0.1.0rc1/tests/fixtures/project/models/main/flows/F-0001.yaml +9 -0
  209. threatwright-0.1.0rc1/tests/fixtures/project/models/main/measures/M-0001.yaml +8 -0
  210. threatwright-0.1.0rc1/tests/fixtures/project/models/main/model.yaml +26 -0
  211. threatwright-0.1.0rc1/tests/fixtures/project/models/main/questions/Q-0001.yaml +5 -0
  212. threatwright-0.1.0rc1/tests/fixtures/project/models/main/threats/T-0001.yaml +24 -0
  213. threatwright-0.1.0rc1/tests/fixtures/project/threatwright.yaml +5 -0
  214. threatwright-0.1.0rc1/tests/test_arc.py +127 -0
  215. threatwright-0.1.0rc1/tests/test_assistant.py +117 -0
  216. threatwright-0.1.0rc1/tests/test_ci.py +83 -0
  217. threatwright-0.1.0rc1/tests/test_cli_tools.py +98 -0
  218. threatwright-0.1.0rc1/tests/test_interop.py +190 -0
  219. threatwright-0.1.0rc1/tests/test_library.py +85 -0
  220. threatwright-0.1.0rc1/tests/test_method.py +164 -0
  221. threatwright-0.1.0rc1/tests/test_oscal.py +309 -0
  222. threatwright-0.1.0rc1/tests/test_oscal_wiring.py +70 -0
  223. threatwright-0.1.0rc1/tests/test_refactor.py +49 -0
  224. threatwright-0.1.0rc1/tests/test_render.py +375 -0
  225. threatwright-0.1.0rc1/tests/test_rules.py +83 -0
  226. threatwright-0.1.0rc1/tests/test_server.py +136 -0
  227. threatwright-0.1.0rc1/tests/test_store.py +141 -0
  228. threatwright-0.1.0rc1/tests/test_vcs.py +149 -0
  229. threatwright-0.1.0rc1/uv.lock +1391 -0
@@ -0,0 +1,19 @@
1
+ .git
2
+ **/node_modules
3
+ .venv
4
+ build
5
+ dist
6
+ .claude
7
+ .private
8
+ .env
9
+ .env.*
10
+ *.pem
11
+ *.key
12
+ *.p12
13
+ *.pfx
14
+ secrets
15
+ **/__pycache__
16
+ .mypy_cache
17
+ .ruff_cache
18
+ .pytest_cache
19
+ src/threatwright/web
@@ -0,0 +1,6 @@
1
+ * text=auto eol=lf
2
+ *.docx binary
3
+ *.odt binary
4
+ *.xlsx binary
5
+ *.png binary
6
+ *.ico binary
@@ -0,0 +1,52 @@
1
+ name: audit
2
+
3
+ # Known vulnerabilities in locked dependencies (SECURITY.md, docs/cra-self-assessment.md).
4
+
5
+ on:
6
+ pull_request:
7
+ schedule:
8
+ - cron: "17 5 * * 1" # weekly, Monday
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ python:
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
19
+ with:
20
+ persist-credentials: false
21
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
22
+ - name: pip-audit (runtime dependencies from uv.lock)
23
+ run: |
24
+ uv export --frozen --no-dev --no-emit-project --format requirements-txt -o requirements.txt
25
+ uvx pip-audit==2.10.1 --disable-pip --require-hashes -r requirements.txt
26
+
27
+ npm:
28
+ runs-on: ubuntu-latest
29
+ steps:
30
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
31
+ with:
32
+ persist-credentials: false
33
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
34
+ with:
35
+ node-version: "24"
36
+ - name: npm audit (app/package-lock.json)
37
+ working-directory: app
38
+ run: npm audit --audit-level=moderate
39
+
40
+ osv:
41
+ # Second opinion over both lockfiles; informative only.
42
+ runs-on: ubuntu-latest
43
+ continue-on-error: true
44
+ steps:
45
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
46
+ with:
47
+ persist-credentials: false
48
+ - uses: google/osv-scanner-action/osv-scanner-action@b1d267aea5211fa648d9d442fa64b90dbdcbdd36 # v2.7.0
49
+ with:
50
+ scan-args: |-
51
+ --lockfile=uv.lock
52
+ --lockfile=app/package-lock.json
@@ -0,0 +1,58 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-latest, windows-latest]
17
+ python: ["3.12", "3.14"]
18
+ runs-on: ${{ matrix.os }}
19
+ steps:
20
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
21
+ with:
22
+ persist-credentials: false
23
+
24
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
25
+ with:
26
+ python-version: ${{ matrix.python }}
27
+
28
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
29
+ with:
30
+ node-version: "24"
31
+
32
+ - name: Frontend check and build
33
+ working-directory: app
34
+ run: |
35
+ npm ci --no-audit --no-fund
36
+ npm run check
37
+ npm run build
38
+
39
+ - run: uv sync --locked
40
+ - run: uv run ruff check .
41
+ - run: uv run ruff format --check .
42
+ - run: uv run mypy
43
+ - run: uv run playwright install --with-deps chromium
44
+ - run: uv run pytest -q
45
+ - run: uv run threatwright validate tests/fixtures/project
46
+
47
+ - name: Fixture project survives a load/save roundtrip without diff
48
+ run: |
49
+ uv run python -c "from threatwright.model.store import Project; p = Project.load('tests/fixtures/project'); assert not p.issues, p.issues; p.save()"
50
+ git diff --exit-code
51
+
52
+ # One stable check name for branch protection; matrix job names change with the matrix.
53
+ ci-ok:
54
+ if: always()
55
+ needs: [test]
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - run: test "${{ needs.test.result }}" = success
@@ -0,0 +1,26 @@
1
+ name: leakcheck
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ leakcheck:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
16
+ with:
17
+ fetch-depth: 0 # scan full history, not just HEAD
18
+ persist-credentials: false
19
+
20
+ - name: Forbidden files (AI tooling, local config, secrets)
21
+ run: python3 scripts/check_forbidden_files.py
22
+
23
+ - name: Secret scan (gitleaks, full history)
24
+ run: >
25
+ docker run --rm -v "$PWD:/repo" ghcr.io/gitleaks/gitleaks:v8.30.1
26
+ git /repo --redact --verbose --exit-code 1
@@ -0,0 +1,185 @@
1
+ name: release
2
+
3
+ # Tag vX.Y.Z (must match the version in pyproject.toml) -> GitHub Release with sdist, wheel,
4
+ # portable builds (Windows zip, Linux tar.gz), CycloneDX SBOMs, SHA256SUMS, Sigstore
5
+ # provenance; PyPI via trusted publishing; container image on ghcr.io.
6
+
7
+ on:
8
+ push:
9
+ tags: ["v*"]
10
+
11
+ permissions: {}
12
+
13
+ jobs:
14
+ frontend:
15
+ runs-on: ubuntu-latest
16
+ permissions:
17
+ contents: read
18
+ steps:
19
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
20
+ with:
21
+ persist-credentials: false
22
+ - uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
23
+ with:
24
+ node-version: "24"
25
+ - name: Build bundle and npm SBOM
26
+ working-directory: app
27
+ run: |
28
+ npm ci --no-audit --no-fund
29
+ npm run build
30
+ # The bundle is compiled from devDependencies, so the SBOM includes them.
31
+ npm sbom --sbom-format cyclonedx > ../sbom-npm.cdx.json
32
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
33
+ with:
34
+ name: web
35
+ path: src/threatwright/web/
36
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
37
+ with:
38
+ name: release-sbom-npm
39
+ path: sbom-npm.cdx.json
40
+
41
+ python:
42
+ needs: frontend
43
+ runs-on: ubuntu-latest
44
+ permissions:
45
+ contents: read
46
+ steps:
47
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
48
+ with:
49
+ persist-credentials: false
50
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
51
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
52
+ with:
53
+ name: web
54
+ path: src/threatwright/web
55
+ - name: Tag matches package version
56
+ run: test "$(uv version --short)" = "${GITHUB_REF_NAME#v}"
57
+ - run: uv build
58
+ - name: Python SBOM (runtime dependencies from uv.lock)
59
+ run: |
60
+ uv export --frozen --no-dev --no-emit-project --format requirements-txt -o requirements.txt
61
+ uvx --from cyclonedx-bom==7.5.0 cyclonedx-py requirements requirements.txt -o sbom-python.cdx.json
62
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
63
+ with:
64
+ name: release-python
65
+ path: dist/
66
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
67
+ with:
68
+ name: release-sbom-python
69
+ path: sbom-python.cdx.json
70
+
71
+ portable:
72
+ needs: frontend
73
+ strategy:
74
+ matrix:
75
+ os: [windows-latest, ubuntu-latest]
76
+ runs-on: ${{ matrix.os }}
77
+ permissions:
78
+ contents: read
79
+ defaults:
80
+ run:
81
+ shell: bash
82
+ steps:
83
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
84
+ with:
85
+ persist-credentials: false
86
+ - uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
87
+ with:
88
+ python-version: "3.13"
89
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
90
+ with:
91
+ name: web
92
+ path: src/threatwright/web
93
+ - run: uv sync --locked
94
+ - run: uv run python packaging/build.py
95
+ - name: Smoke test
96
+ run: |
97
+ ./dist/threatwright/threatwright --version
98
+ ./dist/threatwright/threatwright validate tests/fixtures/project
99
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
100
+ with:
101
+ name: release-portable-${{ matrix.os }}
102
+ path: |
103
+ dist/threatwright-*.zip
104
+ dist/threatwright-*.tar.gz
105
+
106
+ release:
107
+ needs: [frontend, python, portable]
108
+ runs-on: ubuntu-latest
109
+ permissions:
110
+ contents: write # create the release
111
+ id-token: write # Sigstore signing via GitHub OIDC
112
+ attestations: write
113
+ steps:
114
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
115
+ with:
116
+ pattern: release-*
117
+ path: assets
118
+ merge-multiple: true
119
+ - name: Checksums
120
+ working-directory: assets
121
+ run: sha256sum -- * > SHA256SUMS
122
+ - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
123
+ with:
124
+ subject-path: assets/*
125
+ - uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
126
+ - name: Sign checksums (keyless)
127
+ working-directory: assets
128
+ run: cosign sign-blob --yes --bundle SHA256SUMS.sigstore.json SHA256SUMS
129
+ - name: GitHub Release
130
+ env:
131
+ GH_TOKEN: ${{ github.token }}
132
+ run: >
133
+ gh release create "$GITHUB_REF_NAME" assets/*
134
+ --repo "$GITHUB_REPOSITORY" --verify-tag --generate-notes --title "$GITHUB_REF_NAME"
135
+
136
+ pypi:
137
+ needs: release
138
+ runs-on: ubuntu-latest
139
+ environment: pypi
140
+ permissions:
141
+ id-token: write # trusted publishing
142
+ steps:
143
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
144
+ with:
145
+ name: release-python
146
+ path: dist
147
+ - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
148
+
149
+ image:
150
+ needs: python
151
+ runs-on: ubuntu-latest
152
+ permissions:
153
+ contents: read
154
+ packages: write
155
+ id-token: write
156
+ attestations: write
157
+ steps:
158
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
159
+ with:
160
+ persist-credentials: false
161
+ - name: Image name
162
+ id: meta
163
+ run: |
164
+ owner="$(echo "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')"
165
+ echo "name=ghcr.io/$owner/threatwright" >> "$GITHUB_OUTPUT"
166
+ echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
167
+ - uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
168
+ - uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
169
+ with:
170
+ registry: ghcr.io
171
+ username: ${{ github.actor }}
172
+ password: ${{ github.token }}
173
+ - uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
174
+ id: build
175
+ with:
176
+ context: .
177
+ push: true
178
+ tags: ${{ steps.meta.outputs.name }}:${{ steps.meta.outputs.version }}
179
+ provenance: mode=max
180
+ sbom: true
181
+ - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
182
+ with:
183
+ subject-name: ${{ steps.meta.outputs.name }}
184
+ subject-digest: ${{ steps.build.outputs.digest }}
185
+ push-to-registry: true
@@ -0,0 +1,72 @@
1
+ # --- AI assistant / local tooling: never publish -------------------------
2
+ .claude/
3
+ CLAUDE.md
4
+ CLAUDE.local.md
5
+ **/CLAUDE.md
6
+ **/CLAUDE.local.md
7
+ .mcp.json
8
+ graphify-out/
9
+ .cursor/
10
+ .aider*
11
+ .continue/
12
+ .copilot/
13
+ AGENTS.md
14
+
15
+ # --- Private notes (customer references, drafts): never publish -------------
16
+ .private/
17
+
18
+ # --- Secrets and local config ---------------------------------------------
19
+ .env
20
+ .env.*
21
+ !.env.example
22
+ *.pem
23
+ *.key
24
+ *.p12
25
+ *.pfx
26
+ *.kdbx
27
+ secrets/
28
+ *.local.yaml
29
+ *.local.yml
30
+
31
+ # --- Python -----------------------------------------------------------------
32
+ __pycache__/
33
+ *.py[cod]
34
+ *.egg-info/
35
+ .venv/
36
+ venv/
37
+ .python-version
38
+ .mypy_cache/
39
+ .ruff_cache/
40
+ .pytest_cache/
41
+ .coverage
42
+ .coverage.*
43
+ htmlcov/
44
+ .tox/
45
+ .nox/
46
+
47
+ # --- Node / frontend ----------------------------------------------------------
48
+ node_modules/
49
+ .svelte-kit/
50
+ app/dist/
51
+ src/threatwright/web/
52
+
53
+ # --- Build artefacts ---------------------------------------------------------
54
+ build/
55
+ dist/
56
+ *.spec.bak
57
+ sbom*.json
58
+ playwright-report/
59
+ test-results/
60
+
61
+ # --- Editors / OS ------------------------------------------------------------
62
+ .idea/
63
+ .vscode/
64
+ *.swp
65
+ *~
66
+ .DS_Store
67
+ Thumbs.db
68
+ desktop.ini
69
+
70
+ # --- Office lock files -------------------------------------------------------
71
+ ~$*
72
+ .~lock.*#
@@ -0,0 +1,13 @@
1
+ repos:
2
+ - repo: https://github.com/gitleaks/gitleaks
3
+ rev: v8.30.1
4
+ hooks:
5
+ - id: gitleaks
6
+ - repo: local
7
+ hooks:
8
+ - id: forbidden-files
9
+ name: forbidden files
10
+ entry: python scripts/check_forbidden_files.py
11
+ language: system
12
+ pass_filenames: false
13
+ always_run: true
@@ -0,0 +1,9 @@
1
+ # Hooks offered to other repositories (docs/ci.md). Pass the project folder via `args`,
2
+ # e.g. `args: [--strict, threatmodel]`; default is the repository root.
3
+ - id: threatwright-validate
4
+ name: threatwright validate
5
+ description: Check a Threatwright project (schema, references, rules).
6
+ entry: threatwright validate
7
+ language: python
8
+ files: \.ya?ml$
9
+ pass_filenames: false
@@ -0,0 +1,37 @@
1
+ # CI runtime image (ADR-0009): threatwright CLI + LibreOffice Writer for PDF, no GUI.
2
+ # Base images pinned by digest (multi-arch index), looked up 2026-10-19; bump deliberately.
3
+
4
+ # --- 1: frontend bundle ------------------------------------------------------------
5
+ FROM node:24-slim@sha256:a5f4366e834695d5f363b920c104953a535d3a9864d1bdf74566a0ebe01daee5 AS frontend
6
+ WORKDIR /src/app
7
+ COPY app/package.json app/package-lock.json ./
8
+ RUN npm ci --no-audit --no-fund
9
+ COPY app/ ./
10
+ # vite writes to ../src/threatwright/web
11
+ RUN mkdir -p /src/src/threatwright && npm run build
12
+
13
+ # --- 2: wheel + locked requirements ----------------------------------------------
14
+ FROM python:3.13-slim@sha256:70729b46c69b4f1e97c4822c1af3df53a1476cf5ddc6c087c0c10bc3a5678c2f AS wheel
15
+ COPY --from=ghcr.io/astral-sh/uv:0.13.1@sha256:4a1f3666816dafadd20ceb71eac9a7d56d7ef30279f7d64048519ab901ada336 /uv /usr/local/bin/uv
16
+ WORKDIR /src
17
+ COPY pyproject.toml uv.lock README.md LICENSE ./
18
+ COPY src/ src/
19
+ COPY --from=frontend /src/src/threatwright/web src/threatwright/web
20
+ RUN uv build --wheel --out-dir /dist \
21
+ && uv export --frozen --no-dev --no-emit-project --format requirements-txt -o /dist/requirements.txt
22
+
23
+ # --- 3: runtime --------------------------------------------------------------------
24
+ FROM python:3.13-slim@sha256:70729b46c69b4f1e97c4822c1af3df53a1476cf5ddc6c087c0c10bc3a5678c2f
25
+ # git: diff against tags in CI. LibreOffice Writer (headless) for PDF output.
26
+ RUN apt-get update \
27
+ && apt-get install -y --no-install-recommends git libreoffice-writer-nogui fonts-dejavu-core \
28
+ && rm -rf /var/lib/apt/lists/*
29
+ COPY --from=wheel /dist /tmp/dist
30
+ RUN pip install --no-cache-dir --require-hashes -r /tmp/dist/requirements.txt \
31
+ && pip install --no-cache-dir --no-deps /tmp/dist/*.whl \
32
+ && rm -rf /tmp/dist
33
+ RUN useradd --create-home --uid 10001 threatwright
34
+ USER threatwright
35
+ WORKDIR /work
36
+ ENTRYPOINT ["threatwright"]
37
+ CMD ["--help"]