Connectors and confinement

A connector declares an address, and the kernel is what performs the call. No connector performs its own network call, not even the Ollama one. The transport refuses any non-local address, at registration and on every call. This page documents the connector registry, the locality rule, and the cases that were tested.

Why the connector does not do its own fetch

A connector is a contribution: a plugin may declare one. If it performed its own fetch, it would call whatever it liked, and the absence of network egress would be nothing more than a promise kept by third-party code.

By separating declaration from transport, the connector never holds the network. The check is therefore carried by the kernel, which ships with the application and can be reviewed in one place, rather than by plugin code installed later.

Declaring a connector

K.connectors.register({ id: 'ollama', source: 'core', title: { fr: 'Ollama (local)', en: 'Ollama (local)' }, base: 'http://127.0.0.1:11434', capacites: ['chat', 'outils', 'flux'], modeles: function () { return K.connectors.fetch('http://127.0.0.1:11434/api/tags') .then(function (r) { return r.json(); }); } });
FieldDescription
idNamespaced identifier.
baseBase address. Validated at registration: a non-local address is refused immediately.
capacitesWhat the connector can do: chat, outils, flux, embeddings.
The refusal is fail-closed at registration, not at call time. A plugin declaring a connector pointing at a remote service is rejected on load, with a line in the journal. There is no window during which the connector exists and could make a call.

The locality rule

K.connectors.isLocal(url) normalises the URL with new URL(), then compares the whole hostname, never its prefix.

AddressVerdictReason
http://127.0.0.1:11434/api/chatAcceptedLoopback.
http://localhost:11434/api/chatAcceptedLoopback.
http://[::1]:11434/api/chatAcceptedIPv6 loopback.
http://2130706433/apiAcceptedDecimal IP. new URL() normalises it to 127.0.0.1.
http://0x7f.1/apiAcceptedHexadecimal IP, normalised the same way.
http://127.1/apiAcceptedAbbreviated IP, normalised the same way.
http://127.0.0.1.evil.com/xRefusedA domain name. Normalisation leaves it intact; a prefix comparison would have accepted it.
https://api.openai.com/v1/chatRefusedRemote host.
http://192.168.1.50/apiRefusedLocal network, but not this machine.
file:///etc/passwdRefusedScheme not allowed.
//evil.com/xRefusedImplicit protocol.
Disguised addresses (decimal, hexadecimal, abbreviated) are checked, not assumed: new URL() normalises them, and the hostname comparison recognises them correctly. The delicate case is a domain name that begins with a loopback address, such as 127.0.0.1.evil.com: comparing the hostname in full refuses it, where a prefix comparison would have accepted it.

The transport

K.connectors.fetch(url, opts) is the only egress point. It applies, in this order:

#CheckOn failure
1Address locality.Rejected, with a line in the journal.
2Redirects are not followed.Rejected. A redirect to a remote host would bypass check 1.
3Outgoing headers are filtered.Internal headers, campaign included, are never forwarded.
The active campaign is propagated by wrapping window.fetch, explicitly filtered to internal API calls. A local connector, Ollama included, therefore never receives the campaign identity or the context of the investigation.

Air-gap mode

Transport confinement is independent of air-gap mode: it applies in every case. In air-gap mode the software attempts no outbound connection at all, including to the community database or the science watch, and the assistant keeps working, since its connector is local.

Troubleshooting

SymptomLikely cause
The Assistant panel reports that no model is available. Ollama is not listening on 127.0.0.1:11434. Check ollama serve.
A plugin connector does not appear. Non-local address, refused at registration. The reason is in the journal.
Ollama runs on another machine on the network. Unsupported configuration: the transport refuses any address outside the loopback, 192.168.x.x included.
Answers arrive all at once, without streaming. Expected behaviour whenever tools are offered to the model.