Skip to main content

Run Your Own Backend (Advanced)

Only needed if you're self-hosting. The Quick Start already runs against our deployed Duo sandbox — skip this page unless you want to point the app at your own duo-server + auth-svc.

The boilerplate communicates with two backend services that work together:

  • duo-server — the MPC cloud node. It holds the cloud-side keyshare and participates in every keygen and signing operation.
  • auth-svc — the auth middleware. It handles user and device registration, and authorizes every operation duo-server performs by responding to hook calls.

Think of it this way: duo-server is the vault. auth-svc is the doorman. The vault calls the doorman before opening for any keygen or sign request.

For full auth-svc setup instructions (Docker Compose, environment variables, and hook configuration), see the auth-svc documentation.

Self-hosting checklist

Follow this order when replacing the sandbox with your own backend:

  • Run the Quick Start against the deployed sandbox first. This verifies your local React Native, Expo, iOS, and Android setup before you introduce custom backend configuration.
  • Set up third-party services. Auth0 and FaceTec values must be shared by the app and auth-svc; Google and WalletConnect values are app-only.
  • Configure auth-svc, including the Auth0 API/audience, FaceTec values, database, and hook configuration.
  • Run auth-svc with duo-server, then copy the duo-server URL and the cloud verifying key printed in the duo-server logs.
  • Replace the EXPO_PUBLIC_DUO_*, Auth0, FaceTec, Google, and WalletConnect values in the app's .env.
  • Restart the app so Expo reloads .env. The app defaults to the Duo Demo server preset; after you replace EXPO_PUBLIC_DUO_*, that default preset points at your backend. Use Server settings -> Custom Backend only when you want to enter backend values at runtime without changing .env.

Point the app at your backend

Once your backend is running, set the Duo preset values in the app's .env (these override the sandbox defaults from .env.example):

VariableWhere to find it
EXPO_PUBLIC_DUO_CLOUD_NODE_URLThe URL of duo-server (e.g. https://your-node.example.com)
EXPO_PUBLIC_DUO_CLOUD_NODE_VERIFYING_KEYThe hex verifying key printed in duo-server logs on startup
EXPO_PUBLIC_DUO_BACKEND_BASE_URLThe HTTP base URL of auth-svc (e.g. https://your-auth-svc.example.com)

These seed the Duo Demo entry in the in-app Server settings, and the app selects Duo Demo by default. After replacing these values and restarting the app, the default Duo path uses your backend. You can also enter a backend at runtime via Server settings → Custom Backend without rebuilding.

Your app config must match your auth-svc config. auth-svc validates the JWT and the FaceTec session, so the values baked into the app have to match what auth-svc is configured with — otherwise login and backup/recovery will fail:

App .envMust match auth-svc's
EXPO_PUBLIC_AUTH0_DOMAIN, EXPO_PUBLIC_AUTH0_CLIENT_ID, EXPO_PUBLIC_AUTH0_AUDIENCEAuth0 tenant / API audience
EXPO_PUBLIC_FACETEC_DEVICE_KEY_IDENTIFIER, EXPO_PUBLIC_ENCRYPTION_KEYFaceTec device key + encryption key

See Third-Party Services to create these and keep both sides in sync.

Running locally? Use these addresses depending on your target:

TargetBackend URL
iOS Simulatorhttp://localhost:9090
Android Emulatorhttp://10.0.2.2:9090
Physical deviceYour machine's LAN IP (e.g. http://192.168.1.x:9090) or use ngrok

The same rule applies to the duo-server WebSocket URL — replace localhost with 10.0.2.2 or your LAN IP accordingly.