Skip to main content

Authentication

Configure how self-hosted Menace Voice authenticates users — the default local provider, or Stack Auth for social login
3 min read

Self-hosted Menace Voice ships with a built-in local authentication provider (email + password, backed by a signed JWT). This is the default and needs no external service.

To offer social logins (Google and other providers), you can delegate sign-in to Stack Auth. Enabling it is a runtime configuration change — set a few environment variables and restart. The prebuilt dograhai/dograh-api and dograhai/dograh-ui images work as-is; you do not need to rebuild or build from source.

Note

The active provider is local by default. When the deployment .env contains a Hexclave/Stack project id and secret server key, the API enables stack automatically (AUTH_PROVIDER=local still forces local). The frontend discovers the provider — and, for Stack, its public client config — at runtime from the backend's /api/v1/health response, so the browser bundle never needs Stack values baked in at build time.

How it works#

  1. The backend reads AUTH_PROVIDER and the Stack settings from its environment.
  2. When AUTH_PROVIDER=stack, /api/v1/health returns the public Stack client config (project id + publishable client key).
  3. The UI fetches that at runtime and initializes the Stack SDK in the browser.
  4. The secret server key is used only server-side (by the backend and the UI's server runtime) and is never sent to the browser.

Prerequisites#

A Stack Auth project. Create one in the Stack Auth dashboard and configure the social login providers you want to offer.

Step 1 — Collect your Stack credentials#

From your project in the Stack Auth dashboard, gather:

ValueSensitivity
Project IDPublic
Publishable client keyPublic (safe to expose in the browser)
Secret server keySecret — keep server-side only
API base URLPublic. For Stack's hosted service this is https://api.stack-auth.com

Step 2 — Set them in the deployment .env#

Put the values in the .env next to docker-compose.yaml (the file setup_remote.sh / setup_local.sh created — not api/.env, which only applies to local uvicorn). Compose interpolates that file into both the api and ui containers; you do not need to edit docker-compose.yaml.

.env

Legacy STACK_AUTH_PROJECT_ID / STACK_SECRET_SERVER_KEY names still work.

Note

The UI does not need the project id or publishable client key in its own env — it receives those from the backend at runtime via /api/v1/health. The secret server key is passed to ui as well because SSR pages and /handler/* call Stack server-side.

Step 3 — Restart and verify#

Recreate the containers so they pick up the new environment:

Confirm the backend reports the active provider and the public client config:

Then open the UI. The sign-in page should now present your configured Stack Auth social login options instead of the local email/password form.

Environment variable reference#

VariableServiceSecretNotes
AUTH_PROVIDERapistack or local. Unset + project id + secret enables stack. local always wins
HEXCLAVE_PROJECT_ID / STACK_AUTH_PROJECT_IDapiNoProject ID; served to the UI at runtime
STACK_PUBLISHABLE_CLIENT_KEYapiNoPublishable key; served to the UI at runtime. Optional for newer Hexclave projects
HEXCLAVE_SECRET_SERVER_KEY / STACK_SECRET_SERVER_KEYapi + uiYesServer-side only — never exposed to the browser
STACK_AUTH_API_URL / HEXCLAVE_API_URLapiNoREST API base URL. Defaults to https://api.hexclave.com
Warning

HEXCLAVE_SECRET_SERVER_KEY / STACK_SECRET_SERVER_KEY is the only secret here. Keep it out of any client-visible config and never bake it into an image. The project ID and publishable client key are public by design — the backend deliberately serves them to the browser so Stack can initialize at runtime.

Reverting to local auth#

Remove the variables above (or set AUTH_PROVIDER=local) and restart. The UI detects local from the backend at runtime and falls back to the built-in email/password flow — no rebuild required.