agentsclimarketplace

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

Install
npx -y skills add kjuhwa/skills-hub --skill guardrail-engine-redact-block-audit

Assembled 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.yml and parsed into GuardrailRule (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_end cursor drops overlapping matches that snuck through.
  • Block raises GuardrailBlockedError with 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 (OSError swallowed) — guardrails must never crash the LLM call due to disk failure.
  • Module-level singleton get_guardrail_engine() caches loaded rules; expose reset_guardrail_engine() for hot-reload in tests.
  • Apply guardrails to both system and messages content 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.

Keep looking

Skills are one crate of 326,790. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.