Inspiration
AI image and video tools are everywhere now. What’s still awkward is the part that happens after you hit generate: someone forwards a file, it shows up in a pitch deck or a newsroom Slack, and nobody can tell if it’s the original output or a quiet edit.
We kept running into that gap. Genblaze already produces provenance manifests, and Backblaze B2 is a solid place to keep the bytes. We wanted something a judge (or an editor) could actually use — generate, store, and then check a file without needing a PhD in hashing.
That’s ProofStudio: make the “can I trust this file?” question boringly easy to answer.
What it does
ProofStudio is a small studio web app with three main surfaces:
- Studio — type a prompt, generate an image or a short video clip. Image runs go through a two-step Genblaze pipeline (Imagen generate, then an editorial pass). Video uses Veo 3.1 Lite at 4 seconds / 720p, with Fast as a fallback if Lite fails.
- Gallery — browse past runs pulled from B2, see step counts, open a run into Verify.
- Verify — upload a file (or paste a run ID). We re-hash the bytes, look up the sidecar manifest on B2, and show whether it still matches. Change one byte and it fails. There’s a preview of what you uploaded so the pass/fail isn’t abstract.
Every successful run stores the media and a sidecar provenance manifest on Backblaze B2 (private bucket, served through our API proxy). Genblaze’s Manifest.verify() is part of that check. You can also refine a previous run and keep parent_run_id lineage.
Live demo: https://proofstudio-web-rawshyh2rq-as.a.run.app
How we built it
Frontend is Next.js (Studio / Gallery / Verify). Backend is FastAPI. Generation is async: POST /api/generate returns a job_id immediately, the UI polls status, so long Veo or Imagen runs don’t die on HTTP timeouts.
In genblaze mode the backend builds a Genblaze Pipeline, runs Google providers (Imagen / Veo), then lands assets and manifests on B2 through an S3-compatible path. Layout is content-addressable (assets/<sha>/…, manifests/<run_id>.json) plus a small run index. We also keep a mock mode that generates real local bytes with no API keys — useful while wiring verify and storage.
For deploy we use Cloud Run (asia-southeast1), with secrets in Secret Manager, max-instances=1 and no CPU throttling so in-memory jobs don’t vanish mid-poll. PUBLIC_BASE_URL keeps asset URLs pointing at the live API instead of localhost.
Challenges we ran into
Veo → B2 wasn’t plug-and-play. The provider path we hit stored Google Files API URIs that our transfer step couldn’t download without auth. We had to materialize the MP4 locally (file://) before the B2 sink ran. Related: operation.name as a string vs what google-genai 2.x expects for poll/get. That took more hours than the happy-path docs suggest.
Fallback only helps if the error code is right. Lite returning “model not found”-style failures mapped to UNKNOWN in places, so Genblaze never tried Fast. We normalize those to MODEL_ERROR so fallback_models actually fires.
Cost and demo risk. Full Veo Standard clips add up fast. We standardized on Lite, 4 seconds, 720p (~$0.20/clip) and kept a pre-baked Gallery run as a recording backup.
Cloud Run quirks. Job state lives in memory, so multiple instances break polling. Mixed Content also bit us when old index entries still pointed at http://localhost:8000/files/... from a HTTPS page — we rewrite those onto the current API base.
Accomplishments that we're proud of
- A full loop that judges can click through live: generate → B2 → verify original vs tampered.
- Real multi-step Genblaze image pipeline (generate + editorial), not a single opaque API call.
- Video that actually lands on B2 with the same sidecar story as images.
- Private B2 + proxy so we don’t need a public bucket for the demo.
- Shipping on Cloud Run with health checks that report
genblaze+backblaze-b2.
What we learned
Provenance is only as useful as the verify UX. Hash strings in a JSON blob don’t convince anyone; uploading a file and seeing Verified / Not verified next to a preview does.
We also learned that “SDK integration” often means fighting version edges — provider adapters, error codes, and how bytes move from a model host into your own object store. Genblaze’s pipeline + fallback model ideas are solid once those edges are handled. And for a hackathon, cheaper defaults (Lite, short duration) matter as much as features; burned quota doesn’t impress judges.
What's next for ProofStudio
- Optional inline embed of manifests into MP4/PNG (Genblaze media handlers) alongside the sidecar, for offline verify when the file travels alone.
- Stronger lineage UI for refine chains (parent/child as a small graph, not just an ID).
- Signed share links with expiry, so editors can send a verify URL without exposing the whole gallery.
- Tighten the Veo adapter upstream (or drop the monkeypatch) once newer
genblaze-googlebuilds cover the Files download path we hit. - Broader provider mix later — same Studio/Verify shell, different Genblaze steps.
Built With
- backblaze-b2
- cloud-run
- fastapi
- genblaze
- google-cloud
- next.js
- python
- react
- typescript
Log in or sign up for Devpost to join the conversation.