diff --git a/CLAUDE.md b/CLAUDE.md index 74f5e80..1bd34ff 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,6 +16,10 @@ topp-nivå wiring, showcase + korpus), inkl. OKF-adapter og aktivt-innhold- detektor (EchoLeak-klassen) i output-gaten. Mode-b `import_bundle` skanner reserverte strukturfiler (`index.md`/`log.md`) i mottatte bundles i stedet for å path-avvise dem; upload-front-end beholder shadow-reject (`allow_reserved=False`). +Output-gatens decode-and-rescan mater dekodet base64-klartekst gjennom BÅDE lexicon +og secret-egress (LLM02), så en base64-innpakket credential fanges som +`decoded:egress:*` i stedet for å forsvinne; hex-innpakket er en dokumentert +restgap (entropy eksponerer kun base64-klartekst). Start med `docs/BRIEF.md` for design, `README.md` for bruk, `docs/PLAN.md` for byggerekkefølgen. diff --git a/README.md b/README.md index cabb543..3f877e3 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,12 @@ that a green scan means safe content: collapses to one finding at its first location. This keeps reports readable, but a caller that counts occurrences or needs every offset of a repeated pattern sees only the first: a deliberate readability tradeoff, not full positional coverage. +- **Secret egress: base64-wrapped is caught, hex-wrapped is not.** The output gate + decodes base64 blobs and re-scans the plaintext through the credential/egress set, + so a base64-*wrapped* secret surfaces as `decoded:egress:*` rather than vanishing. + A *hex*-wrapped secret does not: `entropy` exposes decoded plaintext for base64 + only, so hex (and other encodings, or nested wraps) is a deliberate boundary, not + a silent miss — decode the transport layer first if you need it scanned. ## Out-of-scope (documented boundary) diff --git a/src/llm_ingestion_guard/output.py b/src/llm_ingestion_guard/output.py index 9f4de2d..28981b1 100644 --- a/src/llm_ingestion_guard/output.py +++ b/src/llm_ingestion_guard/output.py @@ -15,12 +15,13 @@ input-side scanners do not cover: 2. :func:`~llm_ingestion_guard.entropy.scan_entropy` over the output — encoded / high-entropy carrier blobs. 3. **Decode-and-rescan** — every base64 blob ``entropy`` decoded to printable - text is fed back through ``scan_lexicon``. This is what turns "a blob is - present" into "an injection is hidden *inside* this blob". Findings from the - decoded plaintext are re-labelled ``decoded: