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.
Files changed (29) hide show
  1. {guardkit-0.2.0 → guardkit-0.3.0}/PKG-INFO +32 -1
  2. {guardkit-0.2.0 → guardkit-0.3.0}/README.md +31 -0
  3. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/__init__.py +1 -1
  4. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/classifier.py +4 -3
  5. guardkit-0.3.0/guardkit/data/jailbreak_lr.json +1 -0
  6. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/injection.py +5 -3
  7. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/PKG-INFO +32 -1
  8. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/SOURCES.txt +1 -0
  9. {guardkit-0.2.0 → guardkit-0.3.0}/pyproject.toml +1 -1
  10. {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_injection.py +6 -0
  11. {guardkit-0.2.0 → guardkit-0.3.0}/LICENSE +0 -0
  12. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/cli.py +0 -0
  13. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/content.py +0 -0
  14. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/core.py +0 -0
  15. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/data/injection_lr.json +0 -0
  16. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/pii.py +0 -0
  17. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/pipeline.py +0 -0
  18. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/policy.py +0 -0
  19. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/secrets.py +0 -0
  20. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit/server.py +0 -0
  21. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/dependency_links.txt +0 -0
  22. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/entry_points.txt +0 -0
  23. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/requires.txt +0 -0
  24. {guardkit-0.2.0 → guardkit-0.3.0}/guardkit.egg-info/top_level.txt +0 -0
  25. {guardkit-0.2.0 → guardkit-0.3.0}/setup.cfg +0 -0
  26. {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_pii.py +0 -0
  27. {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_pipeline.py +0 -0
  28. {guardkit-0.2.0 → guardkit-0.3.0}/tests/test_secrets.py +0 -0
  29. {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.2.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.2.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", "injection_lr.json")
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