oath-mcp 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.
- oath_mcp-0.1.0/.gitignore +89 -0
- oath_mcp-0.1.0/CITATION.cff +22 -0
- oath_mcp-0.1.0/LICENSE +21 -0
- oath_mcp-0.1.0/PKG-INFO +276 -0
- oath_mcp-0.1.0/README.md +203 -0
- oath_mcp-0.1.0/corpus/.gitkeep +0 -0
- oath_mcp-0.1.0/docker/eztools/Dockerfile +42 -0
- oath_mcp-0.1.0/docker/eztools/dotnet-tools.json +46 -0
- oath_mcp-0.1.0/docker-compose.yml +86 -0
- oath_mcp-0.1.0/docs/ACCURACY.md +163 -0
- oath_mcp-0.1.0/docs/ARCHITECTURE.md +173 -0
- oath_mcp-0.1.0/docs/ARTIFACT.md +48 -0
- oath_mcp-0.1.0/docs/DATASETS.md +168 -0
- oath_mcp-0.1.0/docs/DEVPOST.md +144 -0
- oath_mcp-0.1.0/docs/PUBLICATION.md +44 -0
- oath_mcp-0.1.0/docs/RECORDING.md +527 -0
- oath_mcp-0.1.0/docs/TRY_IT_OUT.md +149 -0
- oath_mcp-0.1.0/docs/demo.svg +460 -0
- oath_mcp-0.1.0/logs/.gitkeep +0 -0
- oath_mcp-0.1.0/pyproject.toml +119 -0
- oath_mcp-0.1.0/scripts/bootstrap-forensic-tools.sh +206 -0
- oath_mcp-0.1.0/scripts/demo.py +238 -0
- oath_mcp-0.1.0/scripts/dry-run.sh +229 -0
- oath_mcp-0.1.0/scripts/export_sample_run.py +342 -0
- oath_mcp-0.1.0/scripts/install-on-sift.sh +337 -0
- oath_mcp-0.1.0/scripts/install-tools.sh +221 -0
- oath_mcp-0.1.0/scripts/nss_baseline.py +509 -0
- oath_mcp-0.1.0/scripts/oath-mcp.sh +49 -0
- oath_mcp-0.1.0/scripts/prepare-demo.sh +112 -0
- oath_mcp-0.1.0/scripts/render_accuracy.py +186 -0
- oath_mcp-0.1.0/scripts/show_self_correction.py +342 -0
- oath_mcp-0.1.0/src/oath/__init__.py +7 -0
- oath_mcp-0.1.0/src/oath/__main__.py +7 -0
- oath_mcp-0.1.0/src/oath/agent/__init__.py +0 -0
- oath_mcp-0.1.0/src/oath/agent/demo.py +436 -0
- oath_mcp-0.1.0/src/oath/agent/runner.py +284 -0
- oath_mcp-0.1.0/src/oath/benchmark/__init__.py +62 -0
- oath_mcp-0.1.0/src/oath/benchmark/claude_agent.py +391 -0
- oath_mcp-0.1.0/src/oath/benchmark/claude_nss_agent.py +293 -0
- oath_mcp-0.1.0/src/oath/benchmark/corpus.py +237 -0
- oath_mcp-0.1.0/src/oath/benchmark/gemini_nss_agent.py +256 -0
- oath_mcp-0.1.0/src/oath/benchmark/harness.py +214 -0
- oath_mcp-0.1.0/src/oath/benchmark/question.py +297 -0
- oath_mcp-0.1.0/src/oath/benchmark/scorer.py +193 -0
- oath_mcp-0.1.0/src/oath/cli.py +617 -0
- oath_mcp-0.1.0/src/oath/mcp/__init__.py +0 -0
- oath_mcp-0.1.0/src/oath/mcp/evidence_handle.py +182 -0
- oath_mcp-0.1.0/src/oath/mcp/persistence.py +181 -0
- oath_mcp-0.1.0/src/oath/mcp/server.py +760 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/__init__.py +0 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/enumerate_credential_artifacts.py +469 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/find_strings_on_image.py +567 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/parse_amcache.py +308 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/parse_evtx.py +474 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/parse_mft.py +383 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/parse_prefetch.py +266 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/parse_registry.py +435 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/parse_usnjrnl.py +374 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/plaso_supertimeline.py +514 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/run_hayabusa.py +441 -0
- oath_mcp-0.1.0/src/oath/mcp/tools/vol3_query.py +354 -0
- oath_mcp-0.1.0/src/oath/narrator/__init__.py +34 -0
- oath_mcp-0.1.0/src/oath/narrator/terminal.py +386 -0
- oath_mcp-0.1.0/src/oath/receipt/__init__.py +0 -0
- oath_mcp-0.1.0/src/oath/receipt/notarized.py +383 -0
- oath_mcp-0.1.0/src/oath/witness/__init__.py +0 -0
- oath_mcp-0.1.0/src/oath/witness/claim.py +185 -0
- oath_mcp-0.1.0/src/oath/witness/ralph_wiggum.py +276 -0
- oath_mcp-0.1.0/src/oath/witness/verifier.py +366 -0
- oath_mcp-0.1.0/symbols/.gitkeep +0 -0
- oath_mcp-0.1.0/tests/integration/test_mcp_server.py +308 -0
- oath_mcp-0.1.0/tests/integration/test_spoliation.py +677 -0
- oath_mcp-0.1.0/tests/unit/test_agent_runner.py +279 -0
- oath_mcp-0.1.0/tests/unit/test_benchmark.py +436 -0
- oath_mcp-0.1.0/tests/unit/test_benchmark_nss.py +336 -0
- oath_mcp-0.1.0/tests/unit/test_claude_agent.py +210 -0
- oath_mcp-0.1.0/tests/unit/test_claude_nss_agent.py +188 -0
- oath_mcp-0.1.0/tests/unit/test_enumerate_credential_artifacts.py +280 -0
- oath_mcp-0.1.0/tests/unit/test_find_strings_on_image.py +287 -0
- oath_mcp-0.1.0/tests/unit/test_gemini_nss_agent.py +131 -0
- oath_mcp-0.1.0/tests/unit/test_narrator.py +221 -0
- oath_mcp-0.1.0/tests/unit/test_notarized.py +198 -0
- oath_mcp-0.1.0/tests/unit/test_parse_amcache.py +134 -0
- oath_mcp-0.1.0/tests/unit/test_parse_evtx.py +299 -0
- oath_mcp-0.1.0/tests/unit/test_parse_mft.py +225 -0
- oath_mcp-0.1.0/tests/unit/test_parse_prefetch.py +131 -0
- oath_mcp-0.1.0/tests/unit/test_parse_registry.py +285 -0
- oath_mcp-0.1.0/tests/unit/test_parse_usnjrnl.py +202 -0
- oath_mcp-0.1.0/tests/unit/test_plaso_supertimeline.py +290 -0
- oath_mcp-0.1.0/tests/unit/test_ralph_wiggum.py +261 -0
- oath_mcp-0.1.0/tests/unit/test_run_hayabusa.py +272 -0
- oath_mcp-0.1.0/tests/unit/test_vol3_query.py +257 -0
- oath_mcp-0.1.0/tests/unit/test_witness_verifier.py +347 -0
- oath_mcp-0.1.0/uninstall.sh +115 -0
- oath_mcp-0.1.0/verify.sh +40 -0
- oath_mcp-0.1.0/web/README.md +42 -0
- oath_mcp-0.1.0/web/app.js +199 -0
- oath_mcp-0.1.0/web/build-data.sh +71 -0
- oath_mcp-0.1.0/web/data.js +497 -0
- oath_mcp-0.1.0/web/index.html +188 -0
- oath_mcp-0.1.0/web/styles.css +580 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
.venv/
|
|
8
|
+
venv/
|
|
9
|
+
env/
|
|
10
|
+
*.egg-info/
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.mypy_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
|
|
15
|
+
# Node
|
|
16
|
+
node_modules/
|
|
17
|
+
.npm/
|
|
18
|
+
|
|
19
|
+
# Build artifacts
|
|
20
|
+
dist/
|
|
21
|
+
build/
|
|
22
|
+
*.whl
|
|
23
|
+
|
|
24
|
+
# Local secrets / state
|
|
25
|
+
.env
|
|
26
|
+
.env.local
|
|
27
|
+
*.token
|
|
28
|
+
*.key
|
|
29
|
+
|
|
30
|
+
# OS
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
|
33
|
+
|
|
34
|
+
# Editor
|
|
35
|
+
.vscode/
|
|
36
|
+
.idea/
|
|
37
|
+
|
|
38
|
+
# Forensic corpora (big binaries — pulled by scripts, never committed)
|
|
39
|
+
corpus/
|
|
40
|
+
*.E01
|
|
41
|
+
*.dd
|
|
42
|
+
*.raw
|
|
43
|
+
*.vmem
|
|
44
|
+
*.mem
|
|
45
|
+
*.lime
|
|
46
|
+
*.dmp
|
|
47
|
+
|
|
48
|
+
# Volatility 3 symbol packs
|
|
49
|
+
symbols/
|
|
50
|
+
|
|
51
|
+
# Working state
|
|
52
|
+
.pair/
|
|
53
|
+
tmp/
|
|
54
|
+
*.log
|
|
55
|
+
logs/*.jsonl
|
|
56
|
+
|
|
57
|
+
# Benchmark intermediate output
|
|
58
|
+
benchmarks/runs/
|
|
59
|
+
benchmarks/cache/
|
|
60
|
+
|
|
61
|
+
# But keep these
|
|
62
|
+
!logs/.gitkeep
|
|
63
|
+
!corpus/.gitkeep
|
|
64
|
+
!symbols/.gitkeep
|
|
65
|
+
|
|
66
|
+
# Sandboxed local forensic tools (large, machine-specific)
|
|
67
|
+
.oath-tools/
|
|
68
|
+
|
|
69
|
+
# Per-run logs / envelope store / signing keys (machine-specific)
|
|
70
|
+
logs/
|
|
71
|
+
.oath/
|
|
72
|
+
keys/
|
|
73
|
+
.claude/
|
|
74
|
+
log2timeline-*.log.gz
|
|
75
|
+
psort-*.log.gz
|
|
76
|
+
|
|
77
|
+
# Paper-build artifacts (source + PDF are archived on Zenodo, not in-repo)
|
|
78
|
+
oath.tex
|
|
79
|
+
oath.pdf
|
|
80
|
+
oath.aux
|
|
81
|
+
oath.bbl
|
|
82
|
+
oath.blg
|
|
83
|
+
oath.log
|
|
84
|
+
oath.out
|
|
85
|
+
oath.bib
|
|
86
|
+
oath_*.png
|
|
87
|
+
|
|
88
|
+
# Local video composition (the recording lives outside the public repo)
|
|
89
|
+
video/
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use OATH, cite the preprint and the verifier artifact."
|
|
3
|
+
title: "OATH verifier artifact v0.1.0"
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Gharsallah
|
|
7
|
+
given-names: Malek
|
|
8
|
+
version: "v0.1.0"
|
|
9
|
+
date-released: "2026-06-05"
|
|
10
|
+
license: MIT
|
|
11
|
+
doi: "10.5281/zenodo.20549626"
|
|
12
|
+
url: "https://doi.org/10.5281/zenodo.20549626"
|
|
13
|
+
repository-code: "https://github.com/GharsallahDev/oath-mcp"
|
|
14
|
+
preferred-citation:
|
|
15
|
+
type: article
|
|
16
|
+
authors:
|
|
17
|
+
- family-names: Gharsallah
|
|
18
|
+
given-names: Malek
|
|
19
|
+
title: "OATH: Notarized Evidence Envelopes for LLM-Assisted Forensic Claims"
|
|
20
|
+
year: 2026
|
|
21
|
+
doi: "10.5281/zenodo.20549726"
|
|
22
|
+
url: "https://doi.org/10.5281/zenodo.20549726"
|
oath_mcp-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Malek Gharsallah
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
oath_mcp-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: oath-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: OATH — typed MCP server + verifier-gated evidence receipts for LLM-assisted digital forensics.
|
|
5
|
+
Project-URL: Homepage, https://github.com/GharsallahDev/oath-mcp
|
|
6
|
+
Project-URL: Repository, https://github.com/GharsallahDev/oath-mcp
|
|
7
|
+
Project-URL: Issues, https://github.com/GharsallahDev/oath-mcp/issues
|
|
8
|
+
Project-URL: Preprint (Zenodo), https://doi.org/10.5281/zenodo.20549726
|
|
9
|
+
Project-URL: Artifact (Zenodo), https://doi.org/10.5281/zenodo.20549626
|
|
10
|
+
Author-email: GharsallahDev <email@medsyn.solutions>
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: claude-code,dfir,evidence,forensics,hayabusa,incident-response,mcp,sigma
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Information Technology
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Security
|
|
22
|
+
Classifier: Topic :: System :: Systems Administration
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: anyio>=4.3.0
|
|
25
|
+
Requires-Dist: blake3>=0.4.0
|
|
26
|
+
Requires-Dist: click>=8.1.0
|
|
27
|
+
Requires-Dist: cryptography>=42.0.0
|
|
28
|
+
Requires-Dist: httpx>=0.27.0
|
|
29
|
+
Requires-Dist: mcp>=1.0.0
|
|
30
|
+
Requires-Dist: pydantic>=2.5.0
|
|
31
|
+
Requires-Dist: pynacl>=1.5.0
|
|
32
|
+
Requires-Dist: rich>=13.7.0
|
|
33
|
+
Requires-Dist: structlog>=24.1.0
|
|
34
|
+
Provides-Extra: all
|
|
35
|
+
Requires-Dist: anthropic>=0.40.0; extra == 'all'
|
|
36
|
+
Requires-Dist: construct>=2.10.0; extra == 'all'
|
|
37
|
+
Requires-Dist: dfir-iris-client>=2.0.0; extra == 'all'
|
|
38
|
+
Requires-Dist: google-cloud-aiplatform>=1.50.0; extra == 'all'
|
|
39
|
+
Requires-Dist: libfwsi-python>=20240315; extra == 'all'
|
|
40
|
+
Requires-Dist: matplotlib>=3.8.0; extra == 'all'
|
|
41
|
+
Requires-Dist: pandas>=2.2.0; extra == 'all'
|
|
42
|
+
Requires-Dist: python-evtx>=0.7.4; extra == 'all'
|
|
43
|
+
Requires-Dist: regipy>=4.0.0; extra == 'all'
|
|
44
|
+
Requires-Dist: scikit-learn>=1.4.0; extra == 'all'
|
|
45
|
+
Requires-Dist: volatility3>=2.7.0; extra == 'all'
|
|
46
|
+
Requires-Dist: yara-python>=4.5.0; extra == 'all'
|
|
47
|
+
Provides-Extra: benchmark
|
|
48
|
+
Requires-Dist: matplotlib>=3.8.0; extra == 'benchmark'
|
|
49
|
+
Requires-Dist: pandas>=2.2.0; extra == 'benchmark'
|
|
50
|
+
Requires-Dist: scikit-learn>=1.4.0; extra == 'benchmark'
|
|
51
|
+
Provides-Extra: claude
|
|
52
|
+
Requires-Dist: anthropic>=0.40.0; extra == 'claude'
|
|
53
|
+
Provides-Extra: dev
|
|
54
|
+
Requires-Dist: hypothesis>=6.100.0; extra == 'dev'
|
|
55
|
+
Requires-Dist: mypy>=1.9.0; extra == 'dev'
|
|
56
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
57
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
|
|
58
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
59
|
+
Requires-Dist: ruff>=0.4.0; extra == 'dev'
|
|
60
|
+
Provides-Extra: iris
|
|
61
|
+
Requires-Dist: dfir-iris-client>=2.0.0; extra == 'iris'
|
|
62
|
+
Provides-Extra: memory
|
|
63
|
+
Requires-Dist: volatility3>=2.7.0; extra == 'memory'
|
|
64
|
+
Provides-Extra: parsers
|
|
65
|
+
Requires-Dist: construct>=2.10.0; extra == 'parsers'
|
|
66
|
+
Requires-Dist: libfwsi-python>=20240315; extra == 'parsers'
|
|
67
|
+
Requires-Dist: python-evtx>=0.7.4; extra == 'parsers'
|
|
68
|
+
Requires-Dist: regipy>=4.0.0; extra == 'parsers'
|
|
69
|
+
Requires-Dist: yara-python>=4.5.0; extra == 'parsers'
|
|
70
|
+
Provides-Extra: vertex
|
|
71
|
+
Requires-Dist: google-cloud-aiplatform>=1.50.0; extra == 'vertex'
|
|
72
|
+
Description-Content-Type: text/markdown
|
|
73
|
+
|
|
74
|
+
# OATH
|
|
75
|
+
|
|
76
|
+
Verifier-gated evidence receipts for LLM-assisted digital forensics.
|
|
77
|
+
|
|
78
|
+
[](https://doi.org/10.5281/zenodo.20549726)
|
|
79
|
+
[](https://doi.org/10.5281/zenodo.20549626)
|
|
80
|
+
|
|
81
|
+
OATH is a research prototype for making forensic claims replayable. It separates
|
|
82
|
+
what an LLM proposes from what the evidence proves: forensic tools produce signed
|
|
83
|
+
`Notarized<T>` envelopes, and the Witness Oath Verifier promotes only claims that
|
|
84
|
+
can be deterministically re-derived from the original evidence bytes.
|
|
85
|
+
|
|
86
|
+
This repository supports the published preprint:
|
|
87
|
+
|
|
88
|
+
> **OATH: Notarized Evidence Envelopes for LLM-Assisted Forensic Claims**
|
|
89
|
+
> Zenodo DOI: [10.5281/zenodo.20549726](https://doi.org/10.5281/zenodo.20549726)
|
|
90
|
+
|
|
91
|
+
The verifier artifact is archived separately at
|
|
92
|
+
[10.5281/zenodo.20549626](https://doi.org/10.5281/zenodo.20549626).
|
|
93
|
+
|
|
94
|
+
## Relationship to Protocol SIFT
|
|
95
|
+
|
|
96
|
+
OATH extends [Protocol SIFT](https://github.com/teamdfir/protocol-sift) — the
|
|
97
|
+
open-source autonomous-DFIR baseline (Claude Code + five DFIR skill packs +
|
|
98
|
+
PDF reporter, installed under `~/.claude/`). Protocol SIFT provides the agent
|
|
99
|
+
framework; OATH layers a typed MCP-server tool surface, `Notarized<T>`
|
|
100
|
+
envelopes, and a verifier-gated promotion path on top. Both install scripts
|
|
101
|
+
(`scripts/install-tools.sh`, `scripts/install-on-sift.sh`) call Protocol SIFT's
|
|
102
|
+
own installer first, then install OATH. See
|
|
103
|
+
[docs/ARCHITECTURE.md §"How OATH extends Protocol SIFT"](docs/ARCHITECTURE.md#how-oath-extends-protocol-sift)
|
|
104
|
+
for the architectural diff.
|
|
105
|
+
|
|
106
|
+
If you already have Protocol SIFT installed (Claude Code present at
|
|
107
|
+
`~/.claude/CLAUDE.md` and the five skill packs at `~/.claude/skills/`), set
|
|
108
|
+
`OATH_SKIP_PROTOCOL_SIFT=1` before running either install script to skip the
|
|
109
|
+
baseline step:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
OATH_SKIP_PROTOCOL_SIFT=1 bash scripts/install-on-sift.sh
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Core Idea
|
|
116
|
+
|
|
117
|
+
LLM-assisted investigation fails dangerously when a fluent model summary is
|
|
118
|
+
treated as evidence. OATH treats that as a systems problem. A finding is not
|
|
119
|
+
accepted because the model said it; it is accepted only when it cites a signed
|
|
120
|
+
receipt whose contents replay.
|
|
121
|
+
|
|
122
|
+
Each `Notarized<T>` envelope binds:
|
|
123
|
+
|
|
124
|
+
- original evidence hash
|
|
125
|
+
- typed tool name and version
|
|
126
|
+
- canonical tool arguments
|
|
127
|
+
- raw tool-output hash
|
|
128
|
+
- parsed-data hash
|
|
129
|
+
- supporting byte offsets when available
|
|
130
|
+
- model identifier and prompt hash when an LLM contributed
|
|
131
|
+
- previous-envelope hash for tamper-evident sequencing
|
|
132
|
+
- Ed25519 signature over the signed header
|
|
133
|
+
|
|
134
|
+
The verifier then classifies claims as:
|
|
135
|
+
|
|
136
|
+
- `VERIFIED`: the receipt and predicate replay successfully
|
|
137
|
+
- `QUARANTINED`: the receipt is intact, but the cited claim is not supported
|
|
138
|
+
- `RALPH_WIGGUM`: evidence drift or receipt tampering is detected, forcing visible
|
|
139
|
+
abandonment and re-proposal
|
|
140
|
+
|
|
141
|
+
## Results
|
|
142
|
+
|
|
143
|
+
The benchmark is DFIR-Metric Module III, using 510 scored string-search
|
|
144
|
+
questions in the local harness and a four-candidate answer budget.
|
|
145
|
+
|
|
146
|
+
| System | TUS@4 |
|
|
147
|
+
|---|---:|
|
|
148
|
+
| GPT-4.1 published baseline | 38.5% |
|
|
149
|
+
| OATH deterministic baseline, no LLM | 78.43% |
|
|
150
|
+
| OATH live agent with verifier | 92.75% |
|
|
151
|
+
|
|
152
|
+
The architectural result matters more than the model headline: typed tool
|
|
153
|
+
invocation plus deterministic replay removes a large class of free-form
|
|
154
|
+
script-generation failures before any model-specific capability is counted.
|
|
155
|
+
|
|
156
|
+
Full methodology and audit notes are in [docs/ACCURACY.md](docs/ACCURACY.md).
|
|
157
|
+
|
|
158
|
+
## Artifact Release
|
|
159
|
+
|
|
160
|
+
A verifier-focused artifact release is archived on Zenodo:
|
|
161
|
+
|
|
162
|
+
- Artifact: [OATH verifier artifact v0.1.0](https://doi.org/10.5281/zenodo.20549626)
|
|
163
|
+
- Preprint: [OATH: Notarized Evidence Envelopes for LLM-Assisted Forensic Claims](https://doi.org/10.5281/zenodo.20549726)
|
|
164
|
+
|
|
165
|
+
The release is intended to let an independent reviewer answer the narrow
|
|
166
|
+
question: does the receipt, signature, canonicalization, replay, and
|
|
167
|
+
self-correction design work? It does not include private case data, signing
|
|
168
|
+
secrets, API keys, or operational prompts.
|
|
169
|
+
|
|
170
|
+
## Quick Start
|
|
171
|
+
|
|
172
|
+
OATH is published as a Python MCP server. Four one-liners on a SANS SIFT
|
|
173
|
+
Workstation get you from cold boot to "Claude Code is driving 13 typed
|
|
174
|
+
forensic tools against your evidence":
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
# 1. Protocol SIFT baseline (Claude Code + DFIR skill packs)
|
|
178
|
+
curl -fsSL https://raw.githubusercontent.com/teamdfir/protocol-sift/main/install.sh | bash
|
|
179
|
+
|
|
180
|
+
# 2. Forensic-binary bootstrap (.NET 9, EZ Tools, Hayabusa — what SIFT lacks)
|
|
181
|
+
curl -fsSL https://raw.githubusercontent.com/GharsallahDev/oath-mcp/main/scripts/bootstrap-forensic-tools.sh | bash
|
|
182
|
+
exec bash # pick up the new PATH
|
|
183
|
+
|
|
184
|
+
# 3. uv (if not already installed)
|
|
185
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh && exec bash
|
|
186
|
+
|
|
187
|
+
# 4. Wire OATH into Claude Code (this is what goes on screen in the demo)
|
|
188
|
+
claude mcp add --transport stdio oath -- uvx oath-mcp
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Then start a session and confirm the 13 typed tools are connected:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
claude
|
|
195
|
+
# inside Claude:
|
|
196
|
+
/mcp # → oath: connected · 13 tools
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
To use the operator CLI (`oath mount`, `oath verify`, `oath demo`) instead
|
|
200
|
+
of driving via Claude Code, install the package as a tool:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
uv tool install oath-mcp
|
|
204
|
+
oath mount path/to/evidence.E01
|
|
205
|
+
oath verify <envelope-id>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Full forensic workstation setup, including the longer-form
|
|
209
|
+
`install-on-sift.sh` alternative and a non-SIFT Docker path, is documented
|
|
210
|
+
in [docs/TRY_IT_OUT.md](docs/TRY_IT_OUT.md).
|
|
211
|
+
|
|
212
|
+
### Developing locally
|
|
213
|
+
|
|
214
|
+
For working on `src/oath/`:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
git clone https://github.com/GharsallahDev/oath-mcp-mcp
|
|
218
|
+
cd oath-mcp
|
|
219
|
+
uv venv && uv pip install -e ".[dev]"
|
|
220
|
+
PYTHONPATH=src python -m pytest tests/integration/test_spoliation.py -q
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Architecture
|
|
224
|
+
|
|
225
|
+
```mermaid
|
|
226
|
+
flowchart LR
|
|
227
|
+
IMG["Evidence image"] --> HANDLE["Read-only EvidenceHandle"]
|
|
228
|
+
HANDLE --> TOOLS["Typed forensic tools"]
|
|
229
|
+
TOOLS --> ENV["Signed Notarized<T> envelope"]
|
|
230
|
+
LLM["LLM proposes typed arguments and claims"] --> TOOLS
|
|
231
|
+
LLM --> CLAIM["Claim cites envelope_id"]
|
|
232
|
+
CLAIM --> VERIFY{"Witness Oath Verifier"}
|
|
233
|
+
ENV --> VERIFY
|
|
234
|
+
VERIFY -->|receipt replays + predicate matches| OK["VERIFIED"]
|
|
235
|
+
VERIFY -->|receipt intact, predicate missing| Q["QUARANTINED"]
|
|
236
|
+
VERIFY -->|hash/signature/data drift| R["RALPH_WIGGUM"]
|
|
237
|
+
R --> LLM
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
OATH uses a custom MCP-style tool surface with typed functions rather than an
|
|
241
|
+
arbitrary shell. The LLM can propose arguments and hypotheses; it cannot promote
|
|
242
|
+
its own findings. Promotion is reserved for the deterministic verifier.
|
|
243
|
+
|
|
244
|
+
Detailed trust-boundary notes are in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
245
|
+
|
|
246
|
+
## Repository Map
|
|
247
|
+
|
|
248
|
+
| Path | Purpose |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `src/oath/receipt/` | `Notarized<T>` envelope, canonicalization, signatures, prompt hashing |
|
|
251
|
+
| `src/oath/mcp/` | Typed forensic tool surface and evidence-handle plumbing |
|
|
252
|
+
| `src/oath/witness/` | Verifier, claim predicates, self-correction events |
|
|
253
|
+
| `src/oath/benchmark/` | DFIR-Metric harness and scoring utilities |
|
|
254
|
+
| `tests/integration/test_spoliation.py` | Spoliation, data-integrity, chain, and Daubert-binding tests |
|
|
255
|
+
| `logs/self-correction-demo/` | Re-runnable self-correction artifact |
|
|
256
|
+
| `web/` | Static receipt explorer for signed sample envelopes |
|
|
257
|
+
|
|
258
|
+
## What OATH Does Not Claim
|
|
259
|
+
|
|
260
|
+
OATH does not prove legal admissibility, certify tool correctness, make wrappers
|
|
261
|
+
honest by magic, prove general DFIR competence, or remove the need for examiner
|
|
262
|
+
review. It provides a concrete receipt and verifier pattern for making
|
|
263
|
+
LLM-assisted forensic claims auditable.
|
|
264
|
+
|
|
265
|
+
## Documentation
|
|
266
|
+
|
|
267
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
268
|
+
- [Artifact release notes](docs/ARTIFACT.md)
|
|
269
|
+
- [Publication and citation notes](docs/PUBLICATION.md)
|
|
270
|
+
- [Accuracy and benchmark notes](docs/ACCURACY.md)
|
|
271
|
+
- [Dataset documentation](docs/DATASETS.md)
|
|
272
|
+
- [Try-it-out instructions](docs/TRY_IT_OUT.md)
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
MIT. See [LICENSE](LICENSE).
|
oath_mcp-0.1.0/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# OATH
|
|
2
|
+
|
|
3
|
+
Verifier-gated evidence receipts for LLM-assisted digital forensics.
|
|
4
|
+
|
|
5
|
+
[](https://doi.org/10.5281/zenodo.20549726)
|
|
6
|
+
[](https://doi.org/10.5281/zenodo.20549626)
|
|
7
|
+
|
|
8
|
+
OATH is a research prototype for making forensic claims replayable. It separates
|
|
9
|
+
what an LLM proposes from what the evidence proves: forensic tools produce signed
|
|
10
|
+
`Notarized<T>` envelopes, and the Witness Oath Verifier promotes only claims that
|
|
11
|
+
can be deterministically re-derived from the original evidence bytes.
|
|
12
|
+
|
|
13
|
+
This repository supports the published preprint:
|
|
14
|
+
|
|
15
|
+
> **OATH: Notarized Evidence Envelopes for LLM-Assisted Forensic Claims**
|
|
16
|
+
> Zenodo DOI: [10.5281/zenodo.20549726](https://doi.org/10.5281/zenodo.20549726)
|
|
17
|
+
|
|
18
|
+
The verifier artifact is archived separately at
|
|
19
|
+
[10.5281/zenodo.20549626](https://doi.org/10.5281/zenodo.20549626).
|
|
20
|
+
|
|
21
|
+
## Relationship to Protocol SIFT
|
|
22
|
+
|
|
23
|
+
OATH extends [Protocol SIFT](https://github.com/teamdfir/protocol-sift) — the
|
|
24
|
+
open-source autonomous-DFIR baseline (Claude Code + five DFIR skill packs +
|
|
25
|
+
PDF reporter, installed under `~/.claude/`). Protocol SIFT provides the agent
|
|
26
|
+
framework; OATH layers a typed MCP-server tool surface, `Notarized<T>`
|
|
27
|
+
envelopes, and a verifier-gated promotion path on top. Both install scripts
|
|
28
|
+
(`scripts/install-tools.sh`, `scripts/install-on-sift.sh`) call Protocol SIFT's
|
|
29
|
+
own installer first, then install OATH. See
|
|
30
|
+
[docs/ARCHITECTURE.md §"How OATH extends Protocol SIFT"](docs/ARCHITECTURE.md#how-oath-extends-protocol-sift)
|
|
31
|
+
for the architectural diff.
|
|
32
|
+
|
|
33
|
+
If you already have Protocol SIFT installed (Claude Code present at
|
|
34
|
+
`~/.claude/CLAUDE.md` and the five skill packs at `~/.claude/skills/`), set
|
|
35
|
+
`OATH_SKIP_PROTOCOL_SIFT=1` before running either install script to skip the
|
|
36
|
+
baseline step:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
OATH_SKIP_PROTOCOL_SIFT=1 bash scripts/install-on-sift.sh
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Core Idea
|
|
43
|
+
|
|
44
|
+
LLM-assisted investigation fails dangerously when a fluent model summary is
|
|
45
|
+
treated as evidence. OATH treats that as a systems problem. A finding is not
|
|
46
|
+
accepted because the model said it; it is accepted only when it cites a signed
|
|
47
|
+
receipt whose contents replay.
|
|
48
|
+
|
|
49
|
+
Each `Notarized<T>` envelope binds:
|
|
50
|
+
|
|
51
|
+
- original evidence hash
|
|
52
|
+
- typed tool name and version
|
|
53
|
+
- canonical tool arguments
|
|
54
|
+
- raw tool-output hash
|
|
55
|
+
- parsed-data hash
|
|
56
|
+
- supporting byte offsets when available
|
|
57
|
+
- model identifier and prompt hash when an LLM contributed
|
|
58
|
+
- previous-envelope hash for tamper-evident sequencing
|
|
59
|
+
- Ed25519 signature over the signed header
|
|
60
|
+
|
|
61
|
+
The verifier then classifies claims as:
|
|
62
|
+
|
|
63
|
+
- `VERIFIED`: the receipt and predicate replay successfully
|
|
64
|
+
- `QUARANTINED`: the receipt is intact, but the cited claim is not supported
|
|
65
|
+
- `RALPH_WIGGUM`: evidence drift or receipt tampering is detected, forcing visible
|
|
66
|
+
abandonment and re-proposal
|
|
67
|
+
|
|
68
|
+
## Results
|
|
69
|
+
|
|
70
|
+
The benchmark is DFIR-Metric Module III, using 510 scored string-search
|
|
71
|
+
questions in the local harness and a four-candidate answer budget.
|
|
72
|
+
|
|
73
|
+
| System | TUS@4 |
|
|
74
|
+
|---|---:|
|
|
75
|
+
| GPT-4.1 published baseline | 38.5% |
|
|
76
|
+
| OATH deterministic baseline, no LLM | 78.43% |
|
|
77
|
+
| OATH live agent with verifier | 92.75% |
|
|
78
|
+
|
|
79
|
+
The architectural result matters more than the model headline: typed tool
|
|
80
|
+
invocation plus deterministic replay removes a large class of free-form
|
|
81
|
+
script-generation failures before any model-specific capability is counted.
|
|
82
|
+
|
|
83
|
+
Full methodology and audit notes are in [docs/ACCURACY.md](docs/ACCURACY.md).
|
|
84
|
+
|
|
85
|
+
## Artifact Release
|
|
86
|
+
|
|
87
|
+
A verifier-focused artifact release is archived on Zenodo:
|
|
88
|
+
|
|
89
|
+
- Artifact: [OATH verifier artifact v0.1.0](https://doi.org/10.5281/zenodo.20549626)
|
|
90
|
+
- Preprint: [OATH: Notarized Evidence Envelopes for LLM-Assisted Forensic Claims](https://doi.org/10.5281/zenodo.20549726)
|
|
91
|
+
|
|
92
|
+
The release is intended to let an independent reviewer answer the narrow
|
|
93
|
+
question: does the receipt, signature, canonicalization, replay, and
|
|
94
|
+
self-correction design work? It does not include private case data, signing
|
|
95
|
+
secrets, API keys, or operational prompts.
|
|
96
|
+
|
|
97
|
+
## Quick Start
|
|
98
|
+
|
|
99
|
+
OATH is published as a Python MCP server. Four one-liners on a SANS SIFT
|
|
100
|
+
Workstation get you from cold boot to "Claude Code is driving 13 typed
|
|
101
|
+
forensic tools against your evidence":
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# 1. Protocol SIFT baseline (Claude Code + DFIR skill packs)
|
|
105
|
+
curl -fsSL https://raw.githubusercontent.com/teamdfir/protocol-sift/main/install.sh | bash
|
|
106
|
+
|
|
107
|
+
# 2. Forensic-binary bootstrap (.NET 9, EZ Tools, Hayabusa — what SIFT lacks)
|
|
108
|
+
curl -fsSL https://raw.githubusercontent.com/GharsallahDev/oath-mcp/main/scripts/bootstrap-forensic-tools.sh | bash
|
|
109
|
+
exec bash # pick up the new PATH
|
|
110
|
+
|
|
111
|
+
# 3. uv (if not already installed)
|
|
112
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh && exec bash
|
|
113
|
+
|
|
114
|
+
# 4. Wire OATH into Claude Code (this is what goes on screen in the demo)
|
|
115
|
+
claude mcp add --transport stdio oath -- uvx oath-mcp
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Then start a session and confirm the 13 typed tools are connected:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
claude
|
|
122
|
+
# inside Claude:
|
|
123
|
+
/mcp # → oath: connected · 13 tools
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
To use the operator CLI (`oath mount`, `oath verify`, `oath demo`) instead
|
|
127
|
+
of driving via Claude Code, install the package as a tool:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
uv tool install oath-mcp
|
|
131
|
+
oath mount path/to/evidence.E01
|
|
132
|
+
oath verify <envelope-id>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Full forensic workstation setup, including the longer-form
|
|
136
|
+
`install-on-sift.sh` alternative and a non-SIFT Docker path, is documented
|
|
137
|
+
in [docs/TRY_IT_OUT.md](docs/TRY_IT_OUT.md).
|
|
138
|
+
|
|
139
|
+
### Developing locally
|
|
140
|
+
|
|
141
|
+
For working on `src/oath/`:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
git clone https://github.com/GharsallahDev/oath-mcp-mcp
|
|
145
|
+
cd oath-mcp
|
|
146
|
+
uv venv && uv pip install -e ".[dev]"
|
|
147
|
+
PYTHONPATH=src python -m pytest tests/integration/test_spoliation.py -q
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Architecture
|
|
151
|
+
|
|
152
|
+
```mermaid
|
|
153
|
+
flowchart LR
|
|
154
|
+
IMG["Evidence image"] --> HANDLE["Read-only EvidenceHandle"]
|
|
155
|
+
HANDLE --> TOOLS["Typed forensic tools"]
|
|
156
|
+
TOOLS --> ENV["Signed Notarized<T> envelope"]
|
|
157
|
+
LLM["LLM proposes typed arguments and claims"] --> TOOLS
|
|
158
|
+
LLM --> CLAIM["Claim cites envelope_id"]
|
|
159
|
+
CLAIM --> VERIFY{"Witness Oath Verifier"}
|
|
160
|
+
ENV --> VERIFY
|
|
161
|
+
VERIFY -->|receipt replays + predicate matches| OK["VERIFIED"]
|
|
162
|
+
VERIFY -->|receipt intact, predicate missing| Q["QUARANTINED"]
|
|
163
|
+
VERIFY -->|hash/signature/data drift| R["RALPH_WIGGUM"]
|
|
164
|
+
R --> LLM
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
OATH uses a custom MCP-style tool surface with typed functions rather than an
|
|
168
|
+
arbitrary shell. The LLM can propose arguments and hypotheses; it cannot promote
|
|
169
|
+
its own findings. Promotion is reserved for the deterministic verifier.
|
|
170
|
+
|
|
171
|
+
Detailed trust-boundary notes are in [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md).
|
|
172
|
+
|
|
173
|
+
## Repository Map
|
|
174
|
+
|
|
175
|
+
| Path | Purpose |
|
|
176
|
+
|---|---|
|
|
177
|
+
| `src/oath/receipt/` | `Notarized<T>` envelope, canonicalization, signatures, prompt hashing |
|
|
178
|
+
| `src/oath/mcp/` | Typed forensic tool surface and evidence-handle plumbing |
|
|
179
|
+
| `src/oath/witness/` | Verifier, claim predicates, self-correction events |
|
|
180
|
+
| `src/oath/benchmark/` | DFIR-Metric harness and scoring utilities |
|
|
181
|
+
| `tests/integration/test_spoliation.py` | Spoliation, data-integrity, chain, and Daubert-binding tests |
|
|
182
|
+
| `logs/self-correction-demo/` | Re-runnable self-correction artifact |
|
|
183
|
+
| `web/` | Static receipt explorer for signed sample envelopes |
|
|
184
|
+
|
|
185
|
+
## What OATH Does Not Claim
|
|
186
|
+
|
|
187
|
+
OATH does not prove legal admissibility, certify tool correctness, make wrappers
|
|
188
|
+
honest by magic, prove general DFIR competence, or remove the need for examiner
|
|
189
|
+
review. It provides a concrete receipt and verifier pattern for making
|
|
190
|
+
LLM-assisted forensic claims auditable.
|
|
191
|
+
|
|
192
|
+
## Documentation
|
|
193
|
+
|
|
194
|
+
- [Architecture](docs/ARCHITECTURE.md)
|
|
195
|
+
- [Artifact release notes](docs/ARTIFACT.md)
|
|
196
|
+
- [Publication and citation notes](docs/PUBLICATION.md)
|
|
197
|
+
- [Accuracy and benchmark notes](docs/ACCURACY.md)
|
|
198
|
+
- [Dataset documentation](docs/DATASETS.md)
|
|
199
|
+
- [Try-it-out instructions](docs/TRY_IT_OUT.md)
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT. See [LICENSE](LICENSE).
|
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# OATH — Eric Zimmerman's tools (EZ tools) in a pinned .NET 9 container.
|
|
2
|
+
#
|
|
3
|
+
# Pins:
|
|
4
|
+
# - .NET 9.0.0 (SDK runtime — EZ tools target net9.0)
|
|
5
|
+
# - dotnet-tools.json controls which tools + which versions get installed.
|
|
6
|
+
#
|
|
7
|
+
# Tools available after build (invoke as `dotnet TOOLNAME` inside the container):
|
|
8
|
+
# - MFTECmd — $MFT, $J ($UsnJrnl), $LogFile, $Boot, $SDS, $I30 parser
|
|
9
|
+
# - EvtxECmd — Windows Event Log (.evtx) parser with Sigma-style maps
|
|
10
|
+
# - AmcacheParser — Amcache.hve parser
|
|
11
|
+
# - PECmd — Prefetch parser
|
|
12
|
+
# - SrumECmd — SRUDB.dat (process / network / energy) parser
|
|
13
|
+
# - WxTCmd — Windows Timeline ActivitiesCache.db parser
|
|
14
|
+
# - RECmd — Registry hive parser with batch-mode plugins
|
|
15
|
+
# - SBECmd — ShellBags parser
|
|
16
|
+
# - JLECmd — Jump List parser
|
|
17
|
+
# - LECmd — LNK (shortcut) parser
|
|
18
|
+
#
|
|
19
|
+
# All tools accept `--csv-output` or `--json-output` for structured output that
|
|
20
|
+
# the OATH typed-functions layer can deterministically re-derive against.
|
|
21
|
+
|
|
22
|
+
FROM mcr.microsoft.com/dotnet/sdk:9.0
|
|
23
|
+
|
|
24
|
+
# Working dir for tool execution. Mounts inbound: /evidence (RO), /output (RW).
|
|
25
|
+
WORKDIR /work
|
|
26
|
+
VOLUME ["/evidence", "/output"]
|
|
27
|
+
|
|
28
|
+
# Install EZ tools via dotnet-tools.json manifest (pinned versions).
|
|
29
|
+
COPY dotnet-tools.json /work/.config/dotnet-tools.json
|
|
30
|
+
RUN cd /work && dotnet tool restore && dotnet tool list
|
|
31
|
+
|
|
32
|
+
# Add the local tool manifest dir to PATH so `EvtxECmd` etc. are callable.
|
|
33
|
+
ENV PATH="/root/.dotnet/tools:${PATH}"
|
|
34
|
+
ENV DOTNET_CLI_TELEMETRY_OPTOUT=1
|
|
35
|
+
ENV DOTNET_NOLOGO=1
|
|
36
|
+
|
|
37
|
+
# Quick self-check — fails the build if any tool was misnamed or unreleased.
|
|
38
|
+
RUN dotnet EvtxECmd --version || (echo "EvtxECmd not found" && exit 1)
|
|
39
|
+
RUN dotnet MFTECmd --version || (echo "MFTECmd not found" && exit 1)
|
|
40
|
+
|
|
41
|
+
# Idle entrypoint; the OATH MCP server `docker exec`s into this container.
|
|
42
|
+
CMD ["tail", "-f", "/dev/null"]
|