Skip to content

Environment Setup: Secrets and Backend Credentials โ€‹

Time to complete: ~5 minutes, once a maintainer has granted you GCP access.

You do not need any of this to run the app. The public dev config is committed, so npm install && npm run dev works with zero credentials. If you are new, start at ONBOARDING.md and come back here only when you touch server-side code, the local backend services, or anything needing a real secret.

This guide covers pulling the secret set from GCP Secret Manager into .env.local.

For maintainers / forkers: the original Firebase project creation, Cloudflare Pages provisioning, and prod-deploy wiring lives in INITIAL_PROJECT_SETUP.md. Those steps are done; you should not need to repeat them.


Prerequisites โ€‹

You already have a working clone and a running app from ONBOARDING.md. For the secrets work on this page you additionally need:

  • Node.js 24.16.0 (pinned in .nvmrc; package.json engines requires >=24) and npm 11+ (check with node --version / npm --version). A version manager like nvm, fnm, or asdf auto-selects the .nvmrc version.
  • Git configured with your work email + 2FA on your GitHub account
  • GCP access to lantern-app-dev with roles/secretmanager.secretAccessor (a maintainer grants this โ€” see Granting access below)
  • Firebase access to lantern-app-dev (auto-included if you're in the GCP project)
  • gcloud CLI installed โ€” https://cloud.google.com/sdk/docs/install (preinstalled in the Codespaces dev container)

๐Ÿ’ก firebase-tools is not required for setup โ€” the public Firebase config now comes from Secret Manager. Install it only if you want the emulators or firebase:rules:deploy:dev (npm install -g firebase-tools).


Setup โ€‹

Assuming you already cloned, ran npm install, and have the app running (see ONBOARDING.md), pulling the secrets is two commands:

bash
# 1. One-time authentication (uses your Google account, no key files)
gcloud auth application-default login

# 2. Populate .env.local from Secret Manager
npm run env:bootstrap

# Check the result at any point (node, deps, gcloud, .env.local, git hooks):
lantern doctor

If env:bootstrap reports a permission error for every secret, a maintainer has not granted you roles/secretmanager.secretAccessor yet. That is a missing grant, not a broken setup: see Granting access, then re-run it. The app keeps running fine in the meantime.

You do not need Docker or a dev container for local development. Local dev is just npm run dev in WSL (or your OS shell). The .devcontainer/ config exists only for GitHub Codespaces. If VS Code's Dev Containers extension prompts you to "Reopen in Container," you can dismiss it (see Common issues if you clicked through and hit a WSL 2 error).

GitHub Codespaces โ€‹

Opening this repo in a Codespace uses .devcontainer/devcontainer.json, which preinstalls Node 24.16.0 + the gcloud CLI and forwards the dev ports (5173 is made public so the PWA manifest loads without the github.dev auth redirect). A fresh Codespace boots npm run dev with zero auth โ€” the public dev Firebase config is committed in /.env.development. To pull the full secret set, run the one-time login (use --no-launch-browser inside the container):

bash
gcloud auth login --no-launch-browser
gcloud auth application-default login --no-launch-browser
npm run env:bootstrap

Open http://localhost:5173. Browser console should print:

๐Ÿ”ฅ Firebase initialized (local environment)
Project: lantern-app-dev

If you see that, you're connected correctly.


What npm run env:bootstrap does โ€‹

The script (tooling/scripts/bootstrap-env.mjs):

  1. Creates .env.local from .env.local.example if it doesn't exist yet
  2. Fetches all server-side secrets from GCP Secret Manager (Cloudflare/Resend/Anthropic/Discord/etc.)
  3. Fetches the 7 public Firebase config values (VITE_FIREBASE_*) โ€” these are now mirrored into Secret Manager, so the same gcloud auth covers them (no firebase login / firebase-tools needed)
  4. Sets the derived project-id constants (GOOGLE_CLOUD_PROJECT, FIREBASE_PROJECT_ID, GCP_PROJECT_ID) from the target project, so local server-side Admin SDK scripts (backfills, deletion tooling) point at the right project instead of the example placeholder
  5. Merges everything into .env.local, preserving existing values

You don't need to copy anything from the Firebase Console manually โ€” the bootstrap handles it. Even before you authenticate, the committed /.env.development supplies the public Firebase config so npm run dev works out of the box.

What you still set by hand โ€‹

Five per-developer values can't be shared from Secret Manager (the bootstrap output prints a short where-to-get-it hint under each one that is still unset):

VariableWhat it isHow to get it
GH_PATYour personal GitHub PAT (repo scope)https://github.com/settings/tokens
GITHUB_OWNERYour GitHub usernameYour username (e.g. mechelle)
GOOGLE_APPLICATION_CREDENTIALSPath to a service-account JSON keyNeeded to run the auth-api locally (phone+PIN login). ADC user creds (gcloud auth application-default login) read Firestore but cannot sign tokens, so createCustomToken fails. Generate a key for the firebase-adminsdk SA and point this at it (keep it outside the repo).
OTP_TEST_PHONEYour own Prelude test numberThe printed default (+16195550100) is a shared fictional number. For OTP work, create a personal test number in the Prelude dashboard (the login comes from Mechelle, ask her for access). Test numbers only: never point OTP flows at a real phone without her explicit approval.
VITE_DEV_TEST_LOCATIONOptional "lat,long" map spoofFor example "37.7749,-122.4194". Leave blank to use your real device location.

Open .env.local after running bootstrap to fill GH_PAT and GITHUB_OWNER. Everything else is populated for you: the Secret Manager values plus the derived project-id constants.

Re-running bootstrap โ€‹

CommandWhen to use
npm run env:bootstrapFirst-time setup, or after a new secret is added to SECRET_MAP
npm run env:bootstrap:dry-runPreview what would be written without modifying .env.local
npm run env:bootstrap:forceAfter a secret is rotated โ€” overwrite existing values

See Secrets Management for the full deep dive.


Granting access (maintainer task) โ€‹

This is one item of the full new-contributor grant checklist (GitHub invite, Docs-tab access, admin login, and more) in ONBOARDING.md Part 1. The secrets-specific grant: before a new dev can run npm run env:bootstrap, grant their Google account the Secret Manager accessor role:

bash
gcloud projects add-iam-policy-binding lantern-app-dev \
  --member="user:newdev@example.com" \
  --role="roles/secretmanager.secretAccessor"

Firebase access is automatically included for any user with project-level access. The VITE_FIREBASE_* config is read from Secret Manager like any other secret (the role above is all that's needed).


Manual fallback โ€‹

If gcloud isn't installable in your environment (unusual โ€” it works on every modern OS), open .env.local.example and copy values from a teammate. The public Firebase config is also committed in /.env.development, so the web app still boots. The bootstrap script prints remediation commands for each failure mode (missing CLI, expired auth, no access).

The minimum vars needed to start the web app:

bash
VITE_FIREBASE_API_KEY=...
VITE_FIREBASE_AUTH_DOMAIN=lantern-app-dev.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=lantern-app-dev
VITE_FIREBASE_STORAGE_BUCKET=lantern-app-dev.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=...
VITE_FIREBASE_APP_ID=...
VITE_APP_ENV=local

Copy the values from Firebase Console โ†’ Project Settings โ†’ Your apps โ†’ Lantern Dev.


Optional: Location Spoofing for Development โ€‹

Lantern's core features (check-ins, nearby users, venue offers) depend on geolocation. To test without physically visiting venues, spoof your location in dev.

Option 1: Environment variable (auto-loads on startup) โ€‹

bash
# .env.local
VITE_DEV_TEST_LOCATION="40.7128,-74.0060"

Get coordinates from Google Maps: right-click any location โ†’ click the coordinates that appear โ†’ paste into .env.local. Restart npm run dev for changes to apply.

Option 2: Debug panel (change on the fly) โ€‹

While running npm run dev:

  1. Go to Profile Settings (#/profile)
  2. Click the "Privacy" tab
  3. Scroll to the purple "๐Ÿšง Dev: Location Spoofing" panel
  4. Enter lat/lng โ†’ click "Set Location"

The spoofed location persists in localStorage until you clear it.

โš ๏ธ Location spoofing is only available in development builds. Production builds use real geolocation regardless of these settings.


Environment detection in code โ€‹

When adding dev-only features (debug panels, simulate buttons, dev-only API calls), use hostname-based detection rather than import.meta.env.DEV:

javascript
const hostname = typeof window !== 'undefined' ? window.location.hostname : ''
const isProductionEnv =
  import.meta.env.VITE_APP_ENV === 'production' || hostname === 'ourlantern.app'
const isDev = !isProductionEnv

Why hostname check?

  • import.meta.env.DEV only works on localhost (Vite dev server)
  • Deployed dev sites (dev.ourlantern.app) need hostname detection
  • Production site (ourlantern.app) should hide all dev features

Examples in codebase:

  • apps/web/src/screens/dashboard/Dashboard.jsx โ€” "Simulate Wave" button
  • apps/web/src/screens/profile/ProfileSettings.jsx โ€” Location spoof panel
  • apps/web/src/firebase.js โ€” Firebase environment logging

Common issues โ€‹

SymptomFix
npm run env:bootstrap reports permission for every secretMaintainer hasn't granted you roles/secretmanager.secretAccessor yet. See Granting access
npm run env:bootstrap reports authRun gcloud auth application-default login again. ADC expired
Bootstrap reports not-found for VITE_FIREBASE_*The public config secrets haven't been mirrored to Secret Manager yet. See SECRETS_MANAGEMENT.md. The committed /.env.development still boots the app meanwhile
"Firebase not initialized" in browser consoleNeither .env.local nor /.env.development has VITE_FIREBASE_* values. Re-run bootstrap or check the committed fallback
Wrong Firebase project connectingVITE_FIREBASE_PROJECT_ID is wrong in .env.local; should be lantern-app-dev for local dev
VS Code nudges "Reopen in Container", or "WSL 2 distro required. The WSL distro is running with WSL 1"You do not need the container for local dev. Dismiss the prompt and run npm run dev in WSL. .devcontainer/ is for GitHub Codespaces only; that WSL error usually just means Docker Desktop is not installed, which local dev does not require

What's next โ€‹

For deploying / Cloudflare Pages / prod Firebase projects โ†’ INITIAL_PROJECT_SETUP.md (historical reference, not forward-looking).

Built with VitePress