Skip to main content

rein-strands

CI PyPI Python License

A deterministic, no-LLM guardrail for Strands agents. It reviews the code or command a tool is about to run and cancels the call before the tool executes when the verdict crosses a severity threshold. Backed by the rein engine.

No LLM judges the action, so the verdict is the same every run and you can see exactly why a call was stopped. The same check behaves identically whether a person, CI, or the agent triggers it, which keeps accountability clear.

See it block a real agent

examples/agent_demo.py runs an actual Strands Agent (a scripted model stands in for the LLM, so no API key is needed) and lets rein gate its tool calls:

[1] dangerous code
    agent tried: save_code('import os\nos.system(user_input)\n')
    -> BLOCKED before execution; tool body never ran
       rein blocked tool 'save_code': security.os-system (high): os.system/os.popen
       invokes a shell; use subprocess with a list and shell=False.

[2] clean code
    agent tried: save_code('def add(a, b):\n    return a + b\n')
    -> allowed; tool ran

The dangerous tool call is cancelled at the boundary; the tool function never runs. The clean one goes through untouched.

Install

pip install rein-strands

Use

Attach the hook to your agent. That is the whole integration:

from strands import Agent
from strands_tools import shell, file_write, python_repl

from rein_strands import ReinToolGuard

agent = Agent(
    model=model,
    tools=[shell, file_write, python_repl],
    hooks=[ReinToolGuard()],   # blocks HIGH+ verdicts before the tool runs
)

What it reviews

Tool Field reviewed Analysis
python_repl code Full rein code analysis (stateful session, so undefined-name is not enforced)
file_write content (.py) Full rein code analysis, fails closed if the file will not parse
editor file_text / new_str (.py) Full rein code analysis on the added text
shell command Secrets, plus full analysis of any inline python -c "..." code
custom content / code (no path) Treated as Python so dangerous code is still caught
any non-.py file content Secrets only (the Python AST checks do not apply)

rein catches hard-coded secrets, unsafe calls (os.system, eval, pickle, weak hashes, and so on), undefined names, and (with project_root) hallucinated imports. Each finding carries the reason and a remedy, not just an alert.

Modes and threshold

from rein_strands import ReinToolGuard, Severity

# Report only, never block (human-in-the-loop, where a person owns the call):
ReinToolGuard(mode="audit", on_finding=lambda d: print(d.reason))

# Stricter: also block MEDIUM findings (e.g. weak hashes, hallucinated imports):
ReinToolGuard(block_at=Severity.MEDIUM)
  • mode="enforce" (default) cancels a call whose verdict is at or above block_at.
  • mode="audit" never cancels and only reports findings.
  • block_at defaults to Severity.HIGH.

Catching hallucinated imports

Pass project_root and rein also checks every Python import the agent writes against the project's stdlib, declared dependencies, and own modules, so a hallucinated or undeclared module is caught before the file is written or run:

ReinToolGuard(project_root=".", block_at=Severity.MEDIUM)

This needs the project to declare dependencies (a pyproject.toml [project] table or a requirements*.txt); without one rein cannot know what is installed, so the import check stays inert rather than guessing.

Deep mode: external scanners

By default the guard runs rein's fast, in-process native checks. Opt into the external scanners rein integrates (ruff, bandit, gitleaks, semgrep) and they run over the tool's content before it executes, folding their findings into the same verdict:

ReinToolGuard(scanners=("bandit", "gitleaks"))

This is off by default on purpose: external scanners cost real time per call, so it is opt-in and you choose which to run. bandit and gitleaks are reasonable per-call; semgrep is heavier and usually better as a commit-time gate (where rein review already runs it). The named scanners must be installed; a missing one is skipped.

How it fits with Strands' own safety

Strands shell relies on up-front isolation (declare what the agent can reach; everything else does not exist), and Strands offers model-level guardrails. rein-strands is the complementary deterministic, code-level layer: isolation controls what an action can touch, rein judges what the code itself does, before it runs. It is intentionally narrow and precise rather than a broad shell-pattern scanner, so it does not cry wolf on ordinary commands.

Design

The decision logic (evaluate) is a pure function with no Strands or LLM dependency; ReinToolGuard is the thin hook that wires it into an agent, and extraction.py holds the Strands-specific tool-shape mapping. The core has no dependencies beyond rein. Verified against strands-agents 1.44, with an end-to-end test that drives a real agent.

License

Apache-2.0.

Metadata

Release files for rein-strands 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rein-strands 0.4.0
File Size Uploaded Provenance Actions
rein_strands-0.4.0.tar.gz 18.7 kB With provenance Details for rein_strands-0.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for rein-strands 0.4.0
File Interpreter ABI Platform Actions
rein_strands-0.4.0-py3-none-any.whl Python 3 none any Details for rein_strands-0.4.0-py3-none-any.whl

Total release size: 32.6 kB

Release files / rein_strands-0.4.0.tar.gz

Download URL rein_strands-0.4.0.tar.gz
Size 18.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f20428e0d6f605c8d1208f2f373a9f222bebdd6bc6d96b784a301d4617d01461
BLAKE2b-256 checksum
How to use checksums
d8004341fd4eb4c37c08af3d2d0af344263574921ad542fde4ad8f9217135f8c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Release files / rein_strands-0.4.0-py3-none-any.whl

Download URL rein_strands-0.4.0-py3-none-any.whl
Size 13.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ebfa935c8b2fa3cbab319cd357b6a455b6e3954375a921a9ee617015069e11e
BLAKE2b-256 checksum
How to use checksums
bd032372b328fb87f5c8aa2c72fb911135e991b6204fd9361c1ae5f0f7ce45d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

Security for rein-strands 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for rein_strands-0.4.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page