NOTE: This cloud prover is only used for recursing sub-proofs (already proven with concealed private inputs) into a final compressed EVM-compatible proof, or for proving non-sensitive sub-proofs, where a user's device memory is insufficient (i.e. less than ~2 GB). No sensitive passport/national ID card information ever leaves a user's device (unless they explicitly share it with a service).
A cloud-based prover service for generating proofs using Barretenberg (bb), deployed on GKE (spot nodes).
This project implements a cloud prover service for ZKPassport, built using Node.js and TypeScript. It
runs as a containerized service on GKE and shells out to the Barretenberg (bb) proving system.
The container bundles pinned bb builds (4.2.0-aztecnr-rc.2 and 5.0.0) plus the CRS, and
exposes a single POST /prove endpoint. The bb_version field in the request body selects
which build to use. Only the outer*, facematch*, and sig_check_dsc*
circuits are accepted (validated against the ZKPassport circuit registry).
- Compute: GKE Standard cluster
cloud-proverinus-central1-a, projectzkpassport-cloud-prover. A small on-demand system node pool plus a spott2d-standard-16pool (16 vCPU / 64 GB) that runs the prover — one proof per node, ~84 s per large EVM outer proof. The prover pod requests ~14 vCPU / 16 GiB (measured peak ~11 GiB RAM, ~7 cores avg with bursts to all 16). Cluster autoscaler scales the spot pool (min 1warm node →max 6) as proof pods queue. - Networking: GCE Ingress with a Google-managed TLS cert on a static IP; backend timeout 600 s (proofs run ~84 s).
- Image registry: Artifact Registry
us-central1-docker.pkg.dev/zkpassport-cloud-prover/cloud-prover. - IaC:
deploy/terraform/(cluster, node pools, IAM, static IP) anddeploy/k8s/(kustomize manifests). Seedeploy/README.mdfor the bootstrap + cutover runbook. - CI/CD: GitHub Actions (
.github/workflows/deploy.yml) authenticates to GCP via Workload Identity Federation, builds the image on Cloud Build (deploy/cloudbuild.yaml— bb is fetched as a prebuilt binary, so the build is light/fast), thenkubectl apply -ks the manifests to GKE. Triggered manually viaworkflow_dispatch(Actions tab orgh workflow run).
- Node.js 20+
- Docker (for local image builds)
gcloudCLI (for manual deploys / inspection)
Run the server directly against locally-installed bb binaries:
npm install
npm run dev # ts-node src/server.ts, expects bb on PATH (see BB_VERSIONS in src/handler.ts)Or build and run the full container image (linux/amd64):
docker buildx build --platform linux/amd64 -t cloud-prover .
docker run --platform linux/amd64 -p 3000:3000 --rm -it cloud-proverThis gives a local http://localhost:3000 endpoint with POST /prove.
Deploys are triggered manually — run the Deploy to GKE workflow from the Actions tab
(or gh workflow run "Deploy to GKE"). For first-time cluster provisioning, manual deploys,
and decommissioning the old Cloud Run service, see deploy/README.md.
Manual image build + deploy:
# Build + push image on Cloud Build
gcloud builds submit --project=zkpassport-cloud-prover --config=deploy/cloudbuild.yaml \
--substitutions=_SHA=$(git rev-parse --short HEAD)
# Deploy to GKE
gcloud container clusters get-credentials cloud-prover --zone us-central1-a --project zkpassport-cloud-prover
cd deploy/k8s/base
kustomize edit set image \
us-central1-docker.pkg.dev/zkpassport-cloud-prover/cloud-prover/cloud-prover=us-central1-docker.pkg.dev/zkpassport-cloud-prover/cloud-prover/cloud-prover:$(git rev-parse --short HEAD)
kubectl apply -k .bun test