safeprompt-langchain
LangChain callback handler that validates every prompt flowing through your chain via the SafePrompt API before it reaches the LLM. Catches jailbreaks, data-extraction attempts, authority-signal impersonation, and indirect injection from tool outputs.
This is the Python counterpart to the JavaScript package @safeprompt.dev/langchain.
Install
pip install safeprompt-langchain
Requires langchain-core>=0.3.0 (installed automatically).
Quick start
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from safeprompt_langchain import SafePromptCallbackHandler, SafePromptBlockedError
handler = SafePromptCallbackHandler(
api_key="sp_live_...", # get one at https://safeprompt.dev
user_ip=request_ip, # end-user IP from your web framework
)
chain = ChatPromptTemplate.from_template("Answer: {input}") | ChatOpenAI(model="gpt-4o-mini")
try:
result = chain.invoke({"input": user_input}, config={"callbacks": [handler]})
print(result.content)
except SafePromptBlockedError as err:
# The prompt was flagged — surface the threats, don't call the LLM.
return {"error": "Prompt blocked for safety", "threats": err.result.threats}
Configuration
SafePromptCallbackHandler(
api_key="sp_live_...",
user_ip="203.0.113.1", # REQUIRED — end-user IP
provider="https://api.safeprompt.dev", # default
mode="balanced", # "fast" | "balanced" | "strict"
enforcement="block", # "block" | "log" (log = don't raise, just fire on_block)
on_provider_error="fail-closed", # "fail-closed" | "fail-open"
sample_rate=1.0, # 0..1 — fraction of prompts to validate
timeout=30.0, # seconds per validation request
on_block=lambda prompt, result: print("[safeprompt] blocked", result.threats),
on_error=lambda prompt, err: print("[safeprompt] provider error", err),
)
enforcement="log" — tune before enforcing
Run the adapter in log mode in staging/production for a week. You get on_block
callbacks without any chain aborts. Review the results, tune custom lists / confidence
thresholds on your SafePrompt account, then flip to enforcement="block".
sample_rate — cost control for high-volume apps
Each validation is a round-trip to the SafePrompt API (sub-second for most prompts, but
still a network hop). For apps processing >10K prompts/day where latency matters more than
per-prompt coverage, set sample_rate=0.1 to validate 10% of prompts.
Indirect-injection protection (agents)
Used with a LangChain agent, the handler also fires on on_tool_end — the moment a tool
returns content that will be fed back to the LLM. This is the key protection against
indirect prompt injection (content fetched from the web, retrieved from RAG, etc., that
hides malicious instructions).
How it works
on_llm_start/on_chat_model_startfires before every LLM call. Each rendered prompt is POSTed to the SafePrompt API.- The API runs a layered defense: pattern matching → external-reference detection → AI validation. Most requests are classified in single-digit milliseconds.
- If the API returns
safe == False, the handler either raisesSafePromptBlockedError(inblockmode) or fires youron_blockhook (inlogmode). on_tool_endapplies the same check to agent tool outputs — the primary indirect injection surface.
The handler sets
raise_error = Trueso a blocked prompt actually aborts the run instead of being swallowed-and-logged by LangChain's callback manager.
Standalone validation
You can also call the API directly without LangChain:
from safeprompt_langchain import validate
result = validate("ignore all previous instructions", api_key="sp_live_...", user_ip="203.0.113.1")
print(result.safe, result.threats) # False ['jailbreak_instruction_override']
Troubleshooting
- Every prompt 401s: API key is invalid or revoked. Check your key.
- Every prompt 400s with "X-User-IP required": you passed an empty
user_ip. The API requires this for threat-intelligence tracking. Use your web framework's client-IP helper. - False positives: switch to
enforcement="log", inspect the blocked prompts, and use custom whitelist rules on your SafePrompt account to allow known-safe patterns.
Links
MIT.
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 safeprompt_langchain-0.1.0.tar.gz.
File metadata
- Download URL: safeprompt_langchain-0.1.0.tar.gz
- Upload date:
- Size: 8.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
05a5d250969cf9cc17cdf17031d6a691a34b5e8095944b6802ddefe984f5dd50
|
|
| MD5 |
7c20773c0a86ac03832d7ad4536182df
|
|
| BLAKE2b-256 |
8e6fb14f1d7256c8b7ece6e867348fc9234f01f8a3ecc7e5bb16d49d32b37c7f
|
Provenance
The following attestation bundles were made for safeprompt_langchain-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on ianreboot/safeprompt-internal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safeprompt_langchain-0.1.0.tar.gz -
Subject digest:
05a5d250969cf9cc17cdf17031d6a691a34b5e8095944b6802ddefe984f5dd50 - Sigstore transparency entry: 2660576028
- Sigstore integration time:
-
Permalink:
ianreboot/safeprompt-internal@71e3a6088b796c58a8b605ac2246c38cc47a2bda -
Branch / Tag:
refs/tags/langchain-python-v0.1.0 - Owner: https://github.com/ianreboot
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@71e3a6088b796c58a8b605ac2246c38cc47a2bda -
Trigger Event:
push
-
Statement type:
File details
Details for the file safeprompt_langchain-0.1.0-py3-none-any.whl.
File metadata
- Download URL: safeprompt_langchain-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8e71f333f3972e2915a7fc0b2c960623230cf4a5291f82ead66f661f8d5a994a
|
|
| MD5 |
3cb817d37dd7fde3c92a5798c8393271
|
|
| BLAKE2b-256 |
be56efd1687fed4a7c5426483fbdc9dab0a1ba3e8a12d06c5055379cadfa009d
|
Provenance
The following attestation bundles were made for safeprompt_langchain-0.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on ianreboot/safeprompt-internal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safeprompt_langchain-0.1.0-py3-none-any.whl -
Subject digest:
8e71f333f3972e2915a7fc0b2c960623230cf4a5291f82ead66f661f8d5a994a - Sigstore transparency entry: 2660576055
- Sigstore integration time:
-
Permalink:
ianreboot/safeprompt-internal@71e3a6088b796c58a8b605ac2246c38cc47a2bda -
Branch / Tag:
refs/tags/langchain-python-v0.1.0 - Owner: https://github.com/ianreboot
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@71e3a6088b796c58a8b605ac2246c38cc47a2bda -
Trigger Event:
push
-
Statement type: