Skip to content

OAuth setup guide (app owner)

Zero xyz edited this page May 27, 2026 · 1 revision

OAuth setup guide (app owner)

This guide is for the owner of the Endowment app who creates and manages sign-in with X, Discord, Google (and Microsoft when enabled). You will register callback URLs in each provider’s developer portal, then copy Client ID and Client Secret into the app’s production configuration.

Live app: https://endowment.zeroauthoritydao.com

Sign-in providers wired today: X, Discord, Google
Shown in UI but not wired yet: Microsoft, GitHub, LinkedIn


What you are configuring

For each provider you will set three things in their portal (not in this repo):

Item Where you set it What you copy out
Callback / redirect URI Provider developer console Nothing to copy — use the exact URLs in the table below
Client ID Same console Give to whoever deploys the app (see Hand off to production)
Client secret Same console Same — treat like a password; shown once on some portals

All flows use OAuth 2.0 with PKCE. Do not change scopes unless engineering asks you to.


Production: app URL and callback URLs

Register these in each provider console for the live site. Use the full URL exactly — correct https, host, path, no trailing slash.

App base URL (production): https://endowment.zeroauthoritydao.com

Callback path pattern: {base URL}/api/auth/oauth/{provider}/callback

Provider Production callback URL (register this)
X https://endowment.zeroauthoritydao.com/api/auth/oauth/x/callback
Discord https://endowment.zeroauthoritydao.com/api/auth/oauth/discord/callback
Google https://endowment.zeroauthoritydao.com/api/auth/oauth/google/callback
Microsoft (when enabled) https://endowment.zeroauthoritydao.com/api/auth/oauth/microsoft/callback

Google only — also add authorized JavaScript origin: https://endowment.zeroauthoritydao.com

Website / app URL fields in provider consoles should use https://endowment.zeroauthoritydao.com where asked.

If the public domain ever changes

Updating DNS or the site URL is not enough for login to keep working:

  1. Register the new production callback URLs (and Google origin) in every provider console.
  2. Give the deployer the updated production base URL and credentials if apps were recreated.
  3. Test sign-in on the new domain before removing old callback URLs.
  4. Update this document with the new hostname so future setup stays correct.

Until provider consoles match the live URL, users will see errors such as redirect_uri_mismatch.


Hand off to production

After you create each OAuth app, send these to whoever manages production hosting (Vercel, Railway, etc.). They enter them as environment variables — not in git.

Variable Value
APP_BASE_URL https://endowment.zeroauthoritydao.com
AUTH_SECRET Long random secret (32+ characters); unique to production
X_CLIENT_ID From X developer portal
X_CLIENT_SECRET From X developer portal
DISCORD_CLIENT_ID From Discord developer portal
DISCORD_CLIENT_SECRET From Discord developer portal
GOOGLE_CLIENT_ID From Google Cloud Console
GOOGLE_CLIENT_SECRET From Google Cloud Console

Optional overrides (only if a portal was configured with a non-standard callback): X_REDIRECT_URI, DISCORD_REDIRECT_URI, GOOGLE_REDIRECT_URI — each must match the portal character for character.

Production checklist

  • Every provider has the production callback URL from the table above.
  • Client ID and secret for X, Discord, and Google are in hosting secrets.
  • APP_BASE_URL is https://endowment.zeroauthoritydao.com (no trailing slash).
  • Google OAuth consent screen is In production when all users should sign in (not only test users).
  • Sign-in tested on endowment.zeroauthoritydao.com for X, Discord, and Google.

Scopes (register or allow in each portal)

Provider Scopes
X users.read, tweet.read, offline.access
Discord identify, email
Google openid, email, profile

X (Twitter)

Portal: X Developer Portal → your Project → App → User authentication settings

  1. Enable OAuth 2.0 (not OAuth 1.0a-only).
  2. Type of app: Web App (typical for this site).
  3. Callback URI / Redirect URL: add
    https://endowment.zeroauthoritydao.com/api/auth/oauth/x/callback
  4. Website URL: https://endowment.zeroauthoritydao.com
  5. Ensure permissions allow user read (users.read at minimum).
  6. Save and copy Client ID and Client Secret (secret may only appear once).

