stopgate 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.
- stopgate-0.1.0/LICENSE +21 -0
- stopgate-0.1.0/PKG-INFO +181 -0
- stopgate-0.1.0/README.md +163 -0
- stopgate-0.1.0/pyproject.toml +35 -0
- stopgate-0.1.0/setup.cfg +4 -0
- stopgate-0.1.0/src/stopgate/__init__.py +12 -0
- stopgate-0.1.0/src/stopgate/cli.py +711 -0
- stopgate-0.1.0/src/stopgate/core/__init__.py +2 -0
- stopgate-0.1.0/src/stopgate/core/action.py +196 -0
- stopgate-0.1.0/src/stopgate/core/detectors.py +117 -0
- stopgate-0.1.0/src/stopgate/core/patterns.py +164 -0
- stopgate-0.1.0/src/stopgate/core/taint.py +513 -0
- stopgate-0.1.0/src/stopgate/data/sample_session.jsonl +8 -0
- stopgate-0.1.0/src/stopgate/digest.py +210 -0
- stopgate-0.1.0/src/stopgate/engine.py +118 -0
- stopgate-0.1.0/src/stopgate/evalsuite.py +443 -0
- stopgate-0.1.0/src/stopgate/logparse.py +286 -0
- stopgate-0.1.0/src/stopgate/policy.py +482 -0
- stopgate-0.1.0/src/stopgate/session.py +260 -0
- stopgate-0.1.0/src/stopgate/supervisor.py +113 -0
- stopgate-0.1.0/src/stopgate.egg-info/PKG-INFO +181 -0
- stopgate-0.1.0/src/stopgate.egg-info/SOURCES.txt +35 -0
- stopgate-0.1.0/src/stopgate.egg-info/dependency_links.txt +1 -0
- stopgate-0.1.0/src/stopgate.egg-info/entry_points.txt +2 -0
- stopgate-0.1.0/src/stopgate.egg-info/top_level.txt +1 -0
- stopgate-0.1.0/tests/test_action.py +322 -0
- stopgate-0.1.0/tests/test_claude_code_transcript.py +78 -0
- stopgate-0.1.0/tests/test_cli.py +351 -0
- stopgate-0.1.0/tests/test_detectors.py +189 -0
- stopgate-0.1.0/tests/test_digest.py +183 -0
- stopgate-0.1.0/tests/test_engine.py +200 -0
- stopgate-0.1.0/tests/test_eval.py +60 -0
- stopgate-0.1.0/tests/test_live_gate.py +174 -0
- stopgate-0.1.0/tests/test_logparse.py +292 -0
- stopgate-0.1.0/tests/test_policy.py +356 -0
- stopgate-0.1.0/tests/test_supervisor.py +121 -0
- stopgate-0.1.0/tests/test_taint.py +309 -0
stopgate-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rohan Kaila
|
|
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.
|
stopgate-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stopgate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Stop watching your agent. A local-first safety envelope that lets you run coding agents unattended.
|
|
5
|
+
Author: Rohan Kaila
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Robomba/stopgate
|
|
8
|
+
Project-URL: Source, https://github.com/Robomba/stopgate
|
|
9
|
+
Keywords: ai,agent,security,guardrail,claude,prompt-injection,taint,dataflow
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Topic :: Security
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Requires-Python: >=3.9
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Dynamic: license-file
|
|
18
|
+
|
|
19
|
+
# Stopgate
|
|
20
|
+
|
|
21
|
+
[](https://github.com/Robomba/stopgate/actions/workflows/ci.yml)
|
|
22
|
+
· MIT · zero runtime deps · runs entirely on your machine
|
|
23
|
+
|
|
24
|
+
### Stop watching your agent.
|
|
25
|
+
|
|
26
|
+
You don't babysit your coding agent because it's dangerous. You babysit it because you can't tell the difference between it *reading a file* and it *reading your `.env` and POSTing it to an IP it found in a README.*
|
|
27
|
+
|
|
28
|
+
Stopgate can. So you can go do something else.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install stopgate
|
|
32
|
+
stopgate report
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
> The PyPI package is **`stopgate`** (plain `stopgate` is an unrelated project); the
|
|
36
|
+
> command is just `stopgate`. For the bleeding edge:
|
|
37
|
+
> `pip install "git+https://github.com/Robomba/stopgate.git"`.
|
|
38
|
+
|
|
39
|
+
No config. It reads the logs your agent already wrote and tells you what it's been doing.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
This session — 8 agent actions:
|
|
43
|
+
|
|
44
|
+
1 file reads touched credentials (/home/dev/app/.env)
|
|
45
|
+
3 network calls to 3 domains (docs.example.com, collect.evil.example, api.github.com)
|
|
46
|
+
1 destructive commands (no confirmation asked)
|
|
47
|
+
1 outbound payload carried a secret read earlier <- this is the one
|
|
48
|
+
2 action(s) taken shortly after reading untrusted content
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Free. MIT. Runs entirely on your machine. Makes zero network calls of its own.**
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Why it's different
|
|
56
|
+
|
|
57
|
+
Most guardrails you can `pip install` today match **keywords**. We published the benchmark showing that doesn't work: a bag-of-words classifier with no model at all scores **0.967** on the standard harm benchmark — and **0.493 (chance)** the moment the attacker stops using the obvious words. Keyword guardrails aren't detecting intent. They're detecting vocabulary. ([AICES paper](https://github.com/Robomba/ai-control-eval-suite) · [dataset](https://huggingface.co/datasets/Robomb/aices-minpair-control))
|
|
58
|
+
|
|
59
|
+
Stopgate watches **where data came from and where it's going.** It tracks which tool results are untrusted (web/email/file/MCP), taints the session when the agent reads them, and fingerprints every secret it sees so it can spot that secret leaving the machine — **even base64-encoded.** *"The agent read `evil.com`, then tried to POST your `.env`"* is not a wording problem. You can't rephrase your way past a hash comparison.
|
|
60
|
+
|
|
61
|
+
**This isn't a new idea, and I won't pretend it is.** Provenance/dataflow defenses for
|
|
62
|
+
agents already exist in research: DeepMind's [CaMeL](https://arxiv.org/abs/2503.18813),
|
|
63
|
+
[Invariant Labs](https://invariantlabs.ai/) (acquired into Snyk), Meta's
|
|
64
|
+
[LlamaFirewall](https://arxiv.org/abs/2505.03574). Stopgate's contribution is **not** the
|
|
65
|
+
concept — it's (1) a zero-config build you can install and run against your own Claude Code
|
|
66
|
+
sessions today, and (2) an **open, minimal-pair controlled benchmark for agent actions** that
|
|
67
|
+
measures the thing everyone hand-waves: how often a guardrail cries wolf. The benchmark is the
|
|
68
|
+
new part; the gate is an honest implementation of a known idea. And to be precise about *how* it
|
|
69
|
+
works: it's a **lexical** action layer (regex for `rm -rf`, `DROP TABLE`, `curl | bash`) **plus**
|
|
70
|
+
a **non-lexical** provenance layer — not "dataflow instead of keywords," but both.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Turn it on (live gating)
|
|
75
|
+
|
|
76
|
+
Stopgate plugs into Claude Code as two hooks. **You need both.**
|
|
77
|
+
|
|
78
|
+
```jsonc
|
|
79
|
+
// ~/.claude/settings.json
|
|
80
|
+
{
|
|
81
|
+
"hooks": {
|
|
82
|
+
"PreToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "stopgate hook" }] }],
|
|
83
|
+
"PostToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "stopgate watch" }] }]
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Why two? `PreToolUse` fires *before* a tool runs, so it never sees a **result** —
|
|
89
|
+
no result, no secret bytes, nothing to fingerprint. `stopgate watch` (PostToolUse)
|
|
90
|
+
is the only place a secret can actually be captured. **Without `watch`, Stopgate
|
|
91
|
+
can only judge one action at a time and cross-call exfiltration is not detected.**
|
|
92
|
+
With it, "read the `.env` at step 3, POST it to an unknown host at step 19" is
|
|
93
|
+
caught — the payload at step 19 looks innocent on its own.
|
|
94
|
+
|
|
95
|
+
### Modes
|
|
96
|
+
|
|
97
|
+
| Mode | Behaviour | Use it when |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `observe` | Scores and logs everything, **always allows**. Cannot stall an agent. | You're building trust, or the agent runs unattended and must never block. |
|
|
100
|
+
| `enforce` *(default)* | A hard-stop surfaces to you as an **ask**. Everything else auto-approves. | You're at the keyboard. |
|
|
101
|
+
| `enforce --headless` | A hard-stop **denies** instead of asking. | Nobody is there — an "ask" nobody answers is a hang, not a guardrail. |
|
|
102
|
+
|
|
103
|
+
Set with `--mode`, or `$STOPGATE_MODE`, or a `~/.stopgate-mode` file.
|
|
104
|
+
|
|
105
|
+
**Kill switch:** `echo observe > ~/.stopgate-mode` — instantly back to logging-only,
|
|
106
|
+
no restart, no config edit.
|
|
107
|
+
|
|
108
|
+
### What it never does
|
|
109
|
+
|
|
110
|
+
Stopgate **never writes your secrets to disk.** Session state holds only rolling-hash
|
|
111
|
+
fingerprints and salted hashes — enough to recognise those bytes trying to leave,
|
|
112
|
+
not enough to reconstruct them. A stolen state file yields nothing. (State lives in
|
|
113
|
+
`~/.cache/stopgate/sessions`, mode `0600`, expires after 7 days.)
|
|
114
|
+
|
|
115
|
+
It also **fails open, on purpose**: if Stopgate itself errors, the tool call is
|
|
116
|
+
allowed and the error is logged. A broken guardrail must never brick the agent it
|
|
117
|
+
is watching. That is a deliberate trade-off, and it is the honest one to state:
|
|
118
|
+
**Stopgate is a safety net, not a guarantee.** It can miss things. Do not use it as
|
|
119
|
+
the only thing standing between an agent and something you cannot undo.
|
|
120
|
+
|
|
121
|
+
## Our promises
|
|
122
|
+
|
|
123
|
+
These are commitments, not features. They're the reason you can trust a security tool you didn't write.
|
|
124
|
+
|
|
125
|
+
**1. We will never phone home.** Zero telemetry, zero analytics, no network calls of Stopgate's own — ever. A security tool that exfiltrates your data to prove nothing is exfiltrating your data is a joke. The code is MIT; verify it.
|
|
126
|
+
|
|
127
|
+
**2. We publish our false-alarm rate every release.** Not our catch rate — anyone can catch everything by blocking everything. The number that matters is **how often we interrupt you for nothing**, and we print it whether it's good or bad. I haven't found another installable agent guardrail that publishes its false-alarm rate on a controlled set — if you know one, tell me and I'll link it.
|
|
128
|
+
|
|
129
|
+
**3. Sixty seconds or we failed.** Install to first insight with no config file, no policy language, no account. If you have to *learn* Stopgate before it helps you, we built it wrong.
|
|
130
|
+
|
|
131
|
+
**4. Some things always stop for a human.** Money moving, production, anything irreversible — those wake you up no matter what your policy says. No "trust level" will ever override that. If a tool offers to fully automate spending your money, close the tab.
|
|
132
|
+
|
|
133
|
+
**5. We tell you what we can't do.** (See below — it stays in the README, permanently.)
|
|
134
|
+
|
|
135
|
+
**6. We'll never ship an attack to sell the defense.** Our demos use dummy canaries and local sinks. We don't publish weapons.
|
|
136
|
+
|
|
137
|
+
**7. Free, MIT, forever.** And the benchmark we grade ourselves with is public — run it against us, and against everyone else.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
## ⚠ Disclaimer
|
|
143
|
+
|
|
144
|
+
**Stopgate is best-effort and will make mistakes.** It can miss real attacks and flag safe
|
|
145
|
+
actions. It is **not a guarantee of safety**, not a substitute for code review or OS
|
|
146
|
+
sandboxing, and is provided **AS IS with no warranty** (MIT). Benchmark numbers come from a
|
|
147
|
+
small, non-human-audited seed set and are indicative, not definitive. **You are responsible
|
|
148
|
+
for what your agent does.** Full text: [DISCLAIMER.md](DISCLAIMER.md).
|
|
149
|
+
|
|
150
|
+
## What Stopgate does NOT catch
|
|
151
|
+
|
|
152
|
+
A security tool that overclaims is worse than none. Stopgate sees **actions, not thoughts.**
|
|
153
|
+
|
|
154
|
+
- **A genuinely malicious model with a covert channel.** If the model is the adversary and hides intent in benign-looking actions, Stopgate can't read its mind.
|
|
155
|
+
- **Anything outside the tool-call boundary.** If it doesn't go through a tool call Stopgate can see, Stopgate can't see it.
|
|
156
|
+
- **The "acted after untrusted content" signal is a temporal-proximity heuristic, not true taint.** We can't see which datum actually influenced the model, so we flag high-risk actions within N steps of an untrusted read — with confidence that **decays** with distance and is **evadable** by simply spacing the action out past the window.
|
|
157
|
+
- **Injection-provenance without secret egress.** A benign-*looking* action an agent runs because untrusted content told it to (no secret leaving) scores at **chance** in our own benchmark — Stopgate ties the keyword baseline there. Stopgate's real dataflow edge is secret-**egress**, not injection-provenance. We publish this miss (see `stopgate eval`).
|
|
158
|
+
- **Transformed exfil.** Byte-matching catches naive/base64/hex copies of a secret; gzip, encryption, or having the model paraphrase the secret defeat it. A competent adversary can get data out. It raises the cost; it is not a wall.
|
|
159
|
+
- **Anything not routed through the adapter** — a subprocess the agent spawns, network made from inside a tool's own code, or an MCP server talked to out-of-band — is invisible.
|
|
160
|
+
- **Closed chat UIs** (ChatGPT / Claude web). There's no interception point.
|
|
161
|
+
- **It is not a substitute for OS-level sandboxing.** Run untrusted agents in a container/VM. Stopgate is a layer on top, not a replacement.
|
|
162
|
+
|
|
163
|
+
Stopgate **reduces babysitting; it does not eliminate risk.**
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Status
|
|
168
|
+
|
|
169
|
+
**Shipped (local, verified):**
|
|
170
|
+
- `stopgate report` — read-only, zero-config: what your agent has been doing.
|
|
171
|
+
- `stopgate digest` — the session receipt: what was let through and *why it was safe*.
|
|
172
|
+
- `stopgate learn` — writes an editable allow-policy from your own sessions (opt-in tuning).
|
|
173
|
+
- `stopgate run` — unattended supervision: **auto-approve in-policy, hard-stop the irreversible.** Money, production, destructive, sign-in, install, and any secret leaving the machine always stop for a human — no policy can override that.
|
|
174
|
+
- `stopgate hook` — the live Claude Code PreToolUse gate (returns allow / ask per tool call).
|
|
175
|
+
|
|
176
|
+
**Next:** `stopgate eval` — the public precision benchmark (false alarms per 1,000 actions).
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
## License
|
|
180
|
+
|
|
181
|
+
MIT. Local-first. No network calls of its own.
|
stopgate-0.1.0/README.md
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Stopgate
|
|
2
|
+
|
|
3
|
+
[](https://github.com/Robomba/stopgate/actions/workflows/ci.yml)
|
|
4
|
+
· MIT · zero runtime deps · runs entirely on your machine
|
|
5
|
+
|
|
6
|
+
### Stop watching your agent.
|
|
7
|
+
|
|
8
|
+
You don't babysit your coding agent because it's dangerous. You babysit it because you can't tell the difference between it *reading a file* and it *reading your `.env` and POSTing it to an IP it found in a README.*
|
|
9
|
+
|
|
10
|
+
Stopgate can. So you can go do something else.
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
pip install stopgate
|
|
14
|
+
stopgate report
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
> The PyPI package is **`stopgate`** (plain `stopgate` is an unrelated project); the
|
|
18
|
+
> command is just `stopgate`. For the bleeding edge:
|
|
19
|
+
> `pip install "git+https://github.com/Robomba/stopgate.git"`.
|
|
20
|
+
|
|
21
|
+
No config. It reads the logs your agent already wrote and tells you what it's been doing.
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
This session — 8 agent actions:
|
|
25
|
+
|
|
26
|
+
1 file reads touched credentials (/home/dev/app/.env)
|
|
27
|
+
3 network calls to 3 domains (docs.example.com, collect.evil.example, api.github.com)
|
|
28
|
+
1 destructive commands (no confirmation asked)
|
|
29
|
+
1 outbound payload carried a secret read earlier <- this is the one
|
|
30
|
+
2 action(s) taken shortly after reading untrusted content
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Free. MIT. Runs entirely on your machine. Makes zero network calls of its own.**
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Why it's different
|
|
38
|
+
|
|
39
|
+
Most guardrails you can `pip install` today match **keywords**. We published the benchmark showing that doesn't work: a bag-of-words classifier with no model at all scores **0.967** on the standard harm benchmark — and **0.493 (chance)** the moment the attacker stops using the obvious words. Keyword guardrails aren't detecting intent. They're detecting vocabulary. ([AICES paper](https://github.com/Robomba/ai-control-eval-suite) · [dataset](https://huggingface.co/datasets/Robomb/aices-minpair-control))
|
|
40
|
+
|
|
41
|
+
Stopgate watches **where data came from and where it's going.** It tracks which tool results are untrusted (web/email/file/MCP), taints the session when the agent reads them, and fingerprints every secret it sees so it can spot that secret leaving the machine — **even base64-encoded.** *"The agent read `evil.com`, then tried to POST your `.env`"* is not a wording problem. You can't rephrase your way past a hash comparison.
|
|
42
|
+
|
|
43
|
+
**This isn't a new idea, and I won't pretend it is.** Provenance/dataflow defenses for
|
|
44
|
+
agents already exist in research: DeepMind's [CaMeL](https://arxiv.org/abs/2503.18813),
|
|
45
|
+
[Invariant Labs](https://invariantlabs.ai/) (acquired into Snyk), Meta's
|
|
46
|
+
[LlamaFirewall](https://arxiv.org/abs/2505.03574). Stopgate's contribution is **not** the
|
|
47
|
+
concept — it's (1) a zero-config build you can install and run against your own Claude Code
|
|
48
|
+
sessions today, and (2) an **open, minimal-pair controlled benchmark for agent actions** that
|
|
49
|
+
measures the thing everyone hand-waves: how often a guardrail cries wolf. The benchmark is the
|
|
50
|
+
new part; the gate is an honest implementation of a known idea. And to be precise about *how* it
|
|
51
|
+
works: it's a **lexical** action layer (regex for `rm -rf`, `DROP TABLE`, `curl | bash`) **plus**
|
|
52
|
+
a **non-lexical** provenance layer — not "dataflow instead of keywords," but both.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Turn it on (live gating)
|
|
57
|
+
|
|
58
|
+
Stopgate plugs into Claude Code as two hooks. **You need both.**
|
|
59
|
+
|
|
60
|
+
```jsonc
|
|
61
|
+
// ~/.claude/settings.json
|
|
62
|
+
{
|
|
63
|
+
"hooks": {
|
|
64
|
+
"PreToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "stopgate hook" }] }],
|
|
65
|
+
"PostToolUse": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "stopgate watch" }] }]
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Why two? `PreToolUse` fires *before* a tool runs, so it never sees a **result** —
|
|
71
|
+
no result, no secret bytes, nothing to fingerprint. `stopgate watch` (PostToolUse)
|
|
72
|
+
is the only place a secret can actually be captured. **Without `watch`, Stopgate
|
|
73
|
+
can only judge one action at a time and cross-call exfiltration is not detected.**
|
|
74
|
+
With it, "read the `.env` at step 3, POST it to an unknown host at step 19" is
|
|
75
|
+
caught — the payload at step 19 looks innocent on its own.
|
|
76
|
+
|
|
77
|
+
### Modes
|
|
78
|
+
|
|
79
|
+
| Mode | Behaviour | Use it when |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| `observe` | Scores and logs everything, **always allows**. Cannot stall an agent. | You're building trust, or the agent runs unattended and must never block. |
|
|
82
|
+
| `enforce` *(default)* | A hard-stop surfaces to you as an **ask**. Everything else auto-approves. | You're at the keyboard. |
|
|
83
|
+
| `enforce --headless` | A hard-stop **denies** instead of asking. | Nobody is there — an "ask" nobody answers is a hang, not a guardrail. |
|
|
84
|
+
|
|
85
|
+
Set with `--mode`, or `$STOPGATE_MODE`, or a `~/.stopgate-mode` file.
|
|
86
|
+
|
|
87
|
+
**Kill switch:** `echo observe > ~/.stopgate-mode` — instantly back to logging-only,
|
|
88
|
+
no restart, no config edit.
|
|
89
|
+
|
|
90
|
+
### What it never does
|
|
91
|
+
|
|
92
|
+
Stopgate **never writes your secrets to disk.** Session state holds only rolling-hash
|
|
93
|
+
fingerprints and salted hashes — enough to recognise those bytes trying to leave,
|
|
94
|
+
not enough to reconstruct them. A stolen state file yields nothing. (State lives in
|
|
95
|
+
`~/.cache/stopgate/sessions`, mode `0600`, expires after 7 days.)
|
|
96
|
+
|
|
97
|
+
It also **fails open, on purpose**: if Stopgate itself errors, the tool call is
|
|
98
|
+
allowed and the error is logged. A broken guardrail must never brick the agent it
|
|
99
|
+
is watching. That is a deliberate trade-off, and it is the honest one to state:
|
|
100
|
+
**Stopgate is a safety net, not a guarantee.** It can miss things. Do not use it as
|
|
101
|
+
the only thing standing between an agent and something you cannot undo.
|
|
102
|
+
|
|
103
|
+
## Our promises
|
|
104
|
+
|
|
105
|
+
These are commitments, not features. They're the reason you can trust a security tool you didn't write.
|
|
106
|
+
|
|
107
|
+
**1. We will never phone home.** Zero telemetry, zero analytics, no network calls of Stopgate's own — ever. A security tool that exfiltrates your data to prove nothing is exfiltrating your data is a joke. The code is MIT; verify it.
|
|
108
|
+
|
|
109
|
+
**2. We publish our false-alarm rate every release.** Not our catch rate — anyone can catch everything by blocking everything. The number that matters is **how often we interrupt you for nothing**, and we print it whether it's good or bad. I haven't found another installable agent guardrail that publishes its false-alarm rate on a controlled set — if you know one, tell me and I'll link it.
|
|
110
|
+
|
|
111
|
+
**3. Sixty seconds or we failed.** Install to first insight with no config file, no policy language, no account. If you have to *learn* Stopgate before it helps you, we built it wrong.
|
|
112
|
+
|
|
113
|
+
**4. Some things always stop for a human.** Money moving, production, anything irreversible — those wake you up no matter what your policy says. No "trust level" will ever override that. If a tool offers to fully automate spending your money, close the tab.
|
|
114
|
+
|
|
115
|
+
**5. We tell you what we can't do.** (See below — it stays in the README, permanently.)
|
|
116
|
+
|
|
117
|
+
**6. We'll never ship an attack to sell the defense.** Our demos use dummy canaries and local sinks. We don't publish weapons.
|
|
118
|
+
|
|
119
|
+
**7. Free, MIT, forever.** And the benchmark we grade ourselves with is public — run it against us, and against everyone else.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
## ⚠ Disclaimer
|
|
125
|
+
|
|
126
|
+
**Stopgate is best-effort and will make mistakes.** It can miss real attacks and flag safe
|
|
127
|
+
actions. It is **not a guarantee of safety**, not a substitute for code review or OS
|
|
128
|
+
sandboxing, and is provided **AS IS with no warranty** (MIT). Benchmark numbers come from a
|
|
129
|
+
small, non-human-audited seed set and are indicative, not definitive. **You are responsible
|
|
130
|
+
for what your agent does.** Full text: [DISCLAIMER.md](DISCLAIMER.md).
|
|
131
|
+
|
|
132
|
+
## What Stopgate does NOT catch
|
|
133
|
+
|
|
134
|
+
A security tool that overclaims is worse than none. Stopgate sees **actions, not thoughts.**
|
|
135
|
+
|
|
136
|
+
- **A genuinely malicious model with a covert channel.** If the model is the adversary and hides intent in benign-looking actions, Stopgate can't read its mind.
|
|
137
|
+
- **Anything outside the tool-call boundary.** If it doesn't go through a tool call Stopgate can see, Stopgate can't see it.
|
|
138
|
+
- **The "acted after untrusted content" signal is a temporal-proximity heuristic, not true taint.** We can't see which datum actually influenced the model, so we flag high-risk actions within N steps of an untrusted read — with confidence that **decays** with distance and is **evadable** by simply spacing the action out past the window.
|
|
139
|
+
- **Injection-provenance without secret egress.** A benign-*looking* action an agent runs because untrusted content told it to (no secret leaving) scores at **chance** in our own benchmark — Stopgate ties the keyword baseline there. Stopgate's real dataflow edge is secret-**egress**, not injection-provenance. We publish this miss (see `stopgate eval`).
|
|
140
|
+
- **Transformed exfil.** Byte-matching catches naive/base64/hex copies of a secret; gzip, encryption, or having the model paraphrase the secret defeat it. A competent adversary can get data out. It raises the cost; it is not a wall.
|
|
141
|
+
- **Anything not routed through the adapter** — a subprocess the agent spawns, network made from inside a tool's own code, or an MCP server talked to out-of-band — is invisible.
|
|
142
|
+
- **Closed chat UIs** (ChatGPT / Claude web). There's no interception point.
|
|
143
|
+
- **It is not a substitute for OS-level sandboxing.** Run untrusted agents in a container/VM. Stopgate is a layer on top, not a replacement.
|
|
144
|
+
|
|
145
|
+
Stopgate **reduces babysitting; it does not eliminate risk.**
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Status
|
|
150
|
+
|
|
151
|
+
**Shipped (local, verified):**
|
|
152
|
+
- `stopgate report` — read-only, zero-config: what your agent has been doing.
|
|
153
|
+
- `stopgate digest` — the session receipt: what was let through and *why it was safe*.
|
|
154
|
+
- `stopgate learn` — writes an editable allow-policy from your own sessions (opt-in tuning).
|
|
155
|
+
- `stopgate run` — unattended supervision: **auto-approve in-policy, hard-stop the irreversible.** Money, production, destructive, sign-in, install, and any secret leaving the machine always stop for a human — no policy can override that.
|
|
156
|
+
- `stopgate hook` — the live Claude Code PreToolUse gate (returns allow / ask per tool call).
|
|
157
|
+
|
|
158
|
+
**Next:** `stopgate eval` — the public precision benchmark (false alarms per 1,000 actions).
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT. Local-first. No network calls of its own.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "stopgate"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Stop watching your agent. A local-first safety envelope that lets you run coding agents unattended."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Rohan Kaila" }]
|
|
13
|
+
keywords = ["ai", "agent", "security", "guardrail", "claude", "prompt-injection", "taint", "dataflow"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Topic :: Security",
|
|
18
|
+
"Environment :: Console",
|
|
19
|
+
]
|
|
20
|
+
# Deliberately ZERO runtime dependencies. Stopgate makes no network calls of its own
|
|
21
|
+
# and pulls in nothing that could. Standard library only. (Promise #1.)
|
|
22
|
+
dependencies = []
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://github.com/Robomba/stopgate"
|
|
26
|
+
Source = "https://github.com/Robomba/stopgate"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
stopgate = "stopgate.cli:main"
|
|
30
|
+
|
|
31
|
+
[tool.setuptools.packages.find]
|
|
32
|
+
where = ["src"]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.package-data]
|
|
35
|
+
stopgate = ["data/*.jsonl"]
|
stopgate-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""Stopgate — stop watching your agent.
|
|
2
|
+
|
|
3
|
+
A local-first safety envelope for coding agents. Detection is by PROVENANCE and
|
|
4
|
+
DATAFLOW, never keywords: every tool result is tagged trusted/untrusted, an
|
|
5
|
+
untrusted read taints the session, high-risk actions near untrusted content
|
|
6
|
+
escalate, and outbound bytes are matched (by rolling hash) against secrets read
|
|
7
|
+
earlier in the session.
|
|
8
|
+
|
|
9
|
+
Stopgate makes zero network calls of its own. Standard library only.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
__version__ = "0.1.0"
|