guardkit 0.2.0__tar.gz → 0.3.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.
- {guardkit-0.2.0 → guardkit-0.3.0}/PKG-INFO +32 -1
- {guardkit-0.2.0 → guardkit-0.3.0}/README.md +31 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/__init__.py +1 -1
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/classifier.py +4 -3
- guardkit-0.3.0/guardkit/data/jailbreak_lr.json +1 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/injection.py +5 -3
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/PKG-INFO +32 -1
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/SOURCES.txt +1 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/pyproject.toml +1 -1
- {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_injection.py +6 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/LICENSE +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/cli.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/content.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/core.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/data/injection_lr.json +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/pii.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/pipeline.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/policy.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/secrets.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/server.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/dependency_links.txt +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/entry_points.txt +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/requires.txt +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/top_level.txt +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/setup.cfg +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_pii.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_pipeline.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_secrets.py +0 -0
- {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: guardkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Offline guardrails for LLM apps: PII (incl. Aadhaar/PAN), secrets, prompt-injection classifier + rules, policy YAML, CLI
|
|
5
5
|
Author: Ashish Dhillon
|
|
6
6
|
License: MIT
|
|
@@ -96,6 +96,30 @@ at roughly 6% false alarms among flagged items, and it was trained on synthetic
|
|
|
96
96
|
adversarial traffic. Use it as one cheap layer, not as your only defence. Retrain with your
|
|
97
97
|
own labelled data via `scripts/train_injection.py`.
|
|
98
98
|
|
|
99
|
+
## External evaluation (in-the-wild jailbreaks)
|
|
100
|
+
|
|
101
|
+
The author-written sets above flatter the detector. On the public in-the-wild jailbreak
|
|
102
|
+
dataset (Shen et al., CCS 2024; 1,405 jailbreak and 13,735 regular prompts) results are much
|
|
103
|
+
weaker. `InjectionGuard(model="jailbreak")` is a second classifier trained on the earlier
|
|
104
|
+
~65% of that data (temporal split, near-duplicates removed) and tested on the later part
|
|
105
|
+
(5,497 prompts, 398 jailbreaks):
|
|
106
|
+
|
|
107
|
+
| Detector | Recall | False-positive rate | Precision (7% prevalence) |
|
|
108
|
+
|---|---|---|---|
|
|
109
|
+
| regex rules | 0.05 | 0.026 | 0.13 |
|
|
110
|
+
| jailbreak classifier, threshold 0.5 | 0.42 | 0.126 | 0.21 |
|
|
111
|
+
| jailbreak classifier, threshold at 1% FPR on training negatives | 0.20 | 0.033 | 0.33 |
|
|
112
|
+
|
|
113
|
+
Classifier AUC is 0.74. The default `model="injection"` classifier (synthetic training) is
|
|
114
|
+
weaker still on this data (recall 0.31, FPR 0.12 zero-shot). Do not rely on guardkit's
|
|
115
|
+
injection detection as a primary defence for user prompts. A full write-up is in
|
|
116
|
+
`docs/technical-report.md`. Reproduce with `scripts/train_jailbreak.py` and
|
|
117
|
+
`scripts/eval_external.py` (download the two CSVs from github.com/verazuo/jailbreak_llms).
|
|
118
|
+
|
|
119
|
+
PII checksums: random 12-digit strings pass Verhoeff 9.9% of the time and random 16-digit strings
|
|
120
|
+
pass Luhn 10.0% of the time, so checksum validation removes about 90% of numeric false
|
|
121
|
+
positives. On 15,140 real prompts, 166 card-shaped digit strings shrank to 9 after Luhn.
|
|
122
|
+
|
|
99
123
|
## Honest limitations
|
|
100
124
|
|
|
101
125
|
- Injection detection is statistical plus rules; a determined attacker can paraphrase around
|
|
@@ -106,6 +130,13 @@ own labelled data via `scripts/train_injection.py`.
|
|
|
106
130
|
- The classifier was trained on synthetic data and evaluated on author-written examples.
|
|
107
131
|
- The bundled HTTP service has no authentication or TLS. Run it behind your own gateway.
|
|
108
132
|
|
|
133
|
+
## Related projects
|
|
134
|
+
|
|
135
|
+
- [injection-bench](https://github.com/ashishdhillon/injection-bench): leakage-controlled benchmark that scored this
|
|
136
|
+
detector (`guardkit:rules`, `guardkit:model`) against baselines on real data.
|
|
137
|
+
- [bharatid](https://github.com/ashishdhillon/bharatid): deeper Indian-ID validators (GSTIN, TAN, vehicle plates and more)
|
|
138
|
+
than the PII guard here.
|
|
139
|
+
|
|
109
140
|
## Develop
|
|
110
141
|
|
|
111
142
|
```bash
|
|
@@ -77,6 +77,30 @@ at roughly 6% false alarms among flagged items, and it was trained on synthetic
|
|
|
77
77
|
adversarial traffic. Use it as one cheap layer, not as your only defence. Retrain with your
|
|
78
78
|
own labelled data via `scripts/train_injection.py`.
|
|
79
79
|
|
|
80
|
+
## External evaluation (in-the-wild jailbreaks)
|
|
81
|
+
|
|
82
|
+
The author-written sets above flatter the detector. On the public in-the-wild jailbreak
|
|
83
|
+
dataset (Shen et al., CCS 2024; 1,405 jailbreak and 13,735 regular prompts) results are much
|
|
84
|
+
weaker. `InjectionGuard(model="jailbreak")` is a second classifier trained on the earlier
|
|
85
|
+
~65% of that data (temporal split, near-duplicates removed) and tested on the later part
|
|
86
|
+
(5,497 prompts, 398 jailbreaks):
|
|
87
|
+
|
|
88
|
+
| Detector | Recall | False-positive rate | Precision (7% prevalence) |
|
|
89
|
+
|---|---|---|---|
|
|
90
|
+
| regex rules | 0.05 | 0.026 | 0.13 |
|
|
91
|
+
| jailbreak classifier, threshold 0.5 | 0.42 | 0.126 | 0.21 |
|
|
92
|
+
| jailbreak classifier, threshold at 1% FPR on training negatives | 0.20 | 0.033 | 0.33 |
|
|
93
|
+
|
|
94
|
+
Classifier AUC is 0.74. The default `model="injection"` classifier (synthetic training) is
|
|
95
|
+
weaker still on this data (recall 0.31, FPR 0.12 zero-shot). Do not rely on guardkit's
|
|
96
|
+
injection detection as a primary defence for user prompts. A full write-up is in
|
|
97
|
+
`docs/technical-report.md`. Reproduce with `scripts/train_jailbreak.py` and
|
|
98
|
+
`scripts/eval_external.py` (download the two CSVs from github.com/verazuo/jailbreak_llms).
|
|
99
|
+
|
|
100
|
+
PII checksums: random 12-digit strings pass Verhoeff 9.9% of the time and random 16-digit strings
|
|
101
|
+
pass Luhn 10.0% of the time, so checksum validation removes about 90% of numeric false
|
|
102
|
+
positives. On 15,140 real prompts, 166 card-shaped digit strings shrank to 9 after Luhn.
|
|
103
|
+
|
|
80
104
|
## Honest limitations
|
|
81
105
|
|
|
82
106
|
- Injection detection is statistical plus rules; a determined attacker can paraphrase around
|
|
@@ -87,6 +111,13 @@ own labelled data via `scripts/train_injection.py`.
|
|
|
87
111
|
- The classifier was trained on synthetic data and evaluated on author-written examples.
|
|
88
112
|
- The bundled HTTP service has no authentication or TLS. Run it behind your own gateway.
|
|
89
113
|
|
|
114
|
+
## Related projects
|
|
115
|
+
|
|
116
|
+
- [injection-bench](https://github.com/ashishdhillon/injection-bench): leakage-controlled benchmark that scored this
|
|
117
|
+
detector (`guardkit:rules`, `guardkit:model`) against baselines on real data.
|
|
118
|
+
- [bharatid](https://github.com/ashishdhillon/bharatid): deeper Indian-ID validators (GSTIN, TAN, vehicle plates and more)
|
|
119
|
+
than the PII guard here.
|
|
120
|
+
|
|
90
121
|
## Develop
|
|
91
122
|
|
|
92
123
|
```bash
|
|
@@ -7,6 +7,6 @@ from .secrets import SecretsGuard
|
|
|
7
7
|
from .injection import InjectionGuard
|
|
8
8
|
from .content import TopicGuard, JSONGuard
|
|
9
9
|
|
|
10
|
-
__version__ = "0.
|
|
10
|
+
__version__ = "0.3.0"
|
|
11
11
|
__all__ = ["Finding", "Guard", "Result", "Pipeline", "Stage", "from_dict", "load",
|
|
12
12
|
"PIIGuard", "SecretsGuard", "InjectionGuard", "TopicGuard", "JSONGuard"]
|
|
@@ -9,11 +9,12 @@ import zlib
|
|
|
9
9
|
from .injection import normalise
|
|
10
10
|
|
|
11
11
|
DIM = 1 << 16
|
|
12
|
+
MAX_CHARS = 4000
|
|
12
13
|
_TOK = re.compile(r"[^\W_]+(?:'[a-z]+)?", re.U)
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def featurize(text: str):
|
|
16
|
-
toks = _TOK.findall(normalise(text))
|
|
17
|
+
toks = _TOK.findall(normalise(text[:MAX_CHARS]))
|
|
17
18
|
feats = {}
|
|
18
19
|
grams = toks + [a + " " + b for a, b in zip(toks, toks[1:])]
|
|
19
20
|
for g in grams:
|
|
@@ -37,8 +38,8 @@ class LogReg:
|
|
|
37
38
|
json.dump({"dim": DIM, "b": self.b, "w": {str(k): round(v, 5) for k, v in self.w.items() if abs(v) > 1e-4}}, fh)
|
|
38
39
|
|
|
39
40
|
@classmethod
|
|
40
|
-
def load(cls, path=None):
|
|
41
|
-
path = path or os.path.join(os.path.dirname(__file__), "data", "
|
|
41
|
+
def load(cls, path=None, name="injection"):
|
|
42
|
+
path = path or os.path.join(os.path.dirname(__file__), "data", f"{name}_lr.json")
|
|
42
43
|
with open(path) as fh:
|
|
43
44
|
d = json.load(fh)
|
|
44
45
|
assert d["dim"] == DIM
|