Bito gateway helm chart
367
This repository holds a Helm chart, not a container image. Pull it with helm,
not docker pull — Docker will reject it with
unsupported media type application/vnd.cncf.helm.config.v1+json.
The gateway's container image lives separately at
bitoai/bito-gateway.
Bito Gateway is a context-driven model router. It sits between your applications or coding harnesses and the model providers, and does two things a proxy doesn't: it puts the context your models are missing into the request, and it routes each call to the right model and credential for that workspace across providers. Multi-tenant, provider-agnostic, and metered per workspace. Provider keys are held envelope-encrypted.
Every command below installs the newest published version — Helm resolves it
automatically when no --version is given.
The defaults are self-hosted and complete: one command brings up the gateway, a MySQL database and a valkey counter store, all on persistent volumes. Nothing outside the cluster is required.
kubectl create namespace bito-gateway
kubectl create secret generic bito-gateway-secrets \
--namespace bito-gateway \
--from-literal=DB_PASSWORD="$(openssl rand -base64 24 | tr -d '/+=')" \
--from-literal=CRYPTO_ENV_KEK_KEY="$(openssl rand -base64 32)" \
--from-literal=MYSQL_ROOT_PASSWORD="$(openssl rand -base64 24 | tr -d '/+=')" \
--from-literal=ADMIN_TOKEN="$(openssl rand -base64 32 | tr -d '/+=')"
helm install gw oci://registry-1.docker.io/bitoai/bito-gateway-helm \
--namespace bito-gateway --set secrets.existingSecret=bito-gateway-secrets
That renders 3 Deployments, 3 Services, 2 PersistentVolumeClaims and a provisioning Job.
See what you're about to get, first:
helm show chart oci://registry-1.docker.io/bitoai/bito-gateway-helm
Pinning. For reproducible deployments, add --version X.Y.Z to any command above.
Available versions are listed under the Tags tab. Upgrading is the same command with
helm upgrade.
CRYPTO_ENV_KEK_KEYmust be base64 of exactly 32 bytes. It encrypts every stored provider credential, so back it up somewhere outside this cluster — losing it makes those credentials unrecoverable.
The two are independent, so your MySQL + the chart's valkey is supported:
| You already run | Set | Point the gateway at yours with |
|---|---|---|
| MySQL | mysql.enabled: false | config.DB_HOST / DB_PORT / DB_NAME / DB_USER (+ DB_TLS) |
| Redis / valkey | redis.enabled: false | config.REDIS_ADDR (+ REDIS_TLS, REDIS_PASSWORD) |
| both | both false | use values-external-db.yaml |
Unpack the latest chart to get them:
helm pull oci://registry-1.docker.io/bitoai/bito-gateway-helm --untar
| File | Use it when |
|---|---|
values-selfhosted.yaml | start here — the defaults written out and explained |
values-external-db.yaml | managed database (RDS / Cloud SQL / Azure Database), TLS, credentials from your own Secret |
values-production-ha.yaml | multi-replica with a shared counter store |
values-single-node.yaml | small or dev, database already in-cluster |
values-demo.yaml | evaluating — in-cluster stores with no persistent volume; every restart loses all data |
The install gives you a running gateway, not a reachable one. values-selfhosted.yaml
carries four ready-to-uncomment Ingress presets — nginx, AWS ALB, GKE and
Azure AGIC — because each controller spells "wait longer" differently and LLM
responses stream for minutes. A default timeout truncates answers mid-sentence.
For a first look, use a port-forward:
kubectl -n bito-gateway port-forward svc/<release>-bito-gateway 8788:8788
appVersion is the default image tag,
so each chart version installs the matching gateway image.helm pull … --untar and read README.md.ADMIN_TOKEN in a SecretADMIN_TOKEN is optional. It exists only as a bootstrap escape hatch for the
case where you need admin access before the database has any rows in it. If you
would rather not store an admin credential in a Kubernetes Secret, a .env file,
or your compose config — leave it unset and mint a database-backed admin instead.
Leaving it unset is not a failure mode. The gateway boots normally, /healthz
returns 200, and the data plane serves traffic; only the bootstrap admin is
disabled. The startup log records exactly that:
bito-gateway :8788 | db=bito_gateway | ... | admin=true | admin_bootstrap=false
Admin auth then resolves entirely against the gw_admin table, which stores only
a SHA-256 hash of each token — the raw value is never written to disk or to your
cluster state.
Mint the first global admin (prints the token once — copy it now, it cannot be retrieved later):
# Docker Compose
docker compose exec gateway gwctl admin create --role global
# plain docker run
docker exec -it <container> gwctl admin create --role global
# Kubernetes
kubectl -n <namespace> exec deploy/bito-gateway -- gwctl admin create --role global
# standalone installer (bundled wrapper)
bito-gateway-ctl admin create --role global
Output:
admin (global) created — token shown once:
gw_admin_<48 hex chars>
Use it as: Authorization: Bearer gw_admin_<...>
Use it against the admin API or to sign in to the embedded admin UI at /admin/:
curl -sS localhost:8788/admin/api/workspaces -H "Authorization: Bearer gw_admin_<...>"
Why this is the better default:
ADMIN_TOKEN in a Secret | gwctl admin create | |
|---|---|---|
| Credential at rest | in your Secret / env / config file | SHA-256 hash in the database only |
| Takes effect | needs a pod/container restart | immediately, no restart |
| Revocable | only by editing the Secret + restarting | gwctl admin revoke <id> |
| Audited | no — one shared identity | yes, per-admin rows in the audit log |
| Scoping | always global | --role global, or --role workspace --workspace <id> |
Requirements: the database must be reachable and migrated (the gateway applies
its schema on first boot, so start the container once before running this), and the
node must serve the control plane (ADMIN_ENABLED=true, the default — a
data-plane-only worker has no admin API to log in to).
Manage admins afterwards with gwctl admin list / gwctl admin revoke <id>, or
from the admin UI. Add more admins there rather than sharing one token.
Content type
Helm
Digest
sha256:f2a53bea5…
Size
178.7 kB
Last updated
about 17 hours ago
helm pull oci://registry-1.docker.io/bitoai/bito-gateway-helm --version 1.0.26