test_knowtation_mcp_security.py python
68 lines 2.3 KB
Raw
sha256:cf6265cea8c21d9228d90dec13ef6ec2dab5103d466db9cc4590681832de4bf8 docs(KD-STAGING): sync governance after KD-6b DONE Human 13 days ago
1 """Tier 7 — security tests for knowtation MCP."""
2
3 from __future__ import annotations
4
5 import pathlib
6
7 import pytest
8
9 from muse.core.attestation import get_attestation_provider, unregister_attestation_provider
10 from muse.mcp.errors import MCPApplicationError
11 from muse.mcp.server import MuseMCPServer
12 from muse.mcp.namespaces.knowtation import KnowtationNamespace
13 from muse.plugins.knowtation.mcp_helpers import validate_note_path
14
15
16 @pytest.fixture
17 def smoke_root() -> pathlib.Path:
18 return pathlib.Path("/Users/aaronrenecarvajal/MUSE_HUB/knowtation-vault-smoke")
19
20
21 def test_path_traversal_rejected() -> None:
22 with pytest.raises(Exception) as exc:
23 validate_note_path("../../secret.md")
24 assert exc.value.reason == "PATH_INVALID"
25
26
27 def test_activation_gate_blocks_tools(tmp_path: pathlib.Path) -> None:
28 (tmp_path / ".muse").mkdir()
29 (tmp_path / ".muse" / "repo.json").write_text('{"domain":"code","repo_id":"x"}', encoding="utf-8")
30 server = MuseMCPServer(tmp_path)
31 resp = server.handle_request(
32 {
33 "jsonrpc": "2.0",
34 "id": 1,
35 "method": "tools/call",
36 "params": {"name": "knowtation/search", "arguments": {"query": "x"}},
37 }
38 )
39 assert resp is not None
40 assert "error" in resp
41
42
43 def test_provider_unregistered_attest(smoke_root: pathlib.Path) -> None:
44 ns = KnowtationNamespace(smoke_root)
45 unregister_attestation_provider("knowtation")
46 try:
47 with pytest.raises(MCPApplicationError) as exc:
48 ns.call_tool("knowtation/attest", {"commit_id": "0" * 64})
49 assert exc.value.reason == "PROVIDER_UNREGISTERED"
50 finally:
51 from muse.mcp.bootstrap import bootstrap_knowtation_mcp
52
53 bootstrap_knowtation_mcp(smoke_root)
54 assert get_attestation_provider("knowtation") is not None
55
56
57 def test_no_secrets_in_search_error(smoke_root: pathlib.Path) -> None:
58 ns = KnowtationNamespace(smoke_root)
59 out = ns.call_tool("knowtation/search", {"query": "test", "mode": "lexical"})
60 blob = str(out)
61 for secret in ("MUSE_AIR_HMAC_KEY", "KNOWTATION_HUB_PORT", "BEGIN PRIVATE KEY"):
62 assert secret not in blob
63
64
65 def test_resource_path_escape_rejected(smoke_root: pathlib.Path) -> None:
66 ns = KnowtationNamespace(smoke_root)
67 with pytest.raises(MCPApplicationError):
68 ns.read_resource("knowtation://vault/../../etc/passwd.md")
File History 1 commit
sha256:cf6265cea8c21d9228d90dec13ef6ec2dab5103d466db9cc4590681832de4bf8 docs(KD-STAGING): sync governance after KD-6b DONE Human 13 days ago