eparch
GitHubGet started

Air-Gapped / Offline Deployment

Eparch is designed to run inside a regulated or classified boundary with no outbound network access. Nothing in the running system needs to reach the public internet.

Why it works with zero egress

Concern Default (SaaS) Air-gapped setting
User login WorkOS AuthKit (external) AUTH_MODE=local — built-in email/password, no external IdP
Model inference managed model gateway self-hosted vLLM / Ollama / TGI on your network
State Postgres, Redis, MinIO all self-hosted (bundled)
Authorization OPA (self-hosted) bundled
Container images pulled at deploy time pre-loaded from the offline bundle

There is no telemetry phone-home. OTEL_EXPORTER_OTLP_ENDPOINT is empty by default; set it only to an OTLP collector inside your boundary.

1. Build the image bundle (on a connected host)

scripts/airgap-bundle.sh build ./airgap-bundle

This pulls the runtime dependency images (Postgres/pgvector, Redis, MinIO, OPA, golang-migrate), builds the Eparch monolith + identity images, and writes a single compressed tarball plus a manifest.txt and SHA-256 checksum.

2. Transfer

Move ./airgap-bundle/ across your air-gap boundary by whatever means your environment allows (removable media, one-way diode, review gateway). Verify the checksum on arrival:

cd airgap-bundle && sha256sum -c eparch-airgap-images.tar.sha256

3. Load + run (on the air-gapped host)

scripts/airgap-bundle.sh load airgap-bundle/eparch-airgap-images.tar.gz

cp deploy/.env.example deploy/.env
# Edit deploy/.env:
#   - keep AUTH_MODE=local
#   - set POSTGRES_PASSWORD / EPARCH_APP_PASSWORD / EPARCH_SECRET_KEY / JWT_RSA_PRIVATE_KEY
#   - point LLM_GATEWAY_URL / LLM_EMBEDDING_URL at your in-boundary model server

docker compose -f deploy/docker-compose.monolith.yml --env-file deploy/.env up -d

The first user to register (via the UI or POST /auth/local/register) becomes the tenant admin.

4. The model server (your responsibility)

The bundle does not include model weights — pre-stage those with your serving engine inside the boundary. Any OpenAI-compatible endpoint works:

  • vLLM: python -m vllm.entrypoints.openai.api_server --model /models/llama-3.3-70bLLM_GATEWAY_URL=http://vllm:8000/v1/chat/completions
  • Ollama: ollama serve with pre-pulled models → LLM_GATEWAY_URL=http://ollama:11434/v1/chat/completions

Register the exact model names you serve with LLM_MODELS (see model-providers.md). An in-boundary model server on a trusted network needs no upstream auth — leave LLM_API_KEY empty.

5. Updates

Rebuild the bundle on a connected host when a new Eparch version is released, transfer it, load, then follow the upgrade steps in operations.md (pull → run migrations job → restart).

Air-gap checklist

  • AUTH_MODE=local (no WorkOS egress)
  • LLM_GATEWAY_URL / LLM_EMBEDDING_URL point at an in-boundary model server
  • OTEL_EXPORTER_OTLP_ENDPOINT empty, or an in-boundary collector
  • WORKOS_* unset
  • All images loaded from the bundle (docker images | grep -E 'eparch|pgvector|opa')
  • Model weights staged with your serving engine

Edit this page on GitHub →