Verify: On the live site, open Log in → X → complete consent → return signed in.


Discord

Portal: Discord Developer Portal → your application → OAuth2

  1. OAuth2 → General: copy Client ID; reveal/copy Client Secret.
  2. OAuth2 → Redirects → Add Redirect:
    https://endowment.zeroauthoritydao.com/api/auth/oauth/discord/callback
  3. Scopes used by the app: identify, email.
  4. Optional: set app icon and description so users recognize the consent screen.

Verify: Log in → Discord on the live site.


Google

Portal: Google Cloud Console → your project → APIs & Services

  1. OAuth consent screen
    • Configure app name, support email, and developer contact.
    • Scopes: openid, email, profile.
    • For public launch: set publishing status to In production (Testing mode only allows listed test users).
  2. Credentials → Create credentials → OAuth client ID
    • Application type: Web application
    • Authorized JavaScript origins: https://endowment.zeroauthoritydao.com
    • Authorized redirect URIs:
      https://endowment.zeroauthoritydao.com/api/auth/oauth/google/callback
  3. Copy Client ID and Client secret.

Do not use Desktop or Android client types for this website flow.

Verify: Log in → Google on the live site.


Microsoft (Entra ID) — not live yet

Microsoft appears in the login UI but engineering has not enabled it. When you are asked to set it up, use the same production callback pattern.

Portal: Microsoft Entra admin center → App registrations → New registration

Field Value
Name Endowment (or your product name)
Supported account types Personal + work/school accounts (if you want both)
Redirect URI (Web) https://endowment.zeroauthoritydao.com/api/auth/oauth/microsoft/callback

Then: copy Application (client) ID; create a client secret under Certificates & secrets; add Graph delegated permissions openid, email, profile, User.Read as directed by engineering.


Troubleshooting (production)

Symptom Likely cause What to check
redirect_uri_mismatch Callback in portal ≠ live URL Production callback table above; no typo or trailing slash
invalid_client Wrong or rotated secret Re-copy Client ID and secret into hosting env
Google “Access blocked” App still in Testing Publish consent screen or add user as test user
Discord “Invalid OAuth2 redirect_uri” Redirect not added OAuth2 → Redirects in Discord portal
X login fails OAuth 2.0 off or wrong callbacks User authentication settings and callback list

Appendix: local development configuration (engineers only)

This section is not for production setup. It explains optional dev settings when someone runs the app on their own machine (pnpm dev). The app owner normally only needs the production sections above.

Dev app URL and callbacks

Item Dev value
Base URL http://localhost:3000
X callback http://localhost:3000/api/auth/oauth/x/callback
Discord callback http://localhost:3000/api/auth/oauth/discord/callback
Google callback http://localhost:3000/api/auth/oauth/google/callback
Google JS origin http://localhost:3000

Add these in addition to production URLs in each provider portal if engineers need to test login locally.

Dev environment file (.env)

  • .env.example in packages/web is a dev template only (placeholders, safe to commit).
  • Engineers copy it to .env (gitignored) on their laptop.
  • Production does not use .env from the repo; production uses hosting secrets with the same variable names.

Dev .env example:

AUTH_SECRET="dev-only-secret-at-least-32-characters-long"
APP_BASE_URL="http://localhost:3000"
X_CLIENT_ID="..."
X_CLIENT_SECRET="..."
DISCORD_CLIENT_ID="..."
DISCORD_CLIENT_SECRET="..."
GOOGLE_CLIENT_ID="..."
GOOGLE_CLIENT_SECRET="..."

Dev verify: From the repo, run pnpm dev, open http://localhost:3000, and test Log in for each provider.


Reference (engineering)

Provider Code Login start route Callback path
X x-oauth.ts /api/auth/x/start /api/auth/oauth/x/callback
Discord discord-oauth.ts /api/auth/discord/start /api/auth/oauth/discord/callback
Google google-oauth.ts /api/auth/google/start /api/auth/oauth/google/callback

Env validation: packages/web/src/env.js · Dev template: packages/web/.env.example

Clone this wiki locally