A guardrail pipeline for LLM apps and agents. When the model is fooled — and it will be — nothing important breaks.
Data-access guards and LLM I/O guards in one in-process lifecycle-hook pipeline.
enforce / observe / off. New rules shadow-run first, reconcile against the audit stream, then enforce — shipping is not a gamble.
A crashed rule ≠ violating content. Per-rule failMode: open | closed; last-gate rules stay closed even when they crash.
Private data + untrusted content + outbound comms — all three present escalates to a human, with the raw underlying call, never a model-written summary.
Tamper-evident hash chain: offline verification, torn-write truncation, chain continuation across restarts. WebCrypto — signs on edge too.
Interception rate alone drifts toward blocking everything. Versioned dataset + reference guards; CI pins the exact numbers.
Zero-dep structural typing: no peer dependencies; one line into wrapLanguageModel or inputProcessors.
import { createGuard, lens } from '@yiong/railguard'
import { faithfulness, injection, inputHygiene, linkPolicy } from '@yiong/railguard/rules'
import { consoleSink } from '@yiong/railguard/audit'
const guard = createGuard({
audit: consoleSink(),
hooks: {
onInput: [inputHygiene(), injection({ mode: 'block' })],
onOutput: [
faithfulness({ resolve: (c) => corpus.slice(c), quoteOf: (c) => c.quote }),
lens(linkPolicy({ allow: ['https://docs.example.com/'] }), (p) => p.answer, (p, v) => ({ ...p, answer: v })),
],
},
})
const input = await guard.run('onInput', userQuestion, guard.context())
if (!input.ok) return refuse(input.blocked?.reason)Design philosophy (OWASP GenAI 2026): the probabilistic layer (injection heuristics) alone is not a security boundary — the boundary is output-side verification and deterministic rules. That is a documented commitment of this package, not a disclaimer.