Metadata-Version: 2.4
Name: eucompliance-redact
Version: 0.1.0
Summary: Strip personal data and credentials from prompts before they reach a model - locally, with a signed record that you did
Project-URL: Homepage, https://eucompliance.tools
Project-URL: Verify, https://eucompliance.tools/verify
Author: Patrick Kaufmann
License: MIT
Keywords: anthropic,compliance,data-protection,gdpr,llm,openai,pii,privacy,prompt,redaction,secrets
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# eucompliance-redact

**Strip personal data and credentials from prompts before they reach a model — locally, with a signed record that you did.**

Every prompt you send to a hosted model is a transfer to a processor. If it contains a customer address, an IBAN or an API key, that is a disclosure under **GDPR Art. 28** — and, for providers outside the EU, **Art. 44**. The obligation is not politeness, it is liability.

```bash
pip install eucompliance-redact
```

```python
from eucompliance_redact import redact

clean = redact(prompt)
answer = model(clean.text)        # only placeholders left
print(clean.restore(answer))      # placeholders put back
```

No dependencies. No network calls. Nothing to configure.

## Or wrap the client once

```python
from eucompliance_redact import wrap
from openai import OpenAI

client = wrap(OpenAI())
client.chat.completions.create(model="gpt-4o", messages=[...])
```

Prompts are redacted on the way out and the answer is translated back on the way in, so your users never see a placeholder. If anything in this library fails, the call goes through unchanged — a safeguard that stops production gets switched off.

## What it finds

Private keys · AWS keys · GitHub tokens · OpenAI and Anthropic keys · Slack tokens · JWTs · credentials embedded in URLs · IBANs (checksum-verified) · payment cards (Luhn-verified) · e-mail addresses · VAT IDs · IP addresses.

Phone numbers are **off by default**: almost any long digit sequence looks like one, and invoice numbers are the usual casualty. Enable with `include_unsafe=True`.

```python
redact(text, skip=["IPV4"])            # leave internal addresses alone
redact(text, kinds=["IBAN", "EMAIL"])  # only these
```

## What it does not find — read this part

This is pattern matching. It finds what has **structure**: a checksum, a prefix, a shape. It does **not** find a person's name sitting in ordinary prose, a street address written out in words, or a medical detail described in a sentence. No amount of regular expressions will, and a library that claims otherwise is more dangerous than no library at all, because you would stop looking.

Use it to remove the leaks that are mechanical and constant. Do not use it as your only control over what goes into a prompt.

## Placeholders are stable

The same value becomes the same placeholder everywhere in the text, so the model can still tell that two mentions are the same person:

```python
r = redact("a@x.at wrote to b@y.at, then a@x.at again")
r.text
# '[EMAIL_1] wrote to [EMAIL_2], then [EMAIL_1] again'
r.count      # 3 occurrences
len(r.mapping)  # 2 distinct values
```

## Proving you did it

Redaction that nobody can verify is worth little in an audit. `receipt()` returns a signed record of **that** redaction happened — how many values of which kinds, and the hashes before and after:

```python
from eucompliance_redact import receipt

r = redact(prompt)
record = receipt(r, controller="Your Company GmbH", processor="OpenAI")
```

Only the two hashes and the per-kind counts are transmitted. Not one redacted value, not one line of the prompt. The record is signed with EIP-191 and verifiable by anyone, free and without an account — at [eucompliance.tools/verify](https://eucompliance.tools/verify).

This is the only part that touches the network, and it is optional. Without it, the package is fully offline.

## What the record proves

**Proves:** that a text with this hash was reduced to a text with that hash, removing this many values of these kinds, at this time, attested by this controller.

**Does not prove:** that nothing sensitive remained. See the section above. It is evidence of a control being applied, not a guarantee of the result.

Not legal advice. Whether your processing is lawful remains your assessment.

## Related

- [`eucompliance-ai-act`](https://pypi.org/project/eucompliance-ai-act/) — EU AI Act Article 50 disclosure, same design: local hashing, signed record.
- [`eucompliance-tools`](https://pypi.org/project/eucompliance-tools/) — VAT, IBAN, sanctions screening and more.

MIT licensed. Operated by Patrick Kaufmann, sole proprietor in Vienna, Austria.
