Soar API Setup
Connect Tauri to a conforming Unified Platform host: Rust config, host environment, sessions, and verification.
This is the Unified Mode counterpart to Supabase Setup: everything needed to run the desktop app against a conforming Web host instead of a Supabase project. If you haven't picked a mode yet, start at Backend Modes.
No host is privileged by framework name — Next.js, Nuxt, and TanStack Start all work; conformance to the frozen contracts is the compatibility boundary.
1. Deploy a conforming host
Deploy one of the Web templates as a Unified Platform Host and complete its host-side setup (database, Better Auth URL and secret, App API):
Sign up on the Web and verify /api/auth/get-session works before touching the
desktop side. For the cross-template picture, see the
platform Unified Quick Start.
2. Configure the client build
Unified Mode needs the build-time environment values in .env:
# .env
SOAR_BACKEND_MODE=soarApi
# Service root of the host deployment. Native-only: consumed by Rust and
# never exposed to the Webview.
SOAR_API_BASE_URL=https://your-web-app.example.com
# Native origin sent on Better Auth requests. Must match the host's
# APP_SCHEME / trustedOrigins allow-list.
SOAR_AUTH_ORIGIN=soar://The SUPABASE_* keys can stay unset — the Supabase adapter is never
initialized in this mode. Only the mode itself reaches the Webview; the API
URL and auth origin stay in Rust.
Configuration errors stop the selected path. An invalid
SOAR_BACKEND_MODE or a missing SOAR_API_BASE_URL fails startup with a
diagnosable error — the other backend is never initialized as a fallback.
3. Configure the host for this app
On the server (the selected host's deployment environment), the app expects the native support described in Native Authentication:
| Server variable | Why the desktop app needs it |
|---|---|
APP_SCHEME=soar:// | Rust sends Origin: soar:// (the configured SOAR_AUTH_ORIGIN) on every request; Better Auth rejects untrusted origins with 403. |
STORAGE_PROVIDER (+ R2_* in production) | Presigned-upload object storage backing the uploads service. |
| Payment provider config (Creem/Stripe) | The host issues subscription snapshots, checkout URLs, and the management portal that desktop opens. |
Tauri Unified intentionally does not implement OAuth, device tokens, or test push — the capability-driven UI hides those actions, so no OAuth audiences or push credentials are required for desktop.
4. Sessions live in a Rust-private keyring namespace
In Unified Mode the app authenticates with Better Auth Bearer tokens (the
set-auth-token response header), not cookies:
- The token is persisted only in a Rust-private OS-keyring namespace — never the Webview, never localStorage, never logs.
- The Webview receives a sanitized session through typed commands; the
Bearer token,
Authorizationheader, and presigned URLs are kept out of the generated bindings. - On relaunch the stored session is restored and validated against the server; sign-out clears both the keyring entry and in-memory state.
- Sessions are database-backed and revocable: revoking a session on the web
invalidates the desktop token immediately, and the app treats
401as "sign in again" — it never retry-loops and never falls back to Supabase auth.
5. Billing through the host
Desktop billing follows the host's subscription state: the app reads the shared subscription snapshot, and checkout or portal flows open provider URLs issued by the host. Rust validates those URLs before opening them externally.
Verify the setup
Run the shared smoke test across both surfaces:
- Sign up or sign in on desktop (email/OTP), then open the same account on the Web.
- Update the profile on one surface and read it from the other.
- Create, edit, reorder, and delete a todo across both surfaces.
- Upload an avatar and confirm its completion URL is readable.
- Revoke the desktop session from the Web and verify the app returns to sign-in.
- Complete a test checkout from desktop and confirm the same entitlement appears on both surfaces.
- Delete the account from desktop and confirm the cascade on the host.
For a concrete end-to-end walkthrough of one host-and-client pair, follow Next.js + Swift Unified Setup — the steps map onto desktop, minus OAuth and push.
Related pages
Backend Modes
The decision page: comparison, mode resolution, and what does not mix.
Environment Variables
Every build key, including SOAR_BACKEND_MODE and SOAR_API_*.
IPC
The typed command boundary that keeps tokens and presigned URLs in Rust.
Native Authentication
Bearer sessions and email OTP on the host side.
