gptme-redact 0.1.1__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.
- gptme_redact-0.1.1/.gitignore +43 -0
- gptme_redact-0.1.1/PKG-INFO +125 -0
- gptme_redact-0.1.1/README.md +113 -0
- gptme_redact-0.1.1/pyproject.toml +27 -0
- gptme_redact-0.1.1/src/redact/__init__.py +1071 -0
- gptme_redact-0.1.1/src/redact/canonicalize.py +343 -0
- gptme_redact-0.1.1/src/redact/cli.py +269 -0
- gptme_redact-0.1.1/src/redact/memory_boundary.py +576 -0
- gptme_redact-0.1.1/src/redact/py.typed +0 -0
- gptme_redact-0.1.1/src/redact/sanitize_document.py +301 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/README.md +54 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/verdict-spec.json +141 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/verdict-spec.md +125 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/workspace/cache/rag-results.md +9 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/workspace/conflicting-roots/project-layer.md +16 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/workspace/conflicting-roots/user-layer.md +18 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/workspace/project-memory/archive-policy.md +14 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/workspace/project-memory/core-goal.md +14 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/workspace/secrets-fixture.md +14 -0
- gptme_redact-0.1.1/tests/fixtures/memory-boundary-auditor/workspace/transcript-snippet.md +5 -0
- gptme_redact-0.1.1/tests/test_assignment_followup_regressions.py +79 -0
- gptme_redact-0.1.1/tests/test_credential_review_regressions.py +80 -0
- gptme_redact-0.1.1/tests/test_latest_review_regressions.py +144 -0
- gptme_redact-0.1.1/tests/test_memory_boundary.py +435 -0
- gptme_redact-0.1.1/tests/test_multiline_json_assignments.py +47 -0
- gptme_redact-0.1.1/tests/test_redact.py +1301 -0
- gptme_redact-0.1.1/tests/test_remaining_bypasses.py +137 -0
- gptme_redact-0.1.1/tests/test_review_regressions.py +195 -0
- gptme_redact-0.1.1/tests/test_sanitize_document.py +359 -0
- gptme_redact-0.1.1/tests/test_span_review_regressions.py +105 -0
- gptme_redact-0.1.1/tests/test_unicode_injection.py +492 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
*.pyc
|
|
2
|
+
__pycache__
|
|
3
|
+
*.egg-info
|
|
4
|
+
.mypy_cache
|
|
5
|
+
.pytest_cache
|
|
6
|
+
.ruff_cache
|
|
7
|
+
|
|
8
|
+
# Python build artifacts
|
|
9
|
+
build/
|
|
10
|
+
dist/
|
|
11
|
+
|
|
12
|
+
# Secrets - never commit
|
|
13
|
+
scripts/discord/logs/*
|
|
14
|
+
scripts/*/.env
|
|
15
|
+
scripts/*/.oauth-state
|
|
16
|
+
scripts/*/.tokens.json
|
|
17
|
+
scripts/.env
|
|
18
|
+
*.oauth-state
|
|
19
|
+
*.tokens.json
|
|
20
|
+
# Per-agent identity allowlist written by dotfiles/install.sh. It carries a
|
|
21
|
+
# machine-specific git identity and must never be committed from a checkout
|
|
22
|
+
# whose ~/.config is symlinked into this tree.
|
|
23
|
+
dotfiles/.config/git/allowed-identities.conf
|
|
24
|
+
|
|
25
|
+
.venv/
|
|
26
|
+
venv/
|
|
27
|
+
.gptme/
|
|
28
|
+
|
|
29
|
+
# Community plugins index (generated artifact — do not commit snapshots)
|
|
30
|
+
state/community_plugins.json
|
|
31
|
+
docs/community_plugins.json
|
|
32
|
+
|
|
33
|
+
# Task lock files (runtime state)
|
|
34
|
+
state/locks/
|
|
35
|
+
|
|
36
|
+
# Session state files (runtime state)
|
|
37
|
+
state/sessions/
|
|
38
|
+
|
|
39
|
+
# Stale directory from tasks->gptodo rename (PR #171)
|
|
40
|
+
packages/tasks/
|
|
41
|
+
|
|
42
|
+
# Dashboard build output
|
|
43
|
+
_site/
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: gptme-redact
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Secret-safe export redactor — layered fail-closed redaction for derived agent content
|
|
5
|
+
Project-URL: Homepage, https://github.com/gptme/gptme-contrib
|
|
6
|
+
Project-URL: Repository, https://github.com/gptme/gptme-contrib
|
|
7
|
+
Project-URL: Issues, https://github.com/gptme/gptme-contrib/issues
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Provides-Extra: test
|
|
10
|
+
Requires-Dist: pytest>=7.0; extra == 'test'
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# gptme-redact
|
|
14
|
+
|
|
15
|
+
Secret-safe export redactor — layered, fail-closed redaction for publishing derived agent content safely.
|
|
16
|
+
|
|
17
|
+
**Distribution name:** `gptme-redact`. **Import module:** `redact`. The
|
|
18
|
+
distribution is renamed because PyPI `redact` 0.1.1 is an unrelated
|
|
19
|
+
config-template renderer; importing `redact` still works, so a bare
|
|
20
|
+
`redact` requirement is a trap that resolves to the wrong project.
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
uv tool install gptme-redact # provides the `redact` CLI
|
|
24
|
+
uv pip install "gptmail[secrets]" # gptmail's outbound scanner extra
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## What it does
|
|
28
|
+
|
|
29
|
+
A six-layer redaction pipeline that blocks artifacts containing secrets before they leave the agent workspace. Fail-closed: any finding at the blocking severity (default: `critical`) rejects the whole artifact rather than silently redacting it.
|
|
30
|
+
|
|
31
|
+
| Layer | What | Mechanism |
|
|
32
|
+
|-------|------|-----------|
|
|
33
|
+
| 1. Deterministic | Strip exact secrets | Env values + explicit literals |
|
|
34
|
+
| 2. Pattern | Regex deny-list | Built-in patterns for API keys, tokens, URLs |
|
|
35
|
+
| 3. TruffleHog | Optional binary scan | `trufflehog filesystem` integration |
|
|
36
|
+
| 4. LLM review | Judge safety | *(external, not in this package)* |
|
|
37
|
+
| 5. Human gate | Report / reject | `--report` mode + fail-closed exit |
|
|
38
|
+
| 6. Prompt-injection | Detect injection surfaces | Advisory scan in untrusted text |
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# Redact a file (blocking on critical findings)
|
|
44
|
+
redact my-file.md
|
|
45
|
+
|
|
46
|
+
# Report mode — see what would be redacted without writing
|
|
47
|
+
redact my-file.md --report
|
|
48
|
+
|
|
49
|
+
# Machine-readable report (for tooling)
|
|
50
|
+
redact my-file.md --json
|
|
51
|
+
|
|
52
|
+
# Add extra literals and run TruffleHog scan
|
|
53
|
+
redact my-file.md --literal "my-secret-token" --trufflehog
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
```txt
|
|
59
|
+
usage: redact [-h] [--out OUT] [--report] [--json] [--literal LITERAL]
|
|
60
|
+
[--allowlist ALLOWLIST] [--no-default-allowlist]
|
|
61
|
+
[--trufflehog] [--scan-injection]
|
|
62
|
+
[--block-severity BLOCK_SEVERITY] [--no-env-secrets]
|
|
63
|
+
file
|
|
64
|
+
|
|
65
|
+
positional arguments:
|
|
66
|
+
file file to redact (use - for stdin)
|
|
67
|
+
|
|
68
|
+
options:
|
|
69
|
+
--out OUT write redacted text here
|
|
70
|
+
--report print findings report instead of redacted text
|
|
71
|
+
--json machine-readable report (implies --report)
|
|
72
|
+
--literal LITERAL extra literal secret to redact (repeatable)
|
|
73
|
+
--allowlist ALLOWLIST
|
|
74
|
+
exempt exact literal from non-critical redaction
|
|
75
|
+
--no-default-allowlist
|
|
76
|
+
skip the built-in known-public allowlist
|
|
77
|
+
--trufflehog enable layer 3 TruffleHog scanning
|
|
78
|
+
--scan-injection enable layer 6 prompt-injection surface scan
|
|
79
|
+
--block-severity minimum severity that blocks (default: critical)
|
|
80
|
+
--no-env-secrets skip env-value redaction (deterministic mode)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Python API
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from redact import redact, collect_secret_literals, Result, Severity
|
|
87
|
+
|
|
88
|
+
result = redact(
|
|
89
|
+
text="my API key is sk-ant-api...",
|
|
90
|
+
literals=collect_secret_literals(), # auto-collects env vars
|
|
91
|
+
allowlist=["https://example.com/public-endpoint"],
|
|
92
|
+
block_severity=Severity.CRITICAL,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
if result.blocked:
|
|
96
|
+
print("Blocked:", result.block_reasons)
|
|
97
|
+
else:
|
|
98
|
+
print(result.redacted)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Prompt-Injection Scan
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from redact import scan_prompt_injection
|
|
105
|
+
|
|
106
|
+
findings = scan_prompt_injection(untrusted_user_text)
|
|
107
|
+
# [Finding(category="injection:system_override", severity=Severity.HIGH, ...)]
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The injection scan is advisory — it flags suspicious content without modifying the text. Use it as a preflight gate before feeding scraped or user-supplied text into an LLM context.
|
|
111
|
+
|
|
112
|
+
## Development
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Run tests
|
|
116
|
+
uv run pytest packages/gptme-redact/tests/ -v
|
|
117
|
+
|
|
118
|
+
# Run CLI on a test file
|
|
119
|
+
uv run python3 -m redact.cli path/to/file.md --report
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Related
|
|
123
|
+
|
|
124
|
+
- [Idea backlog entry #362](https://github.com/ErikBjare/bob/issues/362) — original design
|
|
125
|
+
- `knowledge/processes/fail-closed-redaction.md` — operational guide
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# gptme-redact
|
|
2
|
+
|
|
3
|
+
Secret-safe export redactor — layered, fail-closed redaction for publishing derived agent content safely.
|
|
4
|
+
|
|
5
|
+
**Distribution name:** `gptme-redact`. **Import module:** `redact`. The
|
|
6
|
+
distribution is renamed because PyPI `redact` 0.1.1 is an unrelated
|
|
7
|
+
config-template renderer; importing `redact` still works, so a bare
|
|
8
|
+
`redact` requirement is a trap that resolves to the wrong project.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
uv tool install gptme-redact # provides the `redact` CLI
|
|
12
|
+
uv pip install "gptmail[secrets]" # gptmail's outbound scanner extra
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## What it does
|
|
16
|
+
|
|
17
|
+
A six-layer redaction pipeline that blocks artifacts containing secrets before they leave the agent workspace. Fail-closed: any finding at the blocking severity (default: `critical`) rejects the whole artifact rather than silently redacting it.
|
|
18
|
+
|
|
19
|
+
| Layer | What | Mechanism |
|
|
20
|
+
|-------|------|-----------|
|
|
21
|
+
| 1. Deterministic | Strip exact secrets | Env values + explicit literals |
|
|
22
|
+
| 2. Pattern | Regex deny-list | Built-in patterns for API keys, tokens, URLs |
|
|
23
|
+
| 3. TruffleHog | Optional binary scan | `trufflehog filesystem` integration |
|
|
24
|
+
| 4. LLM review | Judge safety | *(external, not in this package)* |
|
|
25
|
+
| 5. Human gate | Report / reject | `--report` mode + fail-closed exit |
|
|
26
|
+
| 6. Prompt-injection | Detect injection surfaces | Advisory scan in untrusted text |
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Redact a file (blocking on critical findings)
|
|
32
|
+
redact my-file.md
|
|
33
|
+
|
|
34
|
+
# Report mode — see what would be redacted without writing
|
|
35
|
+
redact my-file.md --report
|
|
36
|
+
|
|
37
|
+
# Machine-readable report (for tooling)
|
|
38
|
+
redact my-file.md --json
|
|
39
|
+
|
|
40
|
+
# Add extra literals and run TruffleHog scan
|
|
41
|
+
redact my-file.md --literal "my-secret-token" --trufflehog
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage
|
|
45
|
+
|
|
46
|
+
```txt
|
|
47
|
+
usage: redact [-h] [--out OUT] [--report] [--json] [--literal LITERAL]
|
|
48
|
+
[--allowlist ALLOWLIST] [--no-default-allowlist]
|
|
49
|
+
[--trufflehog] [--scan-injection]
|
|
50
|
+
[--block-severity BLOCK_SEVERITY] [--no-env-secrets]
|
|
51
|
+
file
|
|
52
|
+
|
|
53
|
+
positional arguments:
|
|
54
|
+
file file to redact (use - for stdin)
|
|
55
|
+
|
|
56
|
+
options:
|
|
57
|
+
--out OUT write redacted text here
|
|
58
|
+
--report print findings report instead of redacted text
|
|
59
|
+
--json machine-readable report (implies --report)
|
|
60
|
+
--literal LITERAL extra literal secret to redact (repeatable)
|
|
61
|
+
--allowlist ALLOWLIST
|
|
62
|
+
exempt exact literal from non-critical redaction
|
|
63
|
+
--no-default-allowlist
|
|
64
|
+
skip the built-in known-public allowlist
|
|
65
|
+
--trufflehog enable layer 3 TruffleHog scanning
|
|
66
|
+
--scan-injection enable layer 6 prompt-injection surface scan
|
|
67
|
+
--block-severity minimum severity that blocks (default: critical)
|
|
68
|
+
--no-env-secrets skip env-value redaction (deterministic mode)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Python API
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from redact import redact, collect_secret_literals, Result, Severity
|
|
75
|
+
|
|
76
|
+
result = redact(
|
|
77
|
+
text="my API key is sk-ant-api...",
|
|
78
|
+
literals=collect_secret_literals(), # auto-collects env vars
|
|
79
|
+
allowlist=["https://example.com/public-endpoint"],
|
|
80
|
+
block_severity=Severity.CRITICAL,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
if result.blocked:
|
|
84
|
+
print("Blocked:", result.block_reasons)
|
|
85
|
+
else:
|
|
86
|
+
print(result.redacted)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Prompt-Injection Scan
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from redact import scan_prompt_injection
|
|
93
|
+
|
|
94
|
+
findings = scan_prompt_injection(untrusted_user_text)
|
|
95
|
+
# [Finding(category="injection:system_override", severity=Severity.HIGH, ...)]
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The injection scan is advisory — it flags suspicious content without modifying the text. Use it as a preflight gate before feeding scraped or user-supplied text into an LLM context.
|
|
99
|
+
|
|
100
|
+
## Development
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# Run tests
|
|
104
|
+
uv run pytest packages/gptme-redact/tests/ -v
|
|
105
|
+
|
|
106
|
+
# Run CLI on a test file
|
|
107
|
+
uv run python3 -m redact.cli path/to/file.md --report
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Related
|
|
111
|
+
|
|
112
|
+
- [Idea backlog entry #362](https://github.com/ErikBjare/bob/issues/362) — original design
|
|
113
|
+
- `knowledge/processes/fail-closed-redaction.md` — operational guide
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "gptme-redact"
|
|
3
|
+
version = "0.1.1"
|
|
4
|
+
description = "Secret-safe export redactor — layered fail-closed redaction for derived agent content"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = []
|
|
8
|
+
|
|
9
|
+
[project.scripts]
|
|
10
|
+
redact = "redact.cli:main"
|
|
11
|
+
|
|
12
|
+
[project.urls]
|
|
13
|
+
Homepage = "https://github.com/gptme/gptme-contrib"
|
|
14
|
+
Repository = "https://github.com/gptme/gptme-contrib"
|
|
15
|
+
Issues = "https://github.com/gptme/gptme-contrib/issues"
|
|
16
|
+
|
|
17
|
+
[project.optional-dependencies]
|
|
18
|
+
test = [
|
|
19
|
+
"pytest>=7.0",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
[build-system]
|
|
23
|
+
requires = ["hatchling"]
|
|
24
|
+
build-backend = "hatchling.build"
|
|
25
|
+
|
|
26
|
+
[tool.hatch.build.targets.wheel]
|
|
27
|
+
packages = ["src/redact"]
|