threatwright 0.1.0__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.
- threatwright-0.1.0/.dockerignore +19 -0
- threatwright-0.1.0/.gitattributes +6 -0
- threatwright-0.1.0/.github/workflows/audit.yml +52 -0
- threatwright-0.1.0/.github/workflows/ci.yml +58 -0
- threatwright-0.1.0/.github/workflows/leakcheck.yml +26 -0
- threatwright-0.1.0/.github/workflows/release.yml +187 -0
- threatwright-0.1.0/.gitignore +72 -0
- threatwright-0.1.0/.pre-commit-config.yaml +13 -0
- threatwright-0.1.0/.pre-commit-hooks.yaml +9 -0
- threatwright-0.1.0/Dockerfile +37 -0
- threatwright-0.1.0/LICENSE +661 -0
- threatwright-0.1.0/PKG-INFO +201 -0
- threatwright-0.1.0/README.md +183 -0
- threatwright-0.1.0/ROADMAP.md +23 -0
- threatwright-0.1.0/SECURITY.md +70 -0
- threatwright-0.1.0/app/index.html +12 -0
- threatwright-0.1.0/app/package-lock.json +1462 -0
- threatwright-0.1.0/app/package.json +24 -0
- threatwright-0.1.0/app/src/App.svelte +372 -0
- threatwright-0.1.0/app/src/api.ts +61 -0
- threatwright-0.1.0/app/src/app.css +151 -0
- threatwright-0.1.0/app/src/branding.ts +2 -0
- threatwright-0.1.0/app/src/fields.ts +150 -0
- threatwright-0.1.0/app/src/glossary.ts +220 -0
- threatwright-0.1.0/app/src/i18n.ts +448 -0
- threatwright-0.1.0/app/src/lib/Assessment.svelte +153 -0
- threatwright-0.1.0/app/src/lib/Assistant.svelte +163 -0
- threatwright-0.1.0/app/src/lib/Catalogs.svelte +78 -0
- threatwright-0.1.0/app/src/lib/Controls.svelte +92 -0
- threatwright-0.1.0/app/src/lib/Coverage.svelte +147 -0
- threatwright-0.1.0/app/src/lib/CustomField.svelte +36 -0
- threatwright-0.1.0/app/src/lib/CyberCauseDialog.svelte +88 -0
- threatwright-0.1.0/app/src/lib/Documents.svelte +153 -0
- threatwright-0.1.0/app/src/lib/Info.svelte +67 -0
- threatwright-0.1.0/app/src/lib/MeasureBoard.svelte +76 -0
- threatwright-0.1.0/app/src/lib/ModelMeta.svelte +125 -0
- threatwright-0.1.0/app/src/lib/MultiSelect.svelte +69 -0
- threatwright-0.1.0/app/src/lib/ObjectForm.svelte +266 -0
- threatwright-0.1.0/app/src/lib/Objects.svelte +148 -0
- threatwright-0.1.0/app/src/lib/Overview.svelte +159 -0
- threatwright-0.1.0/app/src/lib/RiskBadge.svelte +14 -0
- threatwright-0.1.0/app/src/lib/Settings.svelte +119 -0
- threatwright-0.1.0/app/src/lib/Setup.svelte +811 -0
- threatwright-0.1.0/app/src/lib/Start.svelte +155 -0
- threatwright-0.1.0/app/src/lib/Validation.svelte +108 -0
- threatwright-0.1.0/app/src/lib/diagram/Canvas.svelte +298 -0
- threatwright-0.1.0/app/src/lib/diagram/Diagram.svelte +165 -0
- threatwright-0.1.0/app/src/lib/diagram/ElementNode.svelte +108 -0
- threatwright-0.1.0/app/src/lib/diagram/Legend.svelte +82 -0
- threatwright-0.1.0/app/src/lib/diagram/ZoneNode.svelte +24 -0
- threatwright-0.1.0/app/src/lib/icons.ts +75 -0
- threatwright-0.1.0/app/src/main.ts +5 -0
- threatwright-0.1.0/app/src/rule-text.ts +74 -0
- threatwright-0.1.0/app/src/setup-text.ts +361 -0
- threatwright-0.1.0/app/src/state.svelte.ts +162 -0
- threatwright-0.1.0/app/src/types.ts +118 -0
- threatwright-0.1.0/app/svelte.config.js +3 -0
- threatwright-0.1.0/app/tsconfig.json +13 -0
- threatwright-0.1.0/app/vite.config.ts +14 -0
- threatwright-0.1.0/ci/github-actions.yml +92 -0
- threatwright-0.1.0/ci/gitlab-ci.yml +66 -0
- threatwright-0.1.0/docs/VERIFY.md +38 -0
- threatwright-0.1.0/docs/adr/0001-record-architecture-decisions.md +12 -0
- threatwright-0.1.0/docs/adr/0002-licensing.md +20 -0
- threatwright-0.1.0/docs/adr/0003-architecture-and-ui.md +21 -0
- threatwright-0.1.0/docs/adr/0004-storage-format.md +21 -0
- threatwright-0.1.0/docs/adr/0005-methodology-as-configuration.md +15 -0
- threatwright-0.1.0/docs/adr/0006-oscal-import-only.md +17 -0
- threatwright-0.1.0/docs/adr/0007-local-first-no-network.md +14 -0
- threatwright-0.1.0/docs/adr/0008-public-repo-hygiene.md +19 -0
- threatwright-0.1.0/docs/adr/0009-ci-integration-gitlab.md +18 -0
- threatwright-0.1.0/docs/adr/0010-tr-method-interpretation.md +20 -0
- threatwright-0.1.0/docs/adr/0011-library-format.md +18 -0
- threatwright-0.1.0/docs/adr/0012-oscal-version-and-arc.md +43 -0
- threatwright-0.1.0/docs/adr/0013-self-hosted-gui.md +18 -0
- threatwright-0.1.0/docs/bibliotheksformat.md +110 -0
- threatwright-0.1.0/docs/ci.md +86 -0
- threatwright-0.1.0/docs/cra-self-assessment.md +66 -0
- threatwright-0.1.0/docs/faq-cyberrisiko.md +33 -0
- threatwright-0.1.0/docs/git-arbeitsweise.md +174 -0
- threatwright-0.1.0/docs/methodik.md +64 -0
- threatwright-0.1.0/docs/oscal.md +141 -0
- threatwright-0.1.0/docs/pruefregeln.md +52 -0
- threatwright-0.1.0/docs/schnellstart.md +58 -0
- threatwright-0.1.0/docs/security.txt +13 -0
- threatwright-0.1.0/docs/tutorial.md +86 -0
- threatwright-0.1.0/docs/vorlagenreferenz.md +299 -0
- threatwright-0.1.0/packaging/build.py +55 -0
- threatwright-0.1.0/packaging/threatwright.spec +34 -0
- threatwright-0.1.0/pyproject.toml +59 -0
- threatwright-0.1.0/schemas/asset.v1.schema.json +166 -0
- threatwright-0.1.0/schemas/custom-fields.v1.schema.json +104 -0
- threatwright-0.1.0/schemas/diagram-layout.v1.schema.json +69 -0
- threatwright-0.1.0/schemas/element.v1.schema.json +124 -0
- threatwright-0.1.0/schemas/flow.v1.schema.json +139 -0
- threatwright-0.1.0/schemas/measure.v1.schema.json +207 -0
- threatwright-0.1.0/schemas/model.v1.schema.json +226 -0
- threatwright-0.1.0/schemas/project.v1.schema.json +66 -0
- threatwright-0.1.0/schemas/question.v1.schema.json +117 -0
- threatwright-0.1.0/schemas/threat.v1.schema.json +342 -0
- threatwright-0.1.0/scripts/check_forbidden_files.py +40 -0
- threatwright-0.1.0/scripts/library_coverage.py +44 -0
- threatwright-0.1.0/scripts/make_templates.py +229 -0
- threatwright-0.1.0/src/threatwright/__init__.py +3 -0
- threatwright-0.1.0/src/threatwright/__main__.py +3 -0
- threatwright-0.1.0/src/threatwright/arc.py +295 -0
- threatwright-0.1.0/src/threatwright/assistant.py +290 -0
- threatwright-0.1.0/src/threatwright/branding.py +4 -0
- threatwright-0.1.0/src/threatwright/catalogs/attack-ics.yaml +87 -0
- threatwright-0.1.0/src/threatwright/catalogs/cra.yaml +107 -0
- threatwright-0.1.0/src/threatwright/catalogs/emb3d.yaml +90 -0
- threatwright-0.1.0/src/threatwright/catalogs/iec62443.yaml +16 -0
- threatwright-0.1.0/src/threatwright/ci.py +158 -0
- threatwright-0.1.0/src/threatwright/ci_templates/github-actions.yml.j2 +95 -0
- threatwright-0.1.0/src/threatwright/ci_templates/gitlab-ci.yml.j2 +69 -0
- threatwright-0.1.0/src/threatwright/cli.py +370 -0
- threatwright-0.1.0/src/threatwright/diagram.py +110 -0
- threatwright-0.1.0/src/threatwright/interop/__init__.py +11 -0
- threatwright-0.1.0/src/threatwright/interop/export.py +196 -0
- threatwright-0.1.0/src/threatwright/interop/importers.py +411 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/elements.yaml +501 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/library.yaml +19 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/data.yaml +170 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/identity.yaml +468 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/integrity.yaml +694 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/logging.yaml +114 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/network.yaml +361 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/organisational.yaml +328 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/remote.yaml +281 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/safety.yaml +148 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/measures/supply-chain.yaml +167 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/threats/field.yaml +1461 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/threats/host.yaml +1568 -0
- threatwright-0.1.0/src/threatwright/libraries/ot/threats/network.yaml +1434 -0
- threatwright-0.1.0/src/threatwright/library.py +296 -0
- threatwright-0.1.0/src/threatwright/method.py +296 -0
- threatwright-0.1.0/src/threatwright/methods/tr-03183-1/method.yaml +223 -0
- threatwright-0.1.0/src/threatwright/model/__init__.py +0 -0
- threatwright-0.1.0/src/threatwright/model/objects.py +246 -0
- threatwright-0.1.0/src/threatwright/model/refactor.py +54 -0
- threatwright-0.1.0/src/threatwright/model/schema.py +31 -0
- threatwright-0.1.0/src/threatwright/model/store.py +326 -0
- threatwright-0.1.0/src/threatwright/oscal/__init__.py +19 -0
- threatwright-0.1.0/src/threatwright/oscal/imports.py +393 -0
- threatwright-0.1.0/src/threatwright/oscal/project.py +22 -0
- threatwright-0.1.0/src/threatwright/oscal/schemas/1.2.3/README.md +32 -0
- threatwright-0.1.0/src/threatwright/oscal/schemas/1.2.3/oscal_catalog_schema.json +1295 -0
- threatwright-0.1.0/src/threatwright/oscal/schemas/1.2.3/oscal_complete_schema.json +6022 -0
- threatwright-0.1.0/src/threatwright/oscal/schemas/1.2.3/oscal_component_schema.json +1821 -0
- threatwright-0.1.0/src/threatwright/oscal/schemas/1.2.3/oscal_profile_schema.json +1616 -0
- threatwright-0.1.0/src/threatwright/oscal/validate.py +150 -0
- threatwright-0.1.0/src/threatwright/render/__init__.py +30 -0
- threatwright-0.1.0/src/threatwright/render/build.py +316 -0
- threatwright-0.1.0/src/threatwright/render/context.py +579 -0
- threatwright-0.1.0/src/threatwright/render/env.py +89 -0
- threatwright-0.1.0/src/threatwright/render/labels.py +247 -0
- threatwright-0.1.0/src/threatwright/render/odt.py +296 -0
- threatwright-0.1.0/src/threatwright/render/package.py +217 -0
- threatwright-0.1.0/src/threatwright/render/pdf.py +66 -0
- threatwright-0.1.0/src/threatwright/render/sections.py +475 -0
- threatwright-0.1.0/src/threatwright/render/word.py +162 -0
- threatwright-0.1.0/src/threatwright/report.py +96 -0
- threatwright-0.1.0/src/threatwright/rules.py +382 -0
- threatwright-0.1.0/src/threatwright/scaffold.py +71 -0
- threatwright-0.1.0/src/threatwright/server.py +940 -0
- threatwright-0.1.0/src/threatwright/templates/_shared/document.html.j2 +69 -0
- threatwright-0.1.0/src/threatwright/templates/_shared/document.md.j2 +47 -0
- threatwright-0.1.0/src/threatwright/templates/acceptance-criteria/template.docx +0 -0
- threatwright-0.1.0/src/threatwright/templates/acceptance-criteria/template.md +2 -0
- threatwright-0.1.0/src/threatwright/templates/acceptance-criteria/template.odt +0 -0
- threatwright-0.1.0/src/threatwright/templates/acceptance-criteria/template.yaml +41 -0
- threatwright-0.1.0/src/threatwright/templates/tr-analysis/template.docx +0 -0
- threatwright-0.1.0/src/threatwright/templates/tr-analysis/template.html +2 -0
- threatwright-0.1.0/src/threatwright/templates/tr-analysis/template.md +2 -0
- threatwright-0.1.0/src/threatwright/templates/tr-analysis/template.odt +0 -0
- threatwright-0.1.0/src/threatwright/templates/tr-analysis/template.yaml +29 -0
- threatwright-0.1.0/src/threatwright/templates/tr-analysis-compact/template.docx +0 -0
- threatwright-0.1.0/src/threatwright/templates/tr-analysis-compact/template.yaml +47 -0
- threatwright-0.1.0/src/threatwright/vcs.py +349 -0
- threatwright-0.1.0/src/threatwright/web/assets/elk.bundled-B7GIUaPm.js +24 -0
- threatwright-0.1.0/src/threatwright/web/assets/index-CQEumOmL.css +1 -0
- threatwright-0.1.0/src/threatwright/web/assets/index-CQtGvHdl.js +13 -0
- threatwright-0.1.0/src/threatwright/web/index.html +13 -0
- threatwright-0.1.0/tests/conftest.py +135 -0
- threatwright-0.1.0/tests/e2e/test_a11y.py +51 -0
- threatwright-0.1.0/tests/e2e/test_diagram.py +67 -0
- threatwright-0.1.0/tests/e2e/test_diagram_zones.py +49 -0
- threatwright-0.1.0/tests/e2e/test_documents.py +22 -0
- threatwright-0.1.0/tests/e2e/test_gui.py +41 -0
- threatwright-0.1.0/tests/e2e/test_info.py +14 -0
- threatwright-0.1.0/tests/e2e/test_landing.py +27 -0
- threatwright-0.1.0/tests/e2e/test_language.py +16 -0
- threatwright-0.1.0/tests/e2e/test_setup.py +90 -0
- threatwright-0.1.0/tests/fixtures/broken/custom-fields.yaml +8 -0
- threatwright-0.1.0/tests/fixtures/broken/method-overrides.yaml +3 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/assets/A-0001.yaml +5 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/assets/A-0002.yaml +6 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/elements/E-0001.yaml +8 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/flows/F-0001.yaml +6 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/measures/M-0001.yaml +4 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/measures/M-0002.yaml +4 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/model.yaml +9 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/questions/Q-0001.yaml +4 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/threats/T-0001.yaml +8 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/threats/T-0002.yaml +11 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/threats/T-0003.yaml +9 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/threats/T-0004.yaml +9 -0
- threatwright-0.1.0/tests/fixtures/broken/models/m/threats/T-0005.yaml +4 -0
- threatwright-0.1.0/tests/fixtures/broken/threatwright.yaml +3 -0
- threatwright-0.1.0/tests/fixtures/interop/threat-dragon-v2.json +187 -0
- threatwright-0.1.0/tests/fixtures/oscal/NOTICE +29 -0
- threatwright-0.1.0/tests/fixtures/oscal/grundschutz-excerpt.json +423 -0
- threatwright-0.1.0/tests/fixtures/oscal/synthetic-arc-catalog.json +173 -0
- threatwright-0.1.0/tests/fixtures/oscal/synthetic-component.json +51 -0
- threatwright-0.1.0/tests/fixtures/oscal/synthetic-profile.json +38 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/assets/A-0001.yaml +5 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/assets/A-0002.yaml +5 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/diagram.layout.yaml +5 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/elements/E-0001.yaml +7 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/elements/E-0002.yaml +7 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/elements/E-0003.yaml +10 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/flows/F-0001.yaml +9 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/measures/M-0001.yaml +8 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/model.yaml +26 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/questions/Q-0001.yaml +5 -0
- threatwright-0.1.0/tests/fixtures/project/models/main/threats/T-0001.yaml +24 -0
- threatwright-0.1.0/tests/fixtures/project/threatwright.yaml +5 -0
- threatwright-0.1.0/tests/test_arc.py +127 -0
- threatwright-0.1.0/tests/test_assistant.py +128 -0
- threatwright-0.1.0/tests/test_ci.py +83 -0
- threatwright-0.1.0/tests/test_cli_tools.py +98 -0
- threatwright-0.1.0/tests/test_interop.py +190 -0
- threatwright-0.1.0/tests/test_library.py +85 -0
- threatwright-0.1.0/tests/test_method.py +164 -0
- threatwright-0.1.0/tests/test_oscal.py +309 -0
- threatwright-0.1.0/tests/test_oscal_wiring.py +70 -0
- threatwright-0.1.0/tests/test_refactor.py +49 -0
- threatwright-0.1.0/tests/test_render.py +375 -0
- threatwright-0.1.0/tests/test_rule_text.py +18 -0
- threatwright-0.1.0/tests/test_rules.py +83 -0
- threatwright-0.1.0/tests/test_server.py +174 -0
- threatwright-0.1.0/tests/test_store.py +141 -0
- threatwright-0.1.0/tests/test_vcs.py +149 -0
- threatwright-0.1.0/uv.lock +1391 -0
|
@@ -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,187 @@
|
|
|
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
|
+
# Linux pinned: the bundle needs at least the build system's glibc, so build on an
|
|
76
|
+
# older base to run on older plant PCs (ubuntu-latest moves to 26.04 from 2026-10-19)
|
|
77
|
+
os: [windows-latest, ubuntu-24.04]
|
|
78
|
+
runs-on: ${{ matrix.os }}
|
|
79
|
+
permissions:
|
|
80
|
+
contents: read
|
|
81
|
+
defaults:
|
|
82
|
+
run:
|
|
83
|
+
shell: bash
|
|
84
|
+
steps:
|
|
85
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
86
|
+
with:
|
|
87
|
+
persist-credentials: false
|
|
88
|
+
- uses: astral-sh/setup-uv@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.0
|
|
89
|
+
with:
|
|
90
|
+
python-version: "3.13"
|
|
91
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
92
|
+
with:
|
|
93
|
+
name: web
|
|
94
|
+
path: src/threatwright/web
|
|
95
|
+
- run: uv sync --locked
|
|
96
|
+
- run: uv run python packaging/build.py
|
|
97
|
+
- name: Smoke test
|
|
98
|
+
run: |
|
|
99
|
+
./dist/threatwright/threatwright --version
|
|
100
|
+
./dist/threatwright/threatwright validate tests/fixtures/project
|
|
101
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
102
|
+
with:
|
|
103
|
+
name: release-portable-${{ matrix.os }}
|
|
104
|
+
path: |
|
|
105
|
+
dist/threatwright-*.zip
|
|
106
|
+
dist/threatwright-*.tar.gz
|
|
107
|
+
|
|
108
|
+
release:
|
|
109
|
+
needs: [frontend, python, portable]
|
|
110
|
+
runs-on: ubuntu-latest
|
|
111
|
+
permissions:
|
|
112
|
+
contents: write # create the release
|
|
113
|
+
id-token: write # Sigstore signing via GitHub OIDC
|
|
114
|
+
attestations: write
|
|
115
|
+
steps:
|
|
116
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
117
|
+
with:
|
|
118
|
+
pattern: release-*
|
|
119
|
+
path: assets
|
|
120
|
+
merge-multiple: true
|
|
121
|
+
- name: Checksums
|
|
122
|
+
working-directory: assets
|
|
123
|
+
run: sha256sum -- * > SHA256SUMS
|
|
124
|
+
- uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
|
|
125
|
+
with:
|
|
126
|
+
subject-path: assets/*
|
|
127
|
+
- uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
|
128
|
+
- name: Sign checksums (keyless)
|
|
129
|
+
working-directory: assets
|
|
130
|
+
run: cosign sign-blob --yes --bundle SHA256SUMS.sigstore.json SHA256SUMS
|
|
131
|
+
- name: GitHub Release
|
|
132
|
+
env:
|
|
133
|
+
GH_TOKEN: ${{ github.token }}
|
|
134
|
+
run: >
|
|
135
|
+
gh release create "$GITHUB_REF_NAME" assets/*
|
|
136
|
+
--repo "$GITHUB_REPOSITORY" --verify-tag --generate-notes --title "$GITHUB_REF_NAME"
|
|
137
|
+
|
|
138
|
+
pypi:
|
|
139
|
+
needs: release
|
|
140
|
+
runs-on: ubuntu-latest
|
|
141
|
+
environment: pypi
|
|
142
|
+
permissions:
|
|
143
|
+
id-token: write # trusted publishing
|
|
144
|
+
steps:
|
|
145
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
146
|
+
with:
|
|
147
|
+
name: release-python
|
|
148
|
+
path: dist
|
|
149
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
|
|
150
|
+
|
|
151
|
+
image:
|
|
152
|
+
needs: python
|
|
153
|
+
runs-on: ubuntu-latest
|
|
154
|
+
permissions:
|
|
155
|
+
contents: read
|
|
156
|
+
packages: write
|
|
157
|
+
id-token: write
|
|
158
|
+
attestations: write
|
|
159
|
+
steps:
|
|
160
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
161
|
+
with:
|
|
162
|
+
persist-credentials: false
|
|
163
|
+
- name: Image name
|
|
164
|
+
id: meta
|
|
165
|
+
run: |
|
|
166
|
+
owner="$(echo "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]')"
|
|
167
|
+
echo "name=ghcr.io/$owner/threatwright" >> "$GITHUB_OUTPUT"
|
|
168
|
+
echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
|
169
|
+
- uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
|
|
170
|
+
- uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
|
|
171
|
+
with:
|
|
172
|
+
registry: ghcr.io
|
|
173
|
+
username: ${{ github.actor }}
|
|
174
|
+
password: ${{ github.token }}
|
|
175
|
+
- uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
|
|
176
|
+
id: build
|
|
177
|
+
with:
|
|
178
|
+
context: .
|
|
179
|
+
push: true
|
|
180
|
+
tags: ${{ steps.meta.outputs.name }}:${{ steps.meta.outputs.version }}
|
|
181
|
+
provenance: mode=max
|
|
182
|
+
sbom: true
|
|
183
|
+
- uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
|
|
184
|
+
with:
|
|
185
|
+
subject-name: ${{ steps.meta.outputs.name }}
|
|
186
|
+
subject-digest: ${{ steps.build.outputs.digest }}
|
|
187
|
+
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"]
|