Skip to main content
Self-hosted Dograh 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, GitHub, and others), 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.
The active provider is controlled by the backend AUTH_PROVIDER variable (local by default). 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 β€” Configure the backend (api)

Set these on the api service. Add them to the environment: block of the api service in your docker-compose.yaml:
docker-compose.yaml
services:
  api:
    environment:
      AUTH_PROVIDER: "stack"
      STACK_AUTH_PROJECT_ID: "<your-project-id>"
      STACK_PUBLISHABLE_CLIENT_KEY: "<your-publishable-client-key>"
      STACK_SECRET_SERVER_KEY: "<your-secret-server-key>"
      STACK_AUTH_API_URL: "https://api.stack-auth.com"

Step 3 β€” Configure the UI (ui)

The UI runs server-side code (SSR pages and the /handler/* auth routes) that calls Stack with the secret server key, so the ui service needs that one value too:
docker-compose.yaml
services:
  ui:
    environment:
      STACK_SECRET_SERVER_KEY: "<your-secret-server-key>"
The ui service does not need the project id or publishable client key β€” it receives those from the backend at runtime via /api/v1/health. Only the secret server key (used server-side) is set here.

Step 4 β€” Restart and verify

Recreate the containers so they pick up the new environment:
docker compose up -d
Confirm the backend reports the active provider and the public client config:
curl -s http://localhost:8000/api/v1/health
# expect: "auth_provider":"stack", plus "stack_project_id" and "stack_publishable_client_key"
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_PROVIDERapiβ€”Set to stack (default local)
STACK_AUTH_PROJECT_IDapiNoStack project ID; served to the UI at runtime
STACK_PUBLISHABLE_CLIENT_KEYapiNoPublishable key; served to the UI at runtime
STACK_SECRET_SERVER_KEYapi + uiYesServer-side only β€” never exposed to the browser
STACK_AUTH_API_URLapiNoStack REST API base URL
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.