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

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(["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.6.0.tar.gz (80.3 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.6.0-py3-none-any.whl (63.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: cendor_guardrails-1.6.0.tar.gz
  • Upload date:
  • Size: 80.3 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.6.0.tar.gz
Algorithm Hash digest
SHA256 661b93105bbadbb17ca586b43dd30fa5429bf55b2666023f75d1a1a9495df2eb
MD5 25aa25f99a2b9f9650a8408418280959
BLAKE2b-256 025688274636cd61df98b92aaf3198150bbbf8788126995286be06c05904add6

See more details on using hashes here.

Provenance

The following attestation bundles were made for cendor_guardrails-1.6.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.6.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cendor_guardrails-1.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b65c8aecc0edfedb1190c800715ee5d2c4a15de4537f70ec969a130be263fcd7
MD5 6f83a2af39dd8a025e11b9497ce4aecd
BLAKE2b-256 ca24dc831655365779f156cc51301e7a99b69c8457561bb5bb5855db56104079

See more details on using hashes here.

Provenance

The following attestation bundles were made for cendor_guardrails-1.6.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