# Deployment options
Witbitz can run as a hosted platform, inside a customer's cloud boundary, or in an air-gapped environment. The product
claim shifts slightly in each mode — so this page keeps the deployment model explicit, then documents all three in one
place: **hosted** (the private-beta path), **your own boundary** (enterprise / VPC), and **air-gap** (zero egress). The
runtime is the *same reproducible image* in every mode; what changes is where its seams point and what a skeptic gets to
check.
---
## The options
HostedWitbitz operates the runtime; builders get tenant keys during private beta.
EnterpriseThe same runtime runs inside a customer cloud boundary.
Air-gapNo external egress; model and replacement services stay local.
| Option | Status | Boundary | Best fit |
|---|---|---|---|
| **Hosted private beta** | Live, invite-only | Witbitz-operated cloud | Early builders and platform integrations. |
| **Enterprise VPC / on-prem** | Runnable today | Customer-controlled cloud or network | Enterprise buyers who want their own model, storage, IdP, and ops. |
| **Air-gap** | Runtime switch exists; self-hosted model quality is the remaining work | No external egress | Regulated, defense, government, and high-control deployments. |
## Choosing a mode
| Need | Start with |
|---|---|
| Build against the API quickly | **Hosted** private beta |
| Keep data and model calls inside your tenant | **Enterprise VPC / on-prem** |
| Prove no external egress | **Air-gap** |
| Verify hosted privacy claims | Hosted + the [Verify](./verify.md) page |
| Remove Witbitz as an operator | On-prem |
---
# Hosted {#hosted}
Hosted is the default private-beta path. Witbitz operates the runtime and exposes the tenant-keyed `/v1` API to invited
integrators. The docs and API contracts are public; tenant keys are gated. This is the operating model for builders
building on Witbitz-hosted infrastructure.
## What you get
| Surface | Status |
|---|---|
| Spaces app | Live |
| `/space` async runtime | Live |
| Tenant-keyed `/v1` API | Private beta |
| OpenAPI production spec | Public |
| Full design OpenAPI | Public, status-labelled |
| Owner rule | Implemented (not enabled by default) |
## Access
Register a coupon-free demo tenant straight from the [Get Started walkthrough](./vault-spaces.md), or redeem an access
code and create a tenant key pair at:
```text
https://witbitz.chat/access
```
Keys are shown once. Secret keys (`wsk_…`) are server-side only. Publishable keys (`wpk_…`) are browser-safe identifiers
for public reads and funnel-entry writes, but they do not authenticate an end user. If you do not have an access code,
email [hello@witbitz.chat](mailto:hello@witbitz.chat).
## API contract
The production `/v1` API is documented openly:
```text
https://api.witbitz.chat/v1/openapi.json
https://api.witbitz.chat/v1/openapi.full.json
https://api.witbitz.chat/v1/
```
During private beta the contract may change in coordination with invited integrators. Treat `openapi.json` as the
production callable surface and `openapi.full.json` as the broader design map. See [Platform API](./api-reference.md).
## Hosted trust evidence
Hosted mode is designed to be checked from outside — every claim has a place you can inspect it:
| Evidence | Where |
|---|---|
| Admission gate refuses unauthorized reads/writes | [Verify it yourself](./verify.md) |
| Stored ledger is sealed to a key we never hold | `op:'sealed'` |
| App egress is browser-enforced | Content-Security-Policy |
| Deployed render build is signed | `/cert.json` |
| Published source reproduces the deployed hash | `/source.tar.gz` and Test 7 |
The [attested server tier](./the-attested-tier.md) is in production: a hosted Space can run its turns
inside a Nitro enclave today (a toggle), with your key sealed to the attested image and the enclave scaling to zero when
idle. Enabling it is the app builder's per-room choice — the platform can run *any* hosted room in the enclave.
## What hosted can and can't see
Hosted Witbitz can still see metadata: room existence, request timing, ciphertext sizes, billing/metering events, and
transient identity during gated verification. It **cannot** read the sealed ledger, because there is no operator
recovery recipient — see [Trust model](./trust-model.md).
When that metadata surface isn't enough — you need customer-controlled model calls, customer-owned storage and records,
your IdP as the only identity authority, and no Witbitz-operated runtime in the path — move to your own boundary.
---
# Your own boundary — enterprise & VPC {#your-boundary}
> **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](./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 (see [Air-gap](#air-gap-zero-egress) below).
## 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](./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*. See
[Identity and admission](./identity-and-admission.md).
### 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.
## The trust story gets *stronger*, not weaker
Hosted, our signed [`/cert.json`](./verify.md) and reproducible build let a skeptic confirm the operator — us — is
running **exactly the published, readable source, byte-for-byte** (Tests 6–7), with the app's egress locked (Test 4).
That we are **blind to your data *in use*** — unable to read the plaintext during the transient decrypt-and-render
instant — is the [attested server tier](./the-attested-tier.md), now in production: turn on the enclave and verify it
against the running measurement. 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.* This
is where [verifiable privacy](./verify.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"}'
```
On-prem and air-gapped deployments are handled as enterprise engagements —
[hello@witbitz.chat](mailto:hello@witbitz.chat?subject=Witbitz%20on-prem).
---
# Air-gap — zero egress {#air-gap-zero-egress}
Air-gap mode is the deployment setting where Witbitz refuses **every** external network path it can control. It is for
environments where "no data leaves" must be a property you can *inspect*, not a vendor promise. The short version: set
`AIRGAP=1`, point the model at an in-boundary endpoint, and verify the browser and server both name no outside hosts.
**Status.** The runtime has a zero-egress switch today. The remaining substantial work for a fully useful air-gapped
tier is not the Witbitz runtime itself — it is operating a self-hosted model with the quality the deployment requires,
plus local replacements for any external data tools you want to keep.
## What `AIRGAP=1` changes
| Layer | Behavior |
|---|---|
| Browser | Content-Security-Policy removes external hosts — the browser itself refuses any external fetch. |
| Server | External map, route, photo, URL, search, and flight paths are refused at a single chokepoint. |
| Tools | Internet-touching tools fail closed even if a Space configured them. |
| Model | Must be pointed at an in-boundary endpoint; otherwise the turn still leaves the network (the runtime warns loudly at boot). |
## What still works
Chat, agent turns against an in-boundary model, document reading, PDF generation, charts and diagrams, shared widget
state, IdP admission against an in-boundary identity provider, and backup / restore / retention / logs.
## What is disabled or needs a local replacement
Public web search · external URL import · Google Places photos/search · map tiles, geocode, and routes (unless
self-hosted) · flights lookup (unless backed by an in-boundary service) · remote model APIs.
## Verify the boundary yourself
```bash
# Browser boundary — in air-gap the CSP names no external host:
curl -sD- https://space.your-co.com/ -o /dev/null | grep -i content-security-policy
# Running build — compare to the published source and your own deploy process:
curl -sXPOST https://space.your-co.com/space -H 'content-type: application/json' -d '{"op":"attest"}'
```
## The trust story
Hosted Witbitz asks you to verify the operator's deployment. Air-gapped Witbitz removes the third-party operator from the
path, so the check becomes supply-chain oriented:
- Is the image you run the audited source? (`op:attest` returns the exact build commit the box is running.)
- Does the browser policy name no external host?
- Do server-side tools refuse outbound access?
- Is the model endpoint in-boundary?
- Are logs, backups, and retention under your control?
---
Read next: [Verify it yourself](./verify.md) · [Status](./status.md) · [Trust model](./trust-model.md)