Instrument your agent
The existing plugins are worked examples, not special cases. Any agent framework connects to OGR the same way. If your framework exposes a tool/exec lifecycle, you can secure it.
pip install openguardrails # or: npm install @openguardrails/core
The four steps
1. Find your interception points
Map your framework's hooks to OGR altitudes. You want, in priority order:
- a pre-tool / pre-exec hook that can block →
invocationaltitude - the exec chokepoint where commands actually run →
executionaltitude - (optional) the LLM request/response boundary →
conversationaltitude - (optional) a post-tool hook to taint provenance from web/MCP results
Most agent frameworks have at least the first two. Hermes exposed all four as plugin hooks, so no forking was needed.
2. Emit a GuardEvent at each point
Translate the hook's arguments into a
GuardEvent. Mint a guard_id at the first
altitude and propagate it (a guard-context) to the
exec point so they correlate.
from openguardrails import GuardEvent
ev = GuardEvent(
kind="tool_call", observation_point="invocation",
sensor={"id": "my-framework-hook", "class": "in_process"},
subject={"agent_id": "my-agent", "agent_type": "custom"},
payload={"name": tool_name, "arguments": args},
provenance=current_session_provenance(), # trusted by default; untrusted if tainted
event_id=new_event_id(), guard_id=guard_id,
timestamp=now_rfc3339(), session_id=session_id,
)
3. Evaluate with the SDK RuntimeClient
Don't hand-roll HTTP — the SDK client wraps the Runtime API (auth, signing, wire mapping, errors):
from openguardrails import RuntimeClient, RuntimeAPIError
client = RuntimeClient() # OGR_RUNTIME_URL + OGR_API_KEY
try:
verdict = client.evaluate(ev) # POST /v1/evaluate
except (RuntimeAPIError, OSError):
verdict = apply_on_unreachable(ev) # cached GET /v1/config policy —
# never fail open on security.*
Cache the degraded-mode config at startup so the
except branch has a policy to apply. For purely local evaluation (no hosted
runtime), the SDK also ships an in-process Runtime you can build from a
policy and detectors — same evaluate(event) → Verdict shape.
4. Enforce the verdict
if verdict.decision in ("block", "require_approval"):
return block(reason=verdict.reasons) # your framework's "don't run this" path
if verdict.decision in ("modify", "redact"):
apply(verdict.modifications) # transform, then proceed
For require_approval you can instead suspend and poll
GET /v1/approvals until a human decides. At the
execution altitude, "enforce" can also mean run the command under a real
sandbox (srt /
OpenShell) compiled from the same policy —
so a rephrased command can't bypass the intent check.
Also report what you observe but don't gate — transcript, tool results —
through /v1/ingest (BatchingIngestor makes it
fire-and-forget), and enroll a key so your events carry a
verifiable identity.
Reference implementation
The Hermes plugin is ~250 lines and demonstrates all four steps:
bridge.py— hook callbacks ↔ GuardEvent, provenance/taint, guard-context.sandbox_guard.py— wrap the exec chokepoint; run under srt when configured.__init__.py— bind the four hooks.
Graceful degradation
If your framework has no sandbox, you still get the invocation altitude — OGR
enforces on intent, and records that the adversary-proof layer was unavailable. Add
a sandbox later without changing your policy.
Start from Policy and adapt the bridge to your framework's hooks.