cendor-guardrails
A local-first gate for LLM apps: define a check — keyword, regex, URL, length, JSON-schema —
attach it to a stage (input, tool_call, tool_output, output), and block, redact, or flag
before the model or a tool ever runs. No server, no account, no model call.
Deterministic checks in microseconds for $0 — and every decision lands in a tamper-evident audit chain.
·
pip install cendor-guardrails
Using an AI coding assistant? npx @cendor/init (TS) / uvx cendor-init (Python) wires it up — or point it at cendor.ai/docs/for-ai-assistants.
from cendor.core import instrument
from cendor.guardrails import install, rules
client = instrument(OpenAI())
install([ # one interceptor gates every call
rules.keyword_deny(["ignore previous instructions"], action="block"),
rules.regex_rule(r"\bsk-[A-Za-z0-9]{20,}\b", action="redact", stage="input"),
rules.url_allowlist(["cendor.ai"], stage="input"),
])
client.chat.completions.create(model="gpt-4o", messages=msgs)
# blocked prompt -> raises GuardrailTripped BEFORE the request is sent ($0 spent)
# a leaked key -> the provider receives "[redacted]" instead
Highlights
- Four intervention points — gate the user turn (
input), the model's request to call a tool (tool_call), the tool's result (tool_output), and the model's final answer (output). Matches Azure Foundry's intervention points and OpenAI's four decorator types. - Deterministic built-ins, no heavy deps —
keyword_deny,regex_rule,spotlight(wrap untrusted content in a trust-lowering delimiter — a$0mitigation, inspired by Azure Spotlighting),url_allowlist/url_deny,length_bounds(char + exact token bounds viacendor.core.tokens),json_schema, andcustom. Regex/arithmetic only — offline, deterministic, $0. - Evidence, not just enforcement — every trip or flag emits a
GuardrailDecisionon thecendor.corebus, socendor-acttracechains it as a tamper-evidentguardrail_decisionentry with no import between the two. "We blocked it" is in the hash chain, not a log line. - Three ways to use it — pure
apply()/evaluate(); framework-independentinstall()on the core seam (orscoped()for per-request gating on a concurrent server); andAgent(guardrails=[…])incendor-sdk(all four in-loop stages + per-run override). - Bring-your-own model judge —
rules.llm_judgefor open-ended risk, with per-guardrailtimeout+on_error(fail-closed by default) andcendor.guardrails.judgehelpers (verdict prompt + strict-JSON parsing). The judge rides an instrumented client, so its own spend is budgeted + audited. - Detection tiers you opt into — a local classifier contract (
rules.classifier,rules.prompt_guardbehind the[promptguard]extra),rules.language, and hosted rails (rules.bedrock_guardrail/azure_content_safety/model_armor— duck-typed clients, metered by the vendor). Every hosted verdict still emits a localguardrail_decision: cloud check, local evidence. No jailbreak/PII-catch-rate claim ships without a reproduced, published benchmark. - Config as data + grounding —
load_policy("guardrails.yaml")builds deterministic rules from a versioned file and stamps itspolicy_hash/policy_versiononto every decision (the audit chain proves which policy was live);rules.groundedness/rules.denied_topicsgate on bring-your-own-embedding cosine similarity (RAG hallucination / off-topic), no bundled model. - Red-team it —
run_redteam(guardrails, load_corpus("attacks.jsonl"))reports the trip rate + false-positive rate against a labeled corpus you supply (cendor vends no attack data). A measurement, not a claim: publish a rate only with the corpus named.
from cendor.guardrails import apply, guardrail, Verdict, GuardrailTripped
@guardrail(stage="output")
def must_be_json(payload, ctx):
if not payload.strip().startswith("{"):
return Verdict("block", reason="expected a JSON object")
try:
apply([must_be_json], "output", model_text) # raises GuardrailTripped on a block
except GuardrailTripped as e:
print(e.decisions) # the recorded decisions, block last
How it plugs into your agent
guardrails is the Gate in the pipeline — contextkit → squeeze → tokenguard → guardrails → cassette → acttrace. It imports only cendor-core: checks ride the same instrument() seam
and event bus every other library uses, so the same guardrail works under cendor-sdk, a bare
instrumented client, or beneath another framework — in Python and TypeScript alike.
Honest limits: the built-ins are deterministic, so they do not stop a novel adversarial
attack — a jailbreak they were never told about will pass. Pair them with a bring-your-own model
judge (rules.llm_judge, an adapter contract — you supply the call, and the extra latency/cost is
real) and treat the deterministic rules as the fast, free floor, not a ceiling. PII/secret
detection lives in cendor-acttrace (guard(Policy…)), not here.
See docs/guardrails.md · CHANGELOG. Part of the Cendor stack — github.com/cendorhq/cendor-libs. Powered by PowerAI Labs. Apache-2.0; provided "as is", without warranty — use at your own risk (LICENSE §7–8).
Metadata
Release files for cendor-guardrails 1.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cendor_guardrails-1.7.0.tar.gz | 82.9 kB | With provenance | Details for cendor_guardrails-1.7.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cendor_guardrails-1.7.0-py3-none-any.whl | Python 3 | none | any | Details for cendor_guardrails-1.7.0-py3-none-any.whl |
Total release size: 147.4 kB
Release files / cendor_guardrails-1.7.0.tar.gz
| Download URL | cendor_guardrails-1.7.0.tar.gz |
|---|---|
| Size | 82.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
382b12505a427812d2ea848d899ee94295aac8b5df8049f96b67e27d0133fb91
|
|
BLAKE2b-256 checksum How to use checksums |
5e818d1898c336727d4f2750d2cf34e09015c994f89fef2c983100b0c9c23410
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.
Transparency logRelease files / cendor_guardrails-1.7.0-py3-none-any.whl
| Download URL | cendor_guardrails-1.7.0-py3-none-any.whl |
|---|---|
| Size | 64.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bb2ce0a4addd483643fe7fb58b6f5c291f0851177f87dae28e0dae24a654c60c
|
|
BLAKE2b-256 checksum How to use checksums |
f3d97a19fb25821421eef2a83646240bb514fc76bfbca2ad8e02364ca70bf1b5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.
Transparency logSecurity for cendor-guardrails 1.7.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for cendor_guardrails-1.7.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 31, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.