OrmAI

Architecture

How OrmAI works.

OrmAI sits between your agent and your ORM as a policy-enforced runtime. Every database call travels the same path — evaluate, compile, redact, audit — with no raw SQL in sight.

        AI agent (LLM)
              │  db.query / db.aggregate / db.update ...
              ▼
   ┌───────────────────────────┐
   │      OrmAI runtime        │
   │  ┌─────────────────────┐  │
   │  │  Policy evaluation  │  │  models · fields · budgets · writes
   │  └─────────┬───────────┘  │
   │            ▼              │
   │  ┌─────────────────────┐  │
   │  │  Compile + scope     │  │  parameterized · tenant_id injected
   │  └─────────┬───────────┘  │
   │            ▼              │
   │  ┌─────────────────────┐  │
   │  │  Redact response     │  │  deny / mask sensitive fields
   │  └─────────┬───────────┘  │
   │            ▼              │
   │  ┌─────────────────────┐  │
   │  │  Immutable audit log │  │  principal · trace · decision
   │  └─────────────────────┘  │
   └────────────┬──────────────┘
                ▼
      Your ORM  →  Your database

One boundary. Every guardrail applied on every call.

  1. 01

    The agent calls a typed tool

    Instead of generating SQL, the agent calls db.query, db.get, db.aggregate, db.create, db.update, or db.delete with structured arguments — model, filters, limits. There is no free-text SQL to inject.

  2. 02

    The policy runtime evaluates the call

    OrmAI checks the call against your declarative policy in-process: is this model allowed, are the requested fields permitted, does the row/join/timeout budget hold, and is the operation (read or write) enabled for this principal?

  3. 03

    It compiles to a parameterized ORM operation

    The approved call is compiled to a parameterized operation on your existing ORM (SQLAlchemy, Prisma, Drizzle, …). Tenant scope is injected from the RunContext. SQL injection is structurally impossible.

  4. 04

    Results are redacted, then returned

    Denied fields are dropped and masked fields are transformed before the response leaves the boundary. The agent only ever sees what policy allows.

  5. 05

    Every call is audited

    Before the result returns, OrmAI writes an immutable audit row: principal, tenant, trace ID, sanitized inputs, and the policy decision. Isolation and access are provable after the fact.

Ready to see the code?

Wire OrmAI into FastAPI and SQLAlchemy in about five minutes.