AI-First Security Tooling for Ruby & Rails

Rails + AI gives you speed-to-market. MechaRuby is the armor.

AI agents can ship a feature in thirty seconds—and open ten security holes along the way. The mecha_* gems are AI-first libraries built to give coding agents one central registry to read and fast, deterministic feedback when they drift. Build software at scale without creating security nightmares.

Why AI Needs Mechanical Guardrails

Why scattering critical boundaries across hundreds of files breaks both human teams and AI agents.

Ruby on Rails and AI coding agents give small teams superpowers. An agent can generate models, controllers, and migrations in minutes that used to take a team all week. We love that speed.

But Rails leaves your sharpest boundaries open by default. Add a new route, and any logged-in user can hit it unless the agent remembers the right before_action. Add a controller action, and one bare Message.find(params[:id]) leaks another customer's data. Add a database column, and sensitive tokens sit in plaintext until someone notices in a post-mortem.

Traditional teams rely on tribal conventions, manual PR checklists, or policy objects scattered across dozens of files. AI agents cannot read rules that live in a senior developer's head. When your security model is spread across a hundred files, an agent has to guess—and one bad guess ships a breach.

Give AI agents a single source of truth and a compiler-grade feedback loop: declare every boundary in one YAML file, enforce it at runtime, audit it statically in milliseconds, and attack it automatically in CI.

That is the MechaRuby approach. Each mecha_* library gives coding agents clear, consistent, line-numbered feedback so they fix violations before code ever ships. No magic DSLs. No guesswork. Just mechanical certainty.

One Architecture. Three Guarantees.

Every MechaRuby gem enforces the same three-step feedback loop for humans and AI coding agents.

01 / CENTRAL REGISTRY

Closed by Default

Declare every route, model, and database column in a single YAML registry. Humans and AI agents read and update one file instead of hunting across the codebase. If a resource is not in the file, the system rejects it immediately.

02 / STATIC AUDITOR

Deterministic Agent Feedback

Inspect your Rails routes, Prism controller ASTs, and database schemas in milliseconds. Unmapped resources and unscoped queries fail with exact file-and-line instructions that AI agents fix on the first pass.

03 / BEHAVIORAL PROBER

Live Attack Matrices

Do not trust static config alone. Built-in probers fire real requests across every persona, run cross-tenant IDOR attacks, and verify database ciphertexts in CI.

Authorization belongs in a single file, not scattered across forty controllers.

In a typical Rails app, answering "who can access POST /webhooks/stripe?" requires grepping routes, tracing controller inheritance chains, and praying an AI agent did not add skip_before_action three commits ago.

mecha_authorize replaces scattered controller callbacks with config/mecha_authorize.yml. Every route and HTTP verb maps to explicit boolean roles.

Unmapped routes return 404. Period.

  • Single-file context for AI & humans: Audit or update your entire application's access matrix in one YAML file.
  • Actionable static parity check: Fails immediately when an agent adds a route without mapping it in mecha_authorize.yml, leaves a dead rule, or mounts an engine that bypasses authorization.
  • Behavioral persona prober: Dispatches live test requests across every route for every role (guest, user, API client, admin) to prove runtime enforcement.
config/mecha_authorize.yml YAML
routes:
  - route_pattern: "/login"
    verb: "GET"
    public: true
    admin: false
    user_ui: false
    user_api: false

  - route_pattern: "/messages/:id"
    verbs: ["GET", "PATCH", "DELETE"]
    public: false
    admin: false
    user_ui: true
    user_api: true

  - route_pattern: "/admin/*"
    verb: "*"
    public: false
    admin: true
    user_ui: false
    user_api: false
$ bin/rails mecha_authorize:verify CLI
Running MechaAuthorize static route audit...
  -> 84 routes mapped to explicit authorization rules
✓ Static route authorization audit passed: 0 dead rules, 0 engine bypasses.

Running MechaAuthorize behavioral persona matrix test suite...
  -> Probed 336 route/persona combinations (public, admin, user_ui, user_api)
✓ 336 assertions, 0 failures, 0 errors.

Make cross-tenant data leaks a syntax error, not a production incident.

AI agents default to standard Rails idioms like Invoice.find(params[:id]). That single unscoped line leaks another customer's data, and human pull-request reviews will never catch every occurrence at scale.

mecha_tenant forces every model into the light. You classify each ApplicationRecord subclass in config/mecha_tenant.yml as either tenant (with an explicit ownership path and scope resolver) or global.

In controllers, code queries tenant data through tenant_scope(Model). If an action does not touch tenant data, it must call skip_tenant_enforcement! with a written reason.

  • Prism AST feedback for agents: Parses every controller with Ruby's Prism parser and prints the exact file, line, and required tenant_scope(Model) call whenever an agent writes a bare model query.
  • Strict model registry: Generating a new model without registering its tenancy classification in mecha_tenant.yml fails the audit immediately.
  • Automated IDOR prober: Seeds victim and attacker records, verifies scope isolation for every model, and fires cross-tenant requests at your parameterized routes.
app/controllers/messages_controller.rb RUBY
class MessagesController < ApplicationController
  # Bare `EmailMessage.find(params[:id])` fails the Prism AST audit.
  # Every tenant lookup goes through `tenant_scope`:
  def show
    @message = tenant_scope(EmailMessage).find(params[:id])
  end
end
$ bin/rails mecha_tenant:verify:static CLI
Running MechaTenant static model & controller AST audit...
  -> 24 models registered (21 tenant, 3 global)
  -> 84 controller routes audited (76 enforced, 8 explicitly skipped)

ERROR: Found 1 unscoped model reference violation(s) in controllers:
  - app/controllers/drafts_controller.rb:19 [DraftsController#destroy]
    Direct query on tenant model 'EmailDraft' must use tenant_scope(EmailDraft)
      EmailDraft.find(params[:id]).destroy!

Account for every column in your database. Encrypt secrets; justify the rest.

Rails 7+ ships with excellent ActiveRecord encryption. The hard part is not encrypting a column. The hard part is when an AI agent generates three new tables during a feature sprint and leaves OAuth tokens or PII sitting in plaintext.

mecha_encrypt brings closed-by-default discipline to your database schema. Every table and column must be registered in config/mecha_encrypt.yml.

If you set encrypted: false on a column, you must write a comment explaining why plaintext storage is safe. No silent defaults.

  • 100% schema parity: When an agent runs a migration that adds a column, the audit fails with the exact missing table and column name until it is classified in mecha_encrypt.yml.
  • Model vs. YAML verification: Catches columns marked encrypted in YAML that lack encrypts :column on the ActiveRecord model (and vice versa).
  • Index & ciphertext prober: Verifies raw database ciphertexts, tests round-trip decryption, and catches B-tree indexes placed on non-deterministic encrypted columns.
config/mecha_encrypt.yml YAML
tables:
  email_accounts:
    id:
      encrypted: false
      comment: "Primary key UUID identifier"
    email_address:
      encrypted: true
      deterministic: true
    oauth_refresh_token:
      encrypted: true
      deterministic: false
$ bin/rails mecha_encrypt:verify CLI
Running MechaEncrypt static database & model encryption audit...
  -> 24 tables audited (3 framework/engine tables ignored via pattern)
  -> 198 columns audited (42 encrypted, 9 deterministic, 147 unencrypted)
✓ Static database encryption audit passed: 0 unregistered columns.

Running MechaEncrypt behavioral encryption & index safety test suite...
  -> Verified raw ciphertext envelopes & IVs across 51 encrypted columns
  -> Verified 0 non-deterministic columns covered by broken B-tree indexes
✓ All encryption & index safety checks passed.