Version 1.0.0
Architecture
The four roles in the reference architecture, the flows allowed and forbidden between them, and the deployment modes.
Lemniscate provides the confined runtime environment for code agents, deployed inside your perimeter. The reference architecture separates four roles: the developer workstation, the gateway services, agent execution and inference. Lemniscate provides the first three and connects to your inference engine (security white paper V3, section 3).
The gateway is the only component that talks to all the others. It holds the policies, the log and revocation.
The overall picture
Section titled “The overall picture”The four roles and the trust zones
Section titled “The four roles and the trust zones”Each role occupies one machine, physical or virtual, with a known exposure surface (security white paper V3, section 3.1).
| Role | What it carries | What bounds it |
|---|---|---|
| Developer workstation | the extension alone: VS Code, JetBrains or terminal | it passes on the instruction, shows the diffs and the approval requests, and knows only the gateway address |
| Gateway services host | the gateway, the database and the administration console | the gateway is the only interface exposed to workstations |
| Execution host | one sandbox per session, with a working copy of the repository | separate from the gateway host, stateless between sessions, a single inbound control channel opened by the gateway |
| Inference server | the inference engine and the open-weights model | reached by the gateway alone |
The product’s trust perimeter comes down to two components: the gateway and the sandbox. The model and the agent are excluded from it. They are treated as untrusted components, and no right depends on their behaviour.
The directory and the SIEM are yours. The gateway connects to them for authentication (OpenID Connect) and for log export.
The allowed and forbidden network flows
Section titled “The allowed and forbidden network flows”The flow matrix fits in eight rows (security white paper V3, section 3.3). Four flows are allowed, all internal to the perimeter. Four are forbidden by construction.
| Status | Flow | Detail |
|---|---|---|
| Allowed | Workstation to gateway | TLS; the only workstation flow related to Lemniscate |
| Allowed | Gateway to execution host | single control channel, opened by the gateway; no flow in the other direction |
| Allowed | Gateway to inference engine | TLS and network filtering; only the gateway host is allowed to reach the engine |
| Allowed | Gateway to directory and SIEM | authentication and log export; addresses set by you |
| Forbidden | Sandbox to any network | no network interface, no name resolution |
| Forbidden | Workstation to execution host or engine | no route; the extension knows only the gateway address |
| Forbidden | Any component to the Internet | no flow leaving the perimeter, no telemetry |
| Forbidden | Execution host to any component | the host never initiates a connection |
Sandboxes are created with no network interface, no route exists between the workstation and the execution host or the engine, no component has an external address, and the execution host is not a client of any other component.
Access to the inference engine is controlled at the network level: the engine listens only on the inference server’s internal network, and your filtering allows the gateway host alone. You can verify the matrix with your own probes. A flow observed outside this matrix is handled as an incident. The detail of what travels on each flow is in Where the data goes.
Connecting to what you already have
Section titled “Connecting to what you already have”Lemniscate sits alongside what is already in place (security white paper V3, section 3.4). The gateway connects to any inference engine that exposes an OpenAI-compatible API, with the open-weights model you choose. The directory and the SIEM are yours.
Two deployments follow from this:
- integrated into your stack: you keep your agent, your model proxy and your inference engine, and Lemniscate adds confined execution, the policies, the log and revocation; see Integrate Lemniscate into your stack;
- full code assistant: Lemniscate also provides the extension, the agent, the model access gateway and the setup of the inference server; see Install the full assistant.
The four deployment modes
Section titled “The four deployment modes”The same product is deployed in four modes (security white paper V3, section 3.4).
| Mode | What characterises it |
|---|---|
| D01, connected | standard internal network; updates through your private registry |
| D02, isolated | no connection; delivery and updates by signed archive on media, verifiable offline |
| D03, sensitive or Restricted Distribution | dedicated execution host; nothing runs on the workstations, no container engine is required there |
| D04, classified | dedicated enclave; artefacts provided in support of your accreditation |
Accreditation remains a decision for your authority. The artefacts the vendor provides in support of it are described in Compliance posture.
The dedicated execution host is the reference mode. A variant runs the sandbox on the workstation, in an unprivileged container with no network; it suits workstation baselines that already allow a container engine. The two are compared in The execution safeguards.
core, the extension logic
Section titled “core, the extension logic”The logic shared by the three forms of the extension lives in core/: the
dialogue with the gateway for model calls (core/llm), the tools the agent can
request (core/tools), the context providers (core/context), configuration loading
(core/config) and the message protocol that ties it all together (core/protocol).
The code is read by exploring the repository on demand. Lemniscate builds no index of the source code: there is no persistent derived copy of the code to be protected (security white paper V3, sections 3.2 and 11.3).
The wrappers reimplement none of these functions. What changes from one wrapper
to another is how core is hosted:
| Wrapper | Hosting of core |
|---|---|
| VS Code | in the extension process, through an in-memory messenger |
| JetBrains | in a separate subprocess, JSON dialogue over standard input and output |
CLI lemni | linked into the program at build time |
On the VS Code side, VsCodeExtension.ts instantiates core behind a InProcessMessenger: a
function call, with no process boundary.
On the JetBrains side, the plugin is in Kotlin and cannot load TypeScript.
core is therefore packaged separately in binary/, which CoreMessenger.kt starts as a
subprocess and sends JSON messages carrying a messageId, a messageType and a payload.
Replies come back over the same channel; those concerning the interface are
forwarded to the embedded browser. The USE_TCP environment variable switches this
channel to a TCP connection, for debugging.
On the CLI side, the extensions/cli build resolves core/ and packages/* through aliases:
the published program contains the logic and does not load it from elsewhere.
gui, one interface for two IDEs
Section titled “gui, one interface for two IDEs”gui/ is a React application: the product’s full screen inside the IDE, with the
conversation, the agent, the history and the settings page. It is not a component
library.
Both extensions embed it. The VS Code extension packaging builds gui/ and
checks that the bundle is present before producing the VSIX; the JetBrains plugin
serves the same bundle from its resources, in an embedded JCEF browser.
The interface knows which IDE it runs in because the page that loads it writes
this into local storage, under the ide key: vscode on one side, jetbrains on the
other. gui reads this value to adapt the keyboard shortcuts and a few screens.
The CLI does not use gui: its interface is the terminal.
The gateway services
Section titled “The gateway services”The three services are installed on your side, on a host separate from the execution host and the inference server (security white paper V3, section 6). The gateway is the enforcement point for all policies; the database and the console serve it.
llm-gateway, the gateway
Section titled “llm-gateway, the gateway”A Hono server. The inference relay is one route, ALL /:endpoint/*: the first path segment
names an endpoint configured in the database; the rest, path and query string, is
forwarded to the base URL of the associated inference engine. Other routes are
placed before this relay, under reserved prefixes (/ide/ for what the
workstation asks of the gateway, the offline documentation, command execution);
an endpoint cannot carry one of these names.
Before relaying, the gateway chains checks in a fixed order: verification of the caller’s identity, revocation list, endpoint resolution, deployment licence, authorisation policy, right to consume, engine key if the engine declares one, then the relay. An unknown endpoint is refused without the right to consume being consulted.
It imposes no schema on the request body. A body that reads as JSON has its model
field replaced by the endpoint’s; a body it cannot read goes through unchanged. A
text/event-stream response is relayed as it streams.
gateway-db, the database
Section titled “gateway-db, the database”A PostgreSQL database. It holds the configuration the console writes (declared
inference engines, models, published endpoints, policy), the revocation list, the
log of authorisation decisions, the agent actions deposited by the workstations
and request_logs, one row per relayed request.
It does not hold the access key for an inference engine. For each declared
engine, it records the name of the environment variable that carries the key and
the HTTP header to place it in. The key itself exists only in the environment of
the llm-gateway process.
gateway-admin, the console
Section titled “gateway-admin, the console”A React application served by its own server, reserved for administrators. In a customer installation, it shows three tabs: the endpoints (Endpoints), the policy (Policy) and the agent actions (Audit). See Open the administration console. It is where engine or model declaration, endpoint publication and policy writing happen.
The console writes directly to the database, with its own connection string. It does not go through the gateway, and the gateway does not talk to it. The coupling between the two services is the database.
The gateway re-reads the database on every request, with no cache: a change made in the console takes effect on the next request, with no restart.
What the diagram does not show
Section titled “What the diagram does not show”- The variant where the sandbox runs on the workstation. The drawing shows the reference mode, the dedicated execution host.
- The session cycle: authentication, project policy, sandbox opening, agent work, diff and approval. It is described in The agentic session cycle.
- What the gateway does with a model call, check by check; see The role of the gateway.
- The functions inherited from the project Lemniscate comes from that do not go through; see What does not exist.