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 devworks with zero credentials. If you are new, start atONBOARDING.mdand 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.jsonengines requires>=24) and npm 11+ (check withnode --version/npm --version). A version manager likenvm,fnm, orasdfauto-selects the.nvmrcversion. - Git configured with your work email + 2FA on your GitHub account
- GCP access to
lantern-app-devwithroles/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) gcloudCLI installed โ https://cloud.google.com/sdk/docs/install (preinstalled in the Codespaces dev container)
๐ก
firebase-toolsis not required for setup โ the public Firebase config now comes from Secret Manager. Install it only if you want the emulators orfirebase: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:
# 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 doctorIf 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 devin 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):
gcloud auth login --no-launch-browser
gcloud auth application-default login --no-launch-browser
npm run env:bootstrapOpen http://localhost:5173. Browser console should print:
๐ฅ Firebase initialized (local environment)
Project: lantern-app-devIf you see that, you're connected correctly.
What npm run env:bootstrap does โ
The script (tooling/scripts/bootstrap-env.mjs):
- Creates
.env.localfrom.env.local.exampleif it doesn't exist yet - Fetches all server-side secrets from GCP Secret Manager (Cloudflare/Resend/Anthropic/Discord/etc.)
- Fetches the 7 public Firebase config values (
VITE_FIREBASE_*) โ these are now mirrored into Secret Manager, so the samegcloud authcovers them (nofirebase login/ firebase-tools needed) - 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 - 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):
| Variable | What it is | How to get it |
|---|---|---|
GH_PAT | Your personal GitHub PAT (repo scope) | https://github.com/settings/tokens |
GITHUB_OWNER | Your GitHub username | Your username (e.g. mechelle) |
GOOGLE_APPLICATION_CREDENTIALS | Path to a service-account JSON key | Needed 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_PHONE | Your own Prelude test number | The 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_LOCATION | Optional "lat,long" map spoof | For 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 โ
| Command | When to use |
|---|---|
npm run env:bootstrap | First-time setup, or after a new secret is added to SECRET_MAP |
npm run env:bootstrap:dry-run | Preview what would be written without modifying .env.local |
npm run env:bootstrap:force | After 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:
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:
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=localCopy 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) โ
# .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:
- Go to Profile Settings (
#/profile) - Click the "Privacy" tab
- Scroll to the purple "๐ง Dev: Location Spoofing" panel
- 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:
const hostname = typeof window !== 'undefined' ? window.location.hostname : ''
const isProductionEnv =
import.meta.env.VITE_APP_ENV === 'production' || hostname === 'ourlantern.app'
const isDev = !isProductionEnvWhy hostname check?
import.meta.env.DEVonly 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" buttonapps/web/src/screens/profile/ProfileSettings.jsxโ Location spoof panelapps/web/src/firebase.jsโ Firebase environment logging
Common issues โ
| Symptom | Fix |
|---|---|
npm run env:bootstrap reports permission for every secret | Maintainer hasn't granted you roles/secretmanager.secretAccessor yet. See Granting access |
npm run env:bootstrap reports auth | Run 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 console | Neither .env.local nor /.env.development has VITE_FIREBASE_* values. Re-run bootstrap or check the committed fallback |
| Wrong Firebase project connecting | VITE_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 โ
- Developer Onboarding: broader context (architecture, code conventions, where to find things)
- Secrets Management โ deep dive on the secret/env system
- AGENTS.md โ project rules and commands
For deploying / Cloudflare Pages / prod Firebase projects โ INITIAL_PROJECT_SETUP.md (historical reference, not forward-looking).