Guardrails for
AI-written code.
rein reviews what your coding agents produce and blocks unsafe, broken, or hallucinated code before it runs. No model judges the action, so the verdict is the same every time and you can see exactly why a call was stopped.
pip install rein-engine
A real agent + rein guardrail (deterministic, no LLM):
[1] dangerous code
agent tried: save_code('import os\nos.system(user_input)')
-> BLOCKED before execution; tool body never ran
security.os-system (high): os.system invokes a shell; use
subprocess with a list and shell=False.
[2] clean code
agent tried: save_code('def add(a, b): return a + b')
-> allowed; tool ran
Same verdict every run, with no model in the review loop.
The problem
Agents write real code now.
Autonomous coding agents write files and run commands on their own. The
failure modes are specific and dangerous: a hallucinated import that does not
exist, a hard-coded secret, an os.system call on user input, code
that will not even parse. Letting a second LLM review it is non-deterministic,
it passes once and fails the next run, and unauditable, you cannot see why.
rein is the deterministic layer that sits at the boundary and decides the same
way, every time.
How it works
One hook, gated at the boundary.
The agent proposes
It is about to write a file or run a command. rein hooks that moment, before anything executes.
rein reviews
Plain functions parse and check the code: security, secrets, hallucinated imports, undefined names. No LLM.
Block or allow
At or above your threshold, the call is cancelled with the reason and a fix. Otherwise it runs untouched.
Coverage
What it catches.
Unsafe code
os.system, eval, exec, pickle, subprocess shell=True, weak hashes, by AST, not guesswork.
Hard-coded secrets
API keys and tokens committed into source, caught before they ship.
Hallucinated imports
An import that resolves to no stdlib, dependency, or project module, the classic agent failure a linter misses.
Undefined names
A name used but bound nowhere reachable: a NameError caught before it runs.
Best-of-breed scanners
Opt into bandit, gitleaks, ruff, and semgrep, run over the agent's code before it touches disk.
A reason and a fix
Every finding comes with why it fired and how to remedy it, not just an alert.
Why deterministic
Not a second opinion.
LLM reviewer
- Non-deterministic: passes once, fails the next run
- Costs tokens on every check
- Can be prompt-injected by the very code it reviews
- Cannot explain its verdict
rein
- Deterministic: identical verdict every run
- No tokens, no model, runs in microseconds
- Plain functions over an AST, nothing to manipulate
- Every finding has a reason and a fix
Who it's for
Built for teams shipping agents.
Agent builders
Building on Claude Code, OpenHands, or Strands? Gate every tool call deterministically, before it runs.
Platform & devtools teams
Shipping an agent product? Drop in a guardrail your users can trust: no model cost, fully auditable.
Security-minded orgs
Adopting AI codegen? Keep unsafe, secret-leaking, and hallucinated code out of your repos, the same way every time.
Quickstart
Three ways to use it.
In your agent
from rein_strands import ReinToolGuard
agent = Agent(model=model, tools=tools,
hooks=[ReinToolGuard()])Works with Strands and OpenHands. Blocks HIGH+ before the tool runs.
In CI
# .github/workflows/rein.yml
- uses: SametAtas/rein@v0.3.0
with:
paths: src/Reviews every pull request and emits SARIF.
On the CLI
pip install rein-engine
rein review .Or wire it as a pre-commit hook for local gating.
Integrations
Plugs in where your agents run.
FAQ
Questions.
Does rein use an LLM?
No. Detection is plain deterministic functions over the code's AST plus regex for secrets. Same input, same verdict, every time.
Is it slow?
The native checks run in-process in microseconds. The external scanners (bandit, semgrep, and so on) are opt-in, since they cost real time per call.
What languages?
Python today for the code analysis; secret detection works on any text. More languages are on the roadmap.
Will it cry wolf on working code?
Precision is the point. rein is built to fail open and bias toward false negatives over false positives, so a real, working tool call is not blocked.
What does deep mode add?
It runs bandit, gitleaks, ruff, or semgrep over the agent's code before it executes, folding their findings into the same verdict. Opt-in per scanner.
Is it open source?
Yes, Apache-2.0. The engine is on PyPI as rein-engine, with adapters for the major agent frameworks.
Gate your agents today.
pip install rein-engine