Self-host Gesso: run collaboration on infrastructure you control
A contract landed on your desk that says the client's files have to sit inside a boundary you control. Self-hosting is how you answer that. Gesso still works locally first either way; what changes is who owns the servers, and who gets the call when they stop answering.
First, check that you actually need this
Gesso runs three ways, and the right answer is usually the smallest one that fits the job.
Browser-local is available now and asks nothing of you. Work stays in that browser until it is exported or the browser's site data is cleared.
A Gesso account is available in configured builds. It saves locally first, then syncs signed document changes, restores private Asset Library files, and turns on comments, invitations, and people management.
Self-hosted collaboration runs those same guarded workflows against your Supabase project and your web host. The workflows themselves don't change. What changes is who is awake when Auth stops issuing tokens at 2 a.m.
Choose self-hosting when the data has to sit inside a boundary you control, or when your organization can't hand storage and identity to someone else. Don't choose it because it looks like the complete option. It's the one with an operations bill attached, and that bill arrives every month.
If you're reading this to decide, that's as far as you need to go. The rest is for whoever runs your servers. Hand it to them, or read on if that person is you.
Set up the host
- Create a Supabase project. Choose the project your organization will administer. Keep this collaboration project separate from application databases unless you have verified isolation.
- Apply the backend migrations. Run the pinned migration set from
backends/supabase. Never edit a migration that has already been applied to a shared environment. Add a new one. - Deploy the protected functions. Deploy every checked-in Edge Function with JWT verification left enabled. Capability JWTs and database credentials belong in Edge secrets only.
- Configure Resend email. Use Resend custom SMTP for Supabase Auth, and the Resend API for Gesso invitations, alerts, and explicitly opted-in marketing. Verify the sender domain, SPF, DKIM, and DMARC before the first invitation goes out.
- Verify before inviting people. Run the backend verification suite, test an invite with a second account, test a Realtime reconnect, and rehearse a logical restore. Do this on the deployed host, not on a laptop.
Commands from the checked-in backend
export SUPABASE_TELEMETRY_DISABLED=1 # disable CLI telemetry for this setup session
supabase db push # apply the ordered collaboration migrations
supabase functions deploy <function> # every directory under supabase/functions, JWT verification left enabled
scripts/verify.sh # Edge checks, migration checks, database security assertions, restore preflights
Run scripts/verify.sh from backends/supabase. It uses a disposable PostgreSQL database with
Supabase-compatible stubs. A green run is evidence about the code. It says nothing about your
deployment, and it does not replace a live Auth, PostgREST, Realtime, Storage, Edge, backup, or
restore acceptance run.
Configuration boundaries
One rule governs the table below. Anything prefixed NEXT_PUBLIC_ reaches the browser.
Everything else must not.
| Variable | What it is |
|---|---|
NEXT_PUBLIC_SUPABASE_URL | Public web API origin. Safe in the browser when it is the exact HTTPS project origin. |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Public Supabase key for browser Auth and the validated hosted profile. |
NEXT_PUBLIC_GESSO_HOSTING_MODE | Accepts managed or self-hosted. Set it to self-hosted for an operator-run installation. |
NEXT_PUBLIC_SUPABASE_ISSUER | Exact Auth issuer. Must equal the public project URL followed by /auth/v1. |
NEXT_PUBLIC_SUPABASE_POSTGRES_MAJOR | Postgres major certified by this client: 15 through 17. |
GESSO_INSTANCE_NAME, GESSO_INSTANCE_HOME_URL | Optional server-only instance identity. |
SUPABASE_URL, SUPABASE_ANON_KEY | Edge Function configuration for the project and its public key. |
COLLABORATION_APPEND_JWT | Edge-only capability JWT for verified change append operations. |
COLLABORATION_MANAGEMENT_JWT | Edge-only capability JWT for workspace, membership, and actor management. |
COLLABORATION_ASSET_JWT | Edge-only capability JWT for private asset and checkpoint operations. |
COLLABORATION_INVITE_JWT | Edge-only capability JWT for invitation operations. |
RESEND_API_KEY, EMAIL_FROM | Edge-only Resend delivery credentials. Never prefix the API key with NEXT_PUBLIC. |
COLLABORATION_DATABASE_URL and storage credentials | Operator-only backup and restore configuration. Keep them out of the browser and out of committed env files. |
How data is separated
Supabase Storage buckets are flat, so there's no folder-per-client structure hiding underneath
this. The backend uses two private buckets, collaboration-assets and
collaboration-checkpoints, with workspace-scoped, content-addressed paths and membership
checks. There is no physical bucket per user, and you should not add one. The isolation lives in
the path scheme and the membership check, not in the bucket count.
Realtime is a hint, not the source of truth
Clients pull durable changes from their last accepted cursor after every event and after every reconnect. A dropped socket therefore sends a client back to the durable record. It also means Realtime authorization and workspace membership are things you have to test on the deployed host. Nothing in the local suite can tell you whether your production policies are right.
What your team takes on
This is the part people underestimate. Read it as a staffing question, not a setup question.
| Service | Your responsibility | Cost and scaling |
|---|---|---|
| Hosting and updates | Web host, Supabase project, Edge deploys, image and dependency updates | Deployment time, version pinning, alerts, and a named rollback owner |
| Storage and backups | Two private collaboration buckets, logical backups, restore rehearsals, retention | Storage, egress, backup capacity, and growth from assets and checkpoints |
| Resend email | Auth SMTP, transactional delivery, marketing consent and Topics, redirect allowlists, SPF, DKIM, DMARC, bounces, suppressions | Transactional and broadcast usage, domain operations, inbox-delivery monitoring |
| Collaboration and access | Membership, invitation testing, revocation, Realtime reconnects, incident response | More people and workspaces means more support, audit, and operational load |
Before the first invitation leaves your host:
- Backend verification suite run against the deployed project
- Invitation tested end to end with a second, real account
- Realtime reconnect exercised and observed to resume from the last cursor
- Logical restore rehearsed, timed, and written down
- SPF, DKIM, and DMARC verified for the sending domain
- Rollback owner named, and reachable
Attribution and redistribution
Supported distributions can configure the instance identity, but must retain the Gesso by Meridian footer attribution and link. The supported configuration has no removal switch.
Gesso is pay what you can, including zero, and a receipt is the proof of payment and license. A paid license is recommended if you use Gesso to produce commercial content. Reselling, redistributing, sublicensing, or breaking Gesso down into parts is prohibited. The grant covers your own use and your agency's, client work included.
Those are the product's terms as stated here, not a legal document. The repository does not yet carry a license file, and this guide is not one. Treat a counsel-approved license as an open item, not a settled question.
What is ready today
Source and local verification now cover local-first editing, optional Auth, signed document sync, durable retry, private Realtime hints, recoverable Asset Library files, comments, invitations, and people management.
Four things are still open as release gates. A production two-account and reconnect run. SMTP, Realtime, Storage, and restore acceptance on a deployed host. A counsel-approved redistribution license. And the honest footnote: no security review can guarantee 100% security, so treat the acceptance run as the day operations start rather than the day setup ends.
Common questions
No. The source and the setup material are checked in, and that is not the same as your production host being ready. Run the acceptance checks on the infrastructure you operate before you invite anyone onto it.