Deterministic Unicode-aware input hardening for LLM applications.
Project description
llm-input-hardening
Deterministic Unicode-aware input hardening for LLM applications.
llm-input-hardening sits between untrusted text and your prompt or template layer. It normalizes Unicode, removes invisible or control characters that destabilize prompts, emits structured reports for logging and enforcement, and can add confusable mixed-script signals when you want stricter checks.
It is not prompt injection prevention. It addresses text-integrity problems, not model intent.
This repository keeps docs intentionally lightweight. The README is the main reference.
Install
pip install llm-input-hardening
Optional extras:
pip install "llm-input-hardening[security]"for theconfusable_homoglyphsbackendpip install "llm-input-hardening[ftfy]"for pre-sanitize text repair
Rename Compatibility
The project was originally published as llm-input-harderning. The corrected
package is llm-input-hardening, with the canonical import path
llm_input_hardening.
The legacy llm_input_harderning import path remains available as a compatibility
shim for existing code, but new code should use llm_input_hardening.
For PyPI migration, publish the corrected package first, then publish the
compatibility meta-package in packaging/llm-input-harderning-shim so existing
pip install llm-input-harderning users are moved onto llm-input-hardening.
Quickstart
from llm_input_hardening import sanitize
clean_text, report = sanitize(user_text, policy="balanced_chat")
Recursive JSON sanitization:
from llm_input_hardening import sanitize_json
clean_payload, report = sanitize_json(payload, policy="balanced_chat")
Enforcement-oriented usage:
from llm_input_hardening import sanitize_and_decide
clean_text, report, decision = sanitize_and_decide(
user_text,
sanitize_policy="strict_exec",
confusables_backend="confusable_homoglyphs",
)
Policies
| Policy | Normalization | Default-Ignorables | Whitespace tidy | Typical use |
|---|---|---|---|---|
preserve |
NFC | preserve | no | low-friction logging and observability |
balanced_chat |
NFC | preserve | yes | general chat and prompt input |
strict_exec |
NFKC | strip | yes | tool arguments and execution-adjacent paths |
code_mode |
NFC | strip | no | code snippets and syntax-sensitive text |
Backward-compatible aliases are still accepted: balanced, strict, and code.
Scope
Use this library for:
- user text before prompt interpolation
- retrieved text before it reaches the model
- tool and function argument strings
- JSON payloads that contain prompt-bearing string leaves
Do not use it as a substitute for:
- system prompt design
- tool sandboxing and allowlists
- output validation
- human review for high-risk actions
CLI
llm-input-hardening sanitize --text "abcdef"
llm-input-hardening inspect --text "abcdef"
llm-input-hardening decide --text "abcdef"
Development
uv sync --all-extras
uv run maturin develop --release
uv run pytest -q
Benchmarks And Bakeoff
The repo has two different evaluation paths.
bench/run_benchmarks.pyis a timing harness. It measures sanitizer latency and throughput on fixed synthetic inputs.bench/run_bakeoff.pyis an evaluation harness. It runs labeled corpus cases, checks expected detections and postconditions, and computes precision, recall, benign-change rate, and stability signals.
Use the Make targets below:
make bench
make bench-plots
make bakeoff-smoke
make bakeoff-smoke-assert
make bakeoff-full
make bakeoff-full-assert
make bakeoff-diff
make bakeoff-diff-assert
What they mean:
bakeoff-smokeis the fast local check. It evaluates onlyllm-input-hardeningand writes results tobench/results/bakeoff_smoke_latest.json.bakeoff-fullis the heavyweight comparison run. It installsllm-guardandconfusable-homoglyphs, then writes comparable results tobench/results/bakeoff_latest.json.bakeoff-diffcompares the current full run tobench/results/bakeoff_baseline_v1.0.0.json.
Generated reports stay under bench/results/.
Repo Notes
CONTRIBUTING.mdcovers contribution mechanics.SECURITY.mdcovers reporting and threat assumptions.SCOPE.mdexplains what the project is and is not trying to solve.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file llm_input_hardening-1.1.0.tar.gz.
File metadata
- Download URL: llm_input_hardening-1.1.0.tar.gz
- Upload date:
- Size: 224.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02ebdc54ecb5d3ce1363991d4602a3f02134ca87e9c233b7935e2e76f155e479
|
|
| MD5 |
13abb06b1636306d1d8718742a3f37ff
|
|
| BLAKE2b-256 |
33e1d87d8f2f5876ed3915ad26f80fd4974d0faae4c17a34c5e47924b51fe373
|
Provenance
The following attestation bundles were made for llm_input_hardening-1.1.0.tar.gz:
Publisher:
release.yml on davidwebstar34/llm-input-hardening
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llm_input_hardening-1.1.0.tar.gz -
Subject digest:
02ebdc54ecb5d3ce1363991d4602a3f02134ca87e9c233b7935e2e76f155e479 - Sigstore transparency entry: 1390570628
- Sigstore integration time:
-
Permalink:
davidwebstar34/llm-input-hardening@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Branch / Tag:
refs/heads/main - Owner: https://github.com/davidwebstar34
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file llm_input_hardening-1.1.0-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: llm_input_hardening-1.1.0-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 275.2 kB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcb82ef4d4b7e1652aad88f02c81f0a5875561b285f770775abd31a3783737ac
|
|
| MD5 |
30fb495bb67f79890e514dec6f2b9e0f
|
|
| BLAKE2b-256 |
ef28fdc3287edae9bf9af0968a33a52113cc6127ff971eeaf802c4a2f5c45d1d
|
Provenance
The following attestation bundles were made for llm_input_hardening-1.1.0-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on davidwebstar34/llm-input-hardening
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llm_input_hardening-1.1.0-cp310-abi3-win_amd64.whl -
Subject digest:
bcb82ef4d4b7e1652aad88f02c81f0a5875561b285f770775abd31a3783737ac - Sigstore transparency entry: 1390570715
- Sigstore integration time:
-
Permalink:
davidwebstar34/llm-input-hardening@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Branch / Tag:
refs/heads/main - Owner: https://github.com/davidwebstar34
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file llm_input_hardening-1.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: llm_input_hardening-1.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 419.7 kB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef3ecc5d74fb88280b66fc38acb5c2959ce9104f1066055c9dbaddab7748d85f
|
|
| MD5 |
bcac37bc5b12281f4ea72c4e19ceabbd
|
|
| BLAKE2b-256 |
6f432c96e080ca997817ce28fbeff6e5ded7ff6145647093387df27d532a09cf
|
Provenance
The following attestation bundles were made for llm_input_hardening-1.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on davidwebstar34/llm-input-hardening
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llm_input_hardening-1.1.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
ef3ecc5d74fb88280b66fc38acb5c2959ce9104f1066055c9dbaddab7748d85f - Sigstore transparency entry: 1390570683
- Sigstore integration time:
-
Permalink:
davidwebstar34/llm-input-hardening@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Branch / Tag:
refs/heads/main - Owner: https://github.com/davidwebstar34
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file llm_input_hardening-1.1.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: llm_input_hardening-1.1.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 376.1 kB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3f4d2eef760359451ce4c048665a0d51bb53a2f34fce2a790ccc3dd6c0f9de10
|
|
| MD5 |
740f8507e82cde9690970600a1854517
|
|
| BLAKE2b-256 |
685a55e64b7f9d22b8cdf983675f523fe7d1e39245ac5cd4ddd96139b207f9f9
|
Provenance
The following attestation bundles were made for llm_input_hardening-1.1.0-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on davidwebstar34/llm-input-hardening
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
llm_input_hardening-1.1.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
3f4d2eef760359451ce4c048665a0d51bb53a2f34fce2a790ccc3dd6c0f9de10 - Sigstore transparency entry: 1390570656
- Sigstore integration time:
-
Permalink:
davidwebstar34/llm-input-hardening@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Branch / Tag:
refs/heads/main - Owner: https://github.com/davidwebstar34
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@5891c2bc307825908efdac3af1e00ef66b77bcbf -
Trigger Event:
workflow_dispatch
-
Statement type: