Security and data boundaries
RLM code always executes inside your boundary. ModelRelay is the control plane: it authorizes routes, enforces budgets, meters usage, and records evidence. It does not run your recursive program, and it never receives your query, context, corpus, Python code, stdout, or stderr.
That is not the same as saying no bytes leave. The root-model request and every llm_query or llm_batch prompt are inference calls, and they travel through ModelRelay to the selected model provider. RLM separates data access and code execution from model subcalls so you can control what each layer receives.
Where each piece runs
| Layer | Location | What it sees |
|---|---|---|
| Generated Python | Your machine, VPC, or application process | Everything the process can reach: attachments, SQL results, MCP tool output |
| Data adapters (SQLite, PostgreSQL, Snowflake, MCP) | Same boundary, in a trusted host process | Credentials, connections, raw rows |
| Root and subcall prompts | ModelRelay → model provider | Only what the generated code puts in a prompt |
| Execution evidence | ModelRelay | Content-free facts: routes, limits, usage, cost, typed failures |
Document the complete route for each deployment:
data source → local sandbox → root/subcall prompt → ModelRelay routing → model provider
Local CLI
In mrl rlm:
- Python executes on your machine.
- Attached file paths are opened on your machine.
- Database credentials and connections remain local; generated code receives only a capability binding.
- The root-model request and any
llm_queryorllm_batchprompts go through ModelRelay to the selected model provider. - Generated code decides which values are included in those model prompts.
Do not expose highly sensitive columns merely because the database connection is local. Generated Python runs with the current user’s local file access, so a SQL profile is a behavioral guardrail rather than a sandbox boundary. Use a restricted database copy or an operating-system boundary when the model must not read particular tables.
VPC and application deployments
Placing the engine beside your data in your own infrastructure has the same boundary as the local CLI, with two differences worth planning for:
- Run it under a dedicated least-privilege service account, not a developer’s login. Generated Python inherits whatever that account can reach.
- Model provider calls still receive selected prompt content unless you also route to an in-boundary model endpoint.
Use an execution grant when the engine runs on behalf of one of your customers. The grant gives ModelRelay a hard integer spend ceiling, per-callback admission and metering, and immutable content-free evidence — without ModelRelay seeing the task.
SQL controls
Local SQLite is opened read-only, which prevents mutation but not unauthorized reading by generated Python running as the current user. Production deployments should enforce policy outside the model:
- Use a database user without write privileges.
- Allowlist schemas, tables, and columns.
- Cap returned rows and response bytes.
- Block multiple statements and mutation operations.
- Exclude or redact sensitive columns before they reach the sandbox.
- Record the executed SQL for audit.
Model instructions are not a security boundary. Enforce data access in the adapter, SQL policy, database role, and network configuration.
Connector controls
The PostgreSQL, Snowflake, and remote MCP connectors all follow one rule: the credential lives in a trusted host process, and generated Python receives only a bounded capability.
- Keep DSNs, warehouse credentials, and OAuth material in environment variables resolved by the host, never in flags or generated code.
- Snowflake goes further and splits the broker into its own process or container; the runner gets a short-lived capability token and no Snowflake configuration.
- Classify every MCP tool as read-only.
mrlrejects effectful tools because this surface has no user-confirmation policy. - Enforce timeouts, row counts, and response-byte caps in the host. Queries that exceed a limit must fail closed rather than truncate silently.
See PostgreSQL, Snowflake, and Remote MCP providers for the exact configuration each connector accepts.