Railguard

Introduction

Railguard is a local-first RPC proxy sidecar that secures EVM transactions through Deep Packet Inspection and policy-based enforcement.

What is Railguard?

Railguard is a firewall for your wallet. It sits between your automated scripts (bots, deployment tools, keepers) and your RPC provider, inspecting every transaction before it leaves your machine.

┌──────────────┐     ┌─────────────┐     ┌──────────────────┐
│  Your Script │ ──► │  Railguard  │ ──► │  Upstream RPC    │
│  (Foundry)   │     │  (Inspect)  │     │  (Alchemy/etc)   │
└──────────────┘     └─────────────┘     └──────────────────┘


                     Block or Allow

Why Railguard?

The Problem

Automated scripts interacting with the blockchain are high-value targets:

  • A compromised dependency could drain your wallet
  • A bug in your bot logic could execute unintended transactions
  • A misconfigured script could burn through gas or send funds to wrong addresses

Traditional security (key management, multisig) doesn't help when the threat is your own code making authorized calls with valid signatures.

The Solution

Railguard performs Deep Packet Inspection (DPI) on every eth_sendTransaction and eth_sendRawTransaction call:

  1. Decode the calldata using ABI encoding rules
  2. Match against your policy (allowed contracts, methods, argument limits)
  3. Block violations before they reach the network

All with < 1ms p99 latency and a fail-closed architecture.

Key Features

Fail Closed

If Railguard crashes, your transactions don't leak through. The TCP connection terminates (RST), and nothing reaches the upstream. This is by design.

// Every panic in inspect() becomes a Blocked verdict
let verdict = panic::catch_unwind(|| inspect_inner(tx, policy))
    .unwrap_or(Verdict::blocked("Internal panic - fail closed"));

Deep Packet Inspection

Not just address filtering. Railguard decodes your transaction's calldata and validates:

  • Function selectors (4-byte method signatures)
  • Argument values (decoded ABI parameters)
  • Gas and value limits
[[firewall.rules]]
name = "USDC Safety"
contract = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
allow_methods = ["transfer(address,uint256)"]
arg_constraints = [
    { index = 1, max = "1000000000" }  # Max 1000 USDC per transfer
]

Sub-Millisecond Latency

Selectors are pre-computed at startup, not per-request. Zero-copy inspection means Railguard adds negligible overhead to your transaction flow.

Monitor Mode

Not ready to block? Run in monitor mode to log policy violations without blocking. Perfect for tuning your rules.

[firewall]
mode = "monitor"  # Log violations, don't block

Architecture

Railguard is a Rust Cargo workspace with clear separation of concerns:

CratePurpose
bin/rgCLI, TUI, process management
rg-proxyAxum HTTP server, JSON-RPC handling
rg-policyPolicy engine, ABI decoding, verdicts
rg-typesShared types (Config, Verdict, Receipt)
rg-cloudCloud sync (optional)

Who is Railguard for?

  • DeFi Operators running keeper bots, liquidators, or rebalancers
  • Protocol Engineers deploying contracts with Foundry scripts
  • Institutional Traders needing pre-execution firewalls

Next Steps

On this page