# Run it in your own boundary — enterprise & on-prem

> **Status: shipped and runnable today (VPC tier).** The entire Witbitz runtime — the app, the agent, the sealed
> ledger, admission — runs inside your own network, off our cloud, on infrastructure you control. One switch (`AIRGAP=1`)
> takes it to zero egress. The one piece still in progress is a *self-hosted model* for the fully air-gapped case
> (below).

Enterprises increasingly won't send their data — or their AI — to a third party. Witbitz answers that literally: you
run the whole thing yourself. And the design keeps this from forking the product — **every external dependency is a
single environment switch that defaults to the hosted behavior when unset.** The build we run for the public and the
build you run in your tenant are the same reproducible image; you just point its seams at your own infrastructure. Same
code, same [verifiable-privacy](https://docs.witbitz.chat/docs/verify.md) properties, your boundary.

## Two tiers

| Tier | Boundary | Model | Who it's for |
|---|---|---|---|
| **VPC** | your cloud tenant; may reach your chosen model API + map services | your own cloud key (OpenAI / Azure) | most enterprise buyers |
| **Air-gapped** | no egress at all | a self-hosted model, in-boundary | defense · government · regulated |

The VPC tier is a complete, operable product now. The air-gapped tier is one switch away — except for the self-hosted
model, which is the remaining substantial piece.

## One command

The runtime ships as a single container plus a Compose stack that wires the whole thing — the app, an S3-compatible
object store for the sealed ledger, the record store, and a reverse proxy with automatic TLS:

```bash
cp space.env.example space.env          # your model key + a domain
docker compose up -d --build            # the whole stack, off our cloud
curl https://space.your-co.com/space-config
```

There is no per-app server to stand up and no dependency on our infrastructure. The app the browser loads is the same
static, egress-locked, [reproducibly-built](https://docs.witbitz.chat/docs/verify.md) page — now served from your host.

## What each concern maps to

Every seam is a switch. Unset, it's the hosted default; set, it points at infrastructure you own.

| Concern | Runs on | Switch |
|---|---|---|
| **Model** | any OpenAI-compatible endpoint — your cloud key, Azure, or a self-hosted vLLM / Ollama | `LLM_BASE_URL` |
| **Object store** (the sealed ledger) | MinIO or any S3-compatible store | `S3_ENDPOINT` |
| **Records** (Spaces + Bridges) | a local store (single node) or **Postgres** (multi-node HA) | `DATABASE_URL` |
| **Secrets** | mounted files — a Kubernetes Secret or a Vault agent — instead of a cloud secrets manager | `SECRETS_BACKEND=file` |
| **Who may join** | **your own identity provider** — Okta, Entra, or Keycloak — as a trusted OIDC issuer | `SPACE_OIDC_ISSUERS` |
| **Operations** | backup / restore, a retention sweep, bounded log rotation | included in the kit |
| **Zero egress** | refuse every outbound path — see below | `AIRGAP=1` |

### Your identity provider

An email-gated Space admits members who sign in with an issuer you trust. Register your corporate IdP and it's
authoritative — no dependency on any consumer sign-in. It's additive and fail-closed: a registered issuer can't weaken
the built-in ones, the audience is checked (so a token minted for another app can't be replayed), and the Space's own
membership list still decides who's actually in. The IdP only proves *identity*; the Space decides *admission*.

### Operate it

The record store has no silent auto-expiry, so retention is explicit: a sweep reaps Spaces idle past a window you set
(records carry no timestamps — they hold no plaintext — so "idle" is measured from the last write). Backup captures the
sealed ledger, the records, and the secrets in one archive. Logs rotate with a bound and stream to your stack (Loki /
ELK / your SIEM). For high availability, switch the record store to Postgres and run more than one node.

## Air-gap — zero egress

`AIRGAP=1` makes the runtime refuse *every* outbound path, and it does so in ways you can check independently:

1. **The browser.** The served Content-Security-Policy drops every external host. Read the header and it names zero
   off-box destinations — the browser itself refuses any external fetch.
2. **The server.** The map / route proxies stop calling out, and the agent's internet-touching tools (web search,
   place lookup, flights, external photos, URL fetch) are refused at a single chokepoint — so even a Space configured
   with them can't reach out.

Chat, the agent, document reading, PDF generation, charts and diagrams, and IdP admission all keep working. The one
egress this switch can't close is the **model call itself** — point `LLM_BASE_URL` at a self-hosted, in-boundary model
or the turn still leaves the network (the runtime warns loudly at boot if you don't). Standing up an open-weights model
and assessing its quality against a frontier model is the remaining air-gapped-tier work.

## The trust story gets *stronger*, not weaker

Hosted, our signed [`/cert.json`](https://docs.witbitz.chat/docs/verify.md) and reproducible build let a skeptic
confirm the operator — us — is **blind to your data in use**. On-prem there is no third-party operator at all, so the
cert's meaning inverts into **supply-chain proof**: *the image you are running is byte-for-byte the audited source —
nothing was smuggled in.* And air-gapped, "no data leaves" stops being a promise and becomes something you verify on
your own terms:

- **No data leaves** — read the CSP off the served page: zero external hosts. Confirm the proxies refuse.
- **The code is the audited code** — reproduce the build from published source and match the running image's hash;
  `op:attest` returns the exact build commit the box is running.

This is where [verifiable privacy](https://docs.witbitz.chat/docs/verified-rooms.md) is at its strongest: both halves
are checkable by you, on hardware you control, without trusting us at all.

## Verify a running deployment

```bash
# the egress allowlist, as a header — in air-gap it names no external host:
curl -sD- https://space.your-co.com/ -o /dev/null | grep -i content-security-policy
# the exact build the box is running:
curl -sXPOST https://space.your-co.com/space -H 'content-type: application/json' -d '{"op":"attest"}'
```

## Talk to us

On-prem and air-gapped deployments are handled as enterprise engagements —
[hello@witbitz.chat](mailto:hello@witbitz.chat?subject=Witbitz%20on-prem).
