Docs / Models
What leaves the machine
ivralo is built for code that cannot leave the network. This page lists every way something can leave the machine, what switches each one on, and where ivralo tells you it is happening.
The short answer
With a local model, a local embedder and your own PostgreSQL, the code, the documents and the conversation stay on the machine. Each path out is something you configure, and most of them are off until you do.
| Path | What leaves | When |
|---|---|---|
| A hosted model | Prompts, history and tool output | IVRALO_MODEL or a role names a hosted model |
| A hosted embedder | The documents' text, for the index | IVRALO_EMBED_MODEL names a hosted embedder |
| Web search and fetch | The search query, and requests for the pages read | IVRALO_WEB, on by default; ivralo init --server turns it off |
| Spans | Every prompt, tool argument and tool output | Only when IVRALO_OTEL_ENDPOINT is set |
| Mail and chat messages | What a message says, and its attachments | Only when configured, and each send is approved |
| GitHub and Google | What those integrations read and write | Only when their credentials are configured |
| A draft pull request | The branch ivralo made, to your forge | Server mode, or a person's yes |
A web search sends only the query. A query longer than 200 characters, or one that spans lines, is refused, so a document cannot be pasted into a search box. Pages are fetched only from public hosts.
A hosted model is never silent
A model counts as hosted unless its address is loopback, a private address or a local name (Models and providers has the rule). When any role runs on one, ivralo says so:
- the session header shows a
hostedline naming the provider; ivralo askprints the same note above its text output;ivralo doctornames every provider the work goes to, then what that means for incident evidence.
prompts, history and tool output - the text of what the specialists read - go to Anthropic
incident evidence: refused on these models (IVRALO_INCIDENT_HOSTED_MODEL is off)
A hosted embedder is announced the same way. A hosted embedder never sees code unless you set IVRALO_EMBED_CODE_HOSTED; see Embeddings and the index.
Incident evidence
Logs are personal data. An investigation whose model is hosted is refused unless two settings are on:
| Setting | What it says |
|---|---|
IVRALO_INCIDENT_HOSTED_MODEL=true | You accept that the evidence leaves the machine. ivralo incident --hosted sets it for one run |
IVRALO_INCIDENT_MASK=true | Identifiers are replaced with placeholders before the model reads them |
Masking replaces IP addresses, e-mail addresses and the identifiers you name in identifiers.json (in the home, and in the workspace's .ivralo/) with stable placeholders such as <host-1>. The originals are put back in your copy of the report. A hosted run is also refused when identifiers.json names nothing of yours, because masking would then cover only addresses and every host and customer name would leave. Privacy and masking covers the file.
The egress policy
The section above is about ivralo's own connections. The egress policy is about what the agents run: whether a page they fetch, or code and commands they run, may reach a host. One rule decides it at four exits:
- the web fetch;
- the headless browser that renders blocked pages;
- the worker process a specialist's Python runs in;
- the shell.
| Host | Web fetch and browser | Worker and shell |
|---|---|---|
| Link-local, cloud metadata and other non-public addresses | Denied | Denied |
| Loopback, private ranges, local names | Denied | Asks; hosts.allow lifts it |
| Any other host | Allowed | Asks; refused with nobody there unless listed |
An entry in hosts.deny | Denied | Denied |
The web exits judge URLs that someone else may have chosen, so nothing local is ever reachable from them. The worker and the shell run your own code on your own network, so a local host can be allowed there.
You list hosts in permissions.json, in the home or in the repository's .ivralo/:
{
"hosts": {
"allow": ["artifacts.corp.internal"],
"deny": ["tracker.example.net"]
}
}
An entry is a host name or one address. A name covers the names below it, so corp.internal covers git.corp.internal. There are no wildcards, ports or masks. A deny wins over an allow. A repository's own hosts.allow applies only once you have trusted the folder.
In the worker, a name you have not listed is asked about before it is looked up, so a refusal sends nothing, not even a DNS query. The shell judges the hosts a command names as they are written, without DNS.
ivralo reaching its own configured services (the model, the embedder, GitHub, Google, mail, the search backends) is not judged by this policy: those are the paths in the first table.
Tracing is opt-in
Spans are the most complete record of a run: every prompt, every tool argument, every tool output. They go nowhere until IVRALO_OTEL_ENDPOINT names an OTLP/HTTP collector. /v1/traces is added when the URL has no path, and IVRALO_OTEL_SERVICE sets the service name (default ivralo).
The exporter is not in the default install. It comes with the otel extra (uv sync --extra otel in a checkout). If the endpoint is set but the packages are missing, the run goes on untraced with a warning, and ivralo doctor reports it. Observability covers what you can do with the spans.
agno's telemetry is off
agno, the framework ivralo's agents run on, by default posts each run's ids and model name to its own API. ivralo turns that off on every agent and team it builds. There is nothing to set.