Skip to main content

A secure microkernel for LLM Agents

Project description

Castor

CI PyPI License Python 3.11+

Castor: Same agent, three security levels

The secure execution layer for AI agents. Three levels of protection — from human approval on every action, to full-speed speculative execution with post-hoc review, to time-travel rollback when things go wrong.

Your agent's code stays untouched. Castor wraps your existing tools, tracks every action, and enforces safety — without your agent knowing it's there.


🚀 Quick Start

pip install castor-kernel
import asyncio
from castor import Castor, auto_approve
from castor.lib import tool

# Your existing tools — plain functions, no decorators needed
async def search(query: str) -> list[str]:
    return [f"Result for: {query}"]

async def delete_file(path: str) -> str:
    return f"Deleted {path}"

# Your agent — doesn't know about Castor
async def my_agent():
    results = await tool("search", query="old logs")
    await tool("delete_file", path="/tmp/old1")
    await tool("delete_file", path="/tmp/old2")
    return "Cleaned up"

async def main():
    kernel = Castor(
        tools=[search, delete_file],
        destructive=["delete_file"],       # mark dangerous tools
    )

    # Option A: auto-approve (for testing / trusted environments)
    cp = await kernel.run_until_complete(my_agent, on_hitl=auto_approve)
    print(cp.result)  # "Cleaned up"

    # Option B: speculative — full speed, review after
    cp = await kernel.run(my_agent, speculative=True)
    summary = kernel.scan(cp)
    print(f"{summary.total_steps} steps, {summary.flagged_count} need review")

asyncio.run(main())

search runs immediately (safe tool). delete_file is destructive — in default mode Castor suspends for human approval. In speculative mode it runs but flags the step for post-hoc review. The agent doesn't know either way.

🛡️ Three Levels of Protection

Level 1: HITL — Human approves every dangerous action

cp = await kernel.run(my_agent, budgets={"api": 10})
# → destructive tools pause for approval, safe tools run immediately

Level 2: Speculative — Full speed, review after

cp = await kernel.run(my_agent, speculative=True)
summary = kernel.scan(cp)
# → 23 steps, 21 auto-verified, 2 flagged for review

Agent runs without interruption. Every destructive operation is flagged with needs_review — the kernel decides at execution time, not after. You review the flagged steps, approve or reject.

Level 3: Time-Travel — Rewind and fix mistakes

# Agent finished but Step 5 was wrong
forked = cp.fork(at_step=5)
cp2 = await kernel.run(my_agent, checkpoint=forked)
# → Steps 1-4 replay from cache (free). Steps 5+ re-execute.

Don't re-run the whole thing. Rewind to the mistake, fix it, fork a new timeline. Cached steps cost nothing — no re-execution, no re-billing.

Run uv run python examples/security_levels.py to see all three levels on the same task.

💡 Philosophy

Agent frameworks give LLMs tools. They don't control how those tools are used. Guardrails are advisory — the agent still owns execution.

Castor inverts this. The agent doesn't call tools. It requests them. Every side effect is a syscall that passes through a kernel. The kernel validates, budgets, gates, and logs before anything executes.

OS Concept Castor Analog
🏗️ User / Kernel space Agent code / Castor kernel
📞 System calls tool() / proxy.syscall()
🎟️ Capabilities Depletable budget tokens
⏯️ Process checkpointing Fork, replay, time-travel
🧠 Virtual memory Context window MMU

Like Linux, your program (agent) uses libc (castor.lib) and never touches the kernel directly. The operator configures security policy. Three roles, fully separated:

Tool developer:  writes plain functions (no Castor knowledge)
Agent developer: uses castor.lib.tool() (no kernel imports)
Operator:        Castor(tools=, destructive=, budgets=)

🔧 CLI

Run agents from the command line — like a shell for AI agents:

castor run agent.py:main \
    --tool tools.py:search \
    --tool tools.py:delete_file --destructive \
    --budget api=50 \
    --speculative

Agent and tool code have zero Castor knowledge. The operator configures everything via CLI flags.

castor ps                              # list agents
castor inspect <pid>                   # view checkpoint
castor approve <pid>                   # approve pending action
castor reject <pid> --reason "..."     # reject with feedback

🛡️ Guard Any Framework

Already using an agent framework? Pass your tools through Castor. Your framework runs the agent loop, Castor guards the tool calls.

from castor import Castor
from castor.lib import tool

# ── Your existing tools (unchanged) ──

async def web_search(query: str) -> str:
    return f"Results for: {query}"          # your real search implementation

async def delete_file(path: str) -> str:
    os.remove(path)                         # your real file deletion
    return f"Deleted {path}"

# ── Your existing agent logic (unchanged) ──

async def my_agent():
    results = await tool("web_search", query="old temp files")
    for path in parse_paths(results):
        await tool("delete_file", path=path)
    return "Cleanup done"

# ── Operator adds Castor (one place, no changes to above) ──

kernel = Castor(
    tools=[web_search, delete_file],
    destructive=["delete_file"],
    budgets={"api": 20, "disk": 5},
)

cp = await kernel.run(my_agent, speculative=True)
summary = kernel.scan(cp)
print(f"{summary.total_steps} steps, {summary.flagged_count} need review")

This works with any framework — LangChain, CrewAI, smolagents, pydantic-ai, or your own code. The only requirement: tool calls go through castor.lib.tool(). The agent loop is yours.

🔒 Security Scope

Castor provides application-layer control: it gates what the agent intends to do (tool calls, budgets, approval). It does not sandbox the process (filesystem, network). For defense in depth, run Castor inside a container or use Roche, a sandbox orchestrator designed for AI agents. Castor controls intent; your infrastructure controls capability.

📚 Documentation

🤝 Contributing

Contributions are welcome. See CONTRIBUTING.md for guidelines.

🛠️ Development

git clone https://github.com/substratum-labs/castor.git
cd castor && uv sync
uv run pytest
uv run ruff check src/

📄 License

Apache 2.0. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

castor_kernel-0.5.1.tar.gz (5.2 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

castor_kernel-0.5.1-py3-none-any.whl (71.0 kB view details)

Uploaded Python 3

File details

Details for the file castor_kernel-0.5.1.tar.gz.

File metadata

  • Download URL: castor_kernel-0.5.1.tar.gz
  • Upload date:
  • Size: 5.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for castor_kernel-0.5.1.tar.gz
Algorithm Hash digest
SHA256 17058b5ee7f50aa4b2f609cc40ab1086f9e160da8f6d77bb0d240742030aff56
MD5 02f874038b97209ca5208ef105f98c3c
BLAKE2b-256 9313e2c20eaf782c95cf00539e0148f25f905e546f37166e9bcb2872ea33f64e

See more details on using hashes here.

File details

Details for the file castor_kernel-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: castor_kernel-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 71.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for castor_kernel-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6c1ddf0baa3dddf88fdf2b8322cc56fa075007bc1e97f31fc8519bdbb3c41331
MD5 50fae973d2be877f2ebdfd74ce1f526b
BLAKE2b-256 d9ea4954da1e204182600dbe37552e0e248a88202f96a66d2abbc3fa31b30aed

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page