Skip to main content

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). Deterministic, microsecond, $0, and every decision is audit-grade evidence.

Project description

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.

PyPI license · pip install cendor-guardrails

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(["docs.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 depskeyword_deny, regex_rule, spotlight (wrap untrusted content in a trust-lowering delimiter — a $0 mitigation, inspired by Azure Spotlighting), url_allowlist / url_deny, length_bounds (char + exact token bounds via cendor.core.tokens), json_schema, and custom. Regex/arithmetic only — offline, deterministic, $0.
  • Evidence, not just enforcement — every trip or flag emits a GuardrailDecision on the cendor.core bus, so cendor-acttrace chains it as a tamper-evident guardrail_decision entry 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-independent install() on the core seam (or scoped() for per-request gating on a concurrent server); and Agent(guardrails=[…]) in cendor-sdk (all four in-loop stages + per-run override).
  • Bring-your-own model judgerules.llm_judge for open-ended risk, with per-guardrail timeout + on_error (fail-closed by default) and cendor.guardrails.judge helpers (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_guard behind 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 local guardrail_decision: cloud check, local evidence. No jailbreak/PII-catch-rate claim ships without a reproduced, published benchmark.
  • Config as data + groundingload_policy("guardrails.yaml") builds deterministic rules from a versioned file and stamps its policy_hash / policy_version onto every decision (the audit chain proves which policy was live); rules.groundedness / rules.denied_topics gate on bring-your-own-embedding cosine similarity (RAG hallucination / off-topic), no bundled model.
  • Red-team itrun_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.

Part of the Cendor stack — github.com/cendorhq/cendor-libs. Powered by PowerAI Labs.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cendor_guardrails-1.5.0.tar.gz (75.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cendor_guardrails-1.5.0-py3-none-any.whl (58.9 kB view details)

Uploaded Python 3

File details

Details for the file cendor_guardrails-1.5.0.tar.gz.

File metadata

  • Download URL: cendor_guardrails-1.5.0.tar.gz
  • Upload date:
  • Size: 75.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for cendor_guardrails-1.5.0.tar.gz
Algorithm Hash digest
SHA256 92f9ee3c6cfa2fe37bc68280c35aab4c7cdb97fe5615dc43a5550f108a003de9
MD5 6829212ffc29f9ad7305d21aef091e8c
BLAKE2b-256 b75987b9710d23a86faec1108a0a29a1438aa4a6c0f34003991f91d41409e0e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for cendor_guardrails-1.5.0.tar.gz:

Publisher: release.yml on cendorhq/cendor-libs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cendor_guardrails-1.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cendor_guardrails-1.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7c34102ed13b1f869e5bec49c3adfa91b7317862d68a18c8f078d87cc70a5975
MD5 8783b6672d3e91d1356fc01e48fbdc96
BLAKE2b-256 dbf998ccb3dbc04d6b22193153a580eb77d381e20c894bdcd1d4e17445999a1d

See more details on using hashes here.

Provenance

The following attestation bundles were made for cendor_guardrails-1.5.0-py3-none-any.whl:

Publisher: release.yml on cendorhq/cendor-libs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page