Run Codex CLI with self-hosted models in air-gapped or restricted networks.
airgap-coder connects the OpenAI Codex CLI to vLLM, SGLang, and other self-hosted Chat Completions services through a pinned LiteLLM gateway. Its zero-dependency lc management CLI generates configuration, keeps private values out of Git, validates tool calling, and builds checksummed offline deployment bundles.
Codex CLI --Responses API--> LiteLLM --Chat Completions--> self-hosted model
host or container gateway private GPU network
Important
airgap-coder does not include a model or inference server. Your exact model, chat template, tool parser, inference-server version, and Codex version must pass lc doctor, lc test, and lc e2e together.
Modern Codex releases use the Responses API, while many self-hosted inference stacks expose Chat Completions. A working HTTP endpoint is not enough: coding agents also depend on reliable function calling, correct context limits, and consistent configuration across machines.
airgap-coder provides:
- Protocol translation — a pinned LiteLLM gateway converts Responses requests into Chat Completions requests.
- Secret separation — endpoints, API keys, and private header values stay in an ignored, mode-
0600.envfile. - Team-safe configuration —
registry.jsonstores model structure and environment-variable names, not resolved private values. - Behavioral diagnostics —
lc doctor,lc test, andlc e2edistinguish connectivity from usable tool calling. - Offline delivery —
lc exportpackages tracked source, container images, a manifest, and checksums for approved transfer. - Deterministic checks — CI validates secret invariants and the Responses-to-Chat-Completions bridge without a GPU, real model, or OpenAI API key.
Requirements: Python 3.9+, Docker with the Compose plugin, and Codex CLI 0.145.0.
git clone https://github.com/LouisDM/airgap-coder.git
cd airgap-coder
npm install -g @openai/codex@0.145.0
./bin/lc init # configure a self-hosted upstream
./bin/lc up # start the LiteLLM gateway
./bin/lc test # validate protocol and tool callingThen start Codex from the project you want to work on. The tool directory and your working directory are different things:
cd ~/your-project
~/airgap-coder/bin/lc code # start Codex with the selected upstreamImportant
lc code runs Codex in the current directory under approval_policy = "never", so the model can read that directory without asking. Starting it inside the airgap-coder directory puts .env — every upstream endpoint and credential — in reach of a single cat. lc code refuses to start when it detects this. If you really do want Codex to work on that directory — the one case being changing airgap-coder itself — pass --allow-workspace-secrets, which starts the session and still prints the warning. See Credentials in the Codex workspace.
lc init asks for the upstream URL, credential, model ID, context window, and backend family. Resolved endpoints and credentials are written only to .env; the shareable structure is written to registry.json.
This path does not require an OPENAI_API_KEY. It uses your self-hosted model credential instead. Maintainers can also run read-only local Codex review with an existing ChatGPT sign-in.
Build the pinned image on a connected staging machine, transfer it through your approved process, then point it at the internal gateway. Mount the project you want Codex to work on — not the airgap-coder directory:
docker run --rm -it -v "/path/to/your-project:/workspace" \
-e GATEWAY_URL=http://gateway.your-intranet.local:4000/v1 \
-e GATEWAY_KEY=your-gateway-key \
-e MODEL=your-model \
airgap-coder:0.1.0 exec "inspect this repository"Important
In the container Codex runs with sandbox_mode = "danger-full-access", because its Landlock/seccomp sandbox is unreliable inside many container runtimes; the container itself is the isolation boundary. That boundary only holds if the mount holds. Mounting the airgap-coder directory — where lc init just wrote .env — puts every upstream endpoint and credential inside the workspace. The entrypoint refuses to start when it finds a .env in the workspace; mount your own project instead, or pass -e AIRGAP_ALLOW_WORKSPACE_SECRETS=1 to allow it explicitly (which still prints the warning). See Credentials in the Codex workspace.
See the complete offline deployment guide before crossing a network boundary.
lc initorlc addwrites private values to.envand non-secret model structure toregistry.json.lc syncgenerates ignored LiteLLM and Codex configuration from those two sources.- LiteLLM accepts
/v1/responsesfrom Codex and sends/v1/chat/completionsto the selected upstream. lc testchecks the protocol bridge and tool-call shape;lc e2everifies that Codex can perform a controlled code edit.lc exportcreates a self-contained deployment bundle for an isolated environment.
Read architecture for components and trust boundaries.
| Command | Purpose |
|---|---|
lc init |
Configure the first upstream interactively |
lc add, lc rm <name>, lc ls |
Manage upstream definitions |
lc use <name> |
Select the default upstream |
lc up, lc down, lc status, lc logs |
Manage the gateway |
lc test [name] |
Run protocol and tool-calling checks |
lc e2e [name] |
Ask Codex to edit a fixture and verify the result |
lc code [--allow-workspace-secrets] [...] |
Start host-side Codex with the selected upstream; refuses when .env is in the workspace unless allowed explicitly |
lc doctor |
Diagnose versions, proxy settings, connectivity, and tool calling |
lc sync |
Regenerate LiteLLM and Codex configuration |
lc migrate |
Move legacy plaintext header values into .env |
lc export [--no-images] [--no-registry] |
Create a checksummed, self-contained offline bundle |
lc version |
Print the airgap-coder version |
Run ./bin/lc help for the built-in reference.
The upstream must expose an OpenAI-compatible Chat Completions endpoint and return structurally valid function calls. A typical vLLM launch includes:
--enable-auto-tool-choice --tool-call-parser hermes --max-model-len 131072For Qwen-family models, disabling thinking mode commonly improves tool-call parsing. airgap-coder supports both common parameter shapes:
- vLLM/SGLang:
chat_template_kwargs: {"enable_thinking": false} - hosted gateways: top-level
enable_thinking: false
These are starting points, not universal compatibility claims. Validate the exact deployment and submit reproducible results through the compatibility report.
.env, generated Codex profiles, and generated LiteLLM configuration are ignored by Git.- Offline export includes tracked source and a validated
registry.jsonby default, while excluding.env, generated configuration, Git history, and local Codex state. Export refuses legacy plaintext header values;--no-registrycreates a generic bundle without the registry. - Release source archives include SHA-256 checksums and GitHub build provenance attestations.
- airgap-coder has no telemetry, but the model service, gateway, container runtime, and Codex runtime remain separate trust boundaries and may have their own logging behavior.
- A checksummed bundle proves integrity, not that its contents are approved for a particular isolated environment.
Read the full threat model and security policy. Report vulnerabilities privately through GitHub Security Advisories, not a public issue.
| Layer | Repository verification | What it does not prove |
|---|---|---|
| Management CLI | Syntax, metadata, version, config, and secret-invariant tests | A specific organization's deployment policy |
| Protocol bridge | GPU-free Responses → Chat Completions → function-call integration test | Real-model tool quality or multi-turn reliability |
| Container | Pinned base image, startup, argument routing, and Docker CI | Compatibility with every host runtime |
| Release | Reproducible source archives, checksums, and build provenance | Approval to import artifacts into an isolated network |
The maintained baseline and real-backend reporting rules live in the compatibility policy. airgap-coder is an early-stage community project; use the latest release rather than assuming main is stable.
| Topic | Guide |
|---|---|
| Installation and concepts | Documentation index |
| Components and data flow | Architecture |
| Transfer into an isolated network | Offline deployment |
| Common failures | Troubleshooting |
| Tested versions and reporting | Compatibility |
| Secrets and trust boundaries | Threat model |
| Local review without an API key | Codex workflow |
| Release history | Changelog |
- Ask setup questions and share deployment patterns in Discussions.
- Open reproducible bugs and feature requests through the issue templates.
- Read CONTRIBUTING.md before submitting code or documentation.
- Add an opt-in, publicly verifiable deployment to the adopters list.
- Interested in long-term maintenance? See the maintainer invitation.