Guardrail engine redact block audit
Skill kjuhwa/skills-hub/skills/safety/guardrail-engine-redact-block-audit
Scan LLM-bound text against a YAML rule set with three actions (redact, block, audit), splice replacements in reverse so earlier positions stay valid, raise a typed error on block, and append a JSONL audit entry for every match.From its SKILL.md
npx -y skills add kjuhwa/skills-hub --skill guardrail-engine-redact-block-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.3 KB, 594 tokens by cl100k_base, as published. Nobody here has run it
Guardrail Engine: Redact / Block / Audit
When to use
You need a uniform pre-LLM filter that supports three behaviors at once: redact secrets in place (with a custom replacement string), block the call entirely if a forbidden term appears, and emit an audit trail for compliance. Rules are user-editable YAML.
How it works
- Rules are defined in
~/.opensre/guardrails.ymland parsed intoGuardrailRule(regex patterns + literal keywords + action enum). engine.scan(text)collects all matches without mutating;engine.apply(text)performs the side-effecting redact/audit/block sequence.- Replacements are spliced in reverse-by-start order so earlier indices remain valid; an extra
seen_endcursor drops overlapping matches that snuck through. - Block raises
GuardrailBlockedErrorwith the offending rule names; the LLM client catches and re-raises so the exception propagates cleanly.
Example
class GuardrailEngine:
def apply(self, text: str) -> str:
result = self.scan(text)
if not result.matches:
return text
for match in result.matches:
if self._audit:
self._audit.log(rule_name=match.rule_name,
action=match.action.value,
matched_text_preview=match.matched_text)
if result.blocked:
raise GuardrailBlockedError(result.blocking_rules)
redact_matches = sorted(
[m for m in result.matches if m.action == GuardrailAction.REDACT],
key=lambda m: m.start, reverse=True,
)
seen_end = len(text)
redacted = text
for m in redact_matches:
if m.end > seen_end:
continue
replacement = self._get_replacement(m.rule_name)
redacted = redacted[:m.start] + replacement + redacted[m.end:]
seen_end = m.start
return redacted
YAML rule file shape:
rules:
- name: aws_access_key
action: redact
patterns: ["AKIA[0-9A-Z]{16}"]
replacement: "[REDACTED:AWS_KEY]"
- name: forbidden_term
action: block
keywords: ["delete production"]
Gotchas
- Keep audit writes best-effort (
OSErrorswallowed) — guardrails must never crash the LLM call due to disk failure. - Module-level singleton
get_guardrail_engine()caches loaded rules; exposereset_guardrail_engine()for hot-reload in tests. - Apply guardrails to both
systemandmessagescontent if your provider separates them (Anthropic does). - Keyword matching uses lowercase comparison; preserve original case in the replacement so the redaction is visually obvious.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.