Python client for agent-input-sanitizer: a thin bridge to the Node.js CLI for byte-identical sanitization verdicts.
Project description
agent-input-sanitizer (Python client)
A thin Python bridge to the agent-input-sanitizer
Node.js CLI. The sanitization logic has a single source of truth — the
JavaScript in src/ — so this package shells out to the CLI rather than
re-implementing it, giving a Python pipeline byte-identical verdicts with no
second implementation to keep in sync.
Requirements
- Node.js (>= 22) on
PATH. The sanitizer is JavaScript; something has to run it. There is deliberately no pure-Python fallback.
That's it — pip install agent-input-sanitizer and, with Node available, you're
ready to go. The wheel ships a self-contained, single-file build of the CLI
(the src/ logic and its npm dependencies bundled into one .mjs at release
time), so there is no separate JavaScript checkout to clone and no environment
variable to set. The bundle is a versioned build artifact from src/, not a
hand-maintained port, so it can't drift from the JS.
Optional: point at your own JS checkout
Set AGENT_SANITIZER_CLI to a checkout's bin/sanitize-cli.mjs to override the
bundled CLI (e.g. to run against unreleased src/ changes). When the module is
imported directly from a repo checkout, the source CLI is found automatically.
Usage
from agent_input_sanitizer import sanitize
result = sanitize("untrusted text", html=True)
print(result.cleaned, result.found, result.warnings)
See the package docstring for the full set of entry points (sanitize_text,
classify_prompt, scan_instruction_files, clean_file, and the long-lived
Sanitizer worker).
Secret redaction ([secrets] extra)
The base install is dependency-free. The optional secrets extra adds a
pure-Python secret-redaction engine under agent_input_sanitizer.secrets —
detect-secrets plus custom detectors, benign-value skipping, cross-line
reassembly, PEM collapse, and exact-match redaction of caller-supplied env-var
values. Unlike the sanitizer above it needs no Node.js; its only dependency
is detect-secrets, pulled in by the extra:
pip install "agent-input-sanitizer[secrets]"
Every detect-secrets import lives inside this subpackage, so a plain
import agent_input_sanitizer never touches it. The engine shares the parent
package's invisible-character SSOT (agent_input_sanitizer.invisible) rather
than forking it — a fork would be a silent security regression.
In-process
from agent_input_sanitizer.secrets import RedactorConfig, redact, redact_map
redacted, found = redact("aws_key = AKIAIOSFODNN7EXAMPLE")
# -> ("aws_key = [REDACTED: AWS Access Key]", ["AWS Access Key"])
# Pass provider/host secret values in — config is supplied, never discovered.
cfg = RedactorConfig(host_cred_vars={"GH_TOKEN": "ghp_realtokenvalue123"})
redact("tok=ghp_realtokenvalue123", cfg) # -> ("tok=[REDACTED: GH_TOKEN]", ["GH_TOKEN"])
The rehydration map contract
redact_map(text, config) returns a lossless, two-way view:
{"text": "<redacted>",
"pairs": [{"placeholder": "[REDACTED: …]", "original": "<secret>", "start": <int>}],
"found": ["<type>", ...]}
Substituting each pair["original"] at its start reconstructs the input
byte-for-byte. start is a Unicode code-point offset into text (the field
is start, not start_offset). U+E000 / U+E001 are reserved placeholder
sentinels: input already containing either is refused with
{"unmappable": "input contains reserved sentinel characters"} (fail closed)
rather than producing an ambiguous map.
Daemon vs. one-shot
detect-secrets caches a process-global secret_type → plugin mapping, so a fresh
one-shot call must re-register the plugin set every time — slow under load. Two
console scripts (installed with the extra) cover both modes:
agent-secret-redactor— one-shot: reads text on stdin, writes the redaction result as JSON on stdout. Re-registers plugins per call.agent-secret-redactor-daemon <socket-path>— long-lived Unix-socket server that configures the plugin set once at startup (a warm-up scan primes the cache before it binds, so a bound socket means ready). Wire protocol both directions: a 4-byte big-endian length prefix then that many bytes of UTF-8 JSON. Request{"text", "map", "web_ingress", "env_secrets"}; response is the one-shot result, JSONnullwhen nothing is redacted, or{"error": …}on a scan failure.
Both console scripts import the engine on startup, so they fail loud if the
[secrets] extra (hence detect-secrets) is not installed — fail closed, never
a silent no-op.
Versioning
This package is versioned in lockstep with the npm
agent-input-sanitizer:
each release publishes both at the same version from the same commit, and the
wheel bundles src/ at exactly that version. So pip install agent-input-sanitizer==X.Y.Z and npm i agent-input-sanitizer@X.Y.Z are the
same underlying logic.
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 Distribution
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 agent_input_sanitizer-1.47.2.tar.gz.
File metadata
- Download URL: agent_input_sanitizer-1.47.2.tar.gz
- Upload date:
- Size: 233.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63f6a94a3ff292bc301c31b3951d113b9997e6c3c84e75856b84f1672ac58221
|
|
| MD5 |
d83217655a46dfce483622e05fc58245
|
|
| BLAKE2b-256 |
98e3a49bb8898069318fbe7c742e7549c81c584ff4082e25721ead06e749a679
|
Provenance
The following attestation bundles were made for agent_input_sanitizer-1.47.2.tar.gz:
Publisher:
publish-python.yaml on AlexanderMattTurner/agent-input-sanitizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_input_sanitizer-1.47.2.tar.gz -
Subject digest:
63f6a94a3ff292bc301c31b3951d113b9997e6c3c84e75856b84f1672ac58221 - Sigstore transparency entry: 2210070984
- Sigstore integration time:
-
Permalink:
AlexanderMattTurner/agent-input-sanitizer@520b31b3bf11a00c1e106101270164ccac882178 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AlexanderMattTurner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yaml@520b31b3bf11a00c1e106101270164ccac882178 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file agent_input_sanitizer-1.47.2-py3-none-any.whl.
File metadata
- Download URL: agent_input_sanitizer-1.47.2-py3-none-any.whl
- Upload date:
- Size: 240.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9daf858525bc4df1c105f49173d794fa81c2d2720ad2056b4f7651170b0e02c6
|
|
| MD5 |
15bb18d993445d88757d53aeb21bf500
|
|
| BLAKE2b-256 |
71adb9c541449f730792f8ca365950711a9ab29bc33f4fbd665b65d1ff453f11
|
Provenance
The following attestation bundles were made for agent_input_sanitizer-1.47.2-py3-none-any.whl:
Publisher:
publish-python.yaml on AlexanderMattTurner/agent-input-sanitizer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_input_sanitizer-1.47.2-py3-none-any.whl -
Subject digest:
9daf858525bc4df1c105f49173d794fa81c2d2720ad2056b4f7651170b0e02c6 - Sigstore transparency entry: 2210071001
- Sigstore integration time:
-
Permalink:
AlexanderMattTurner/agent-input-sanitizer@520b31b3bf11a00c1e106101270164ccac882178 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/AlexanderMattTurner
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yaml@520b31b3bf11a00c1e106101270164ccac882178 -
Trigger Event:
workflow_dispatch
-
Statement type: