Files
freno-dev/.env.example
Michael Freno 6898186df5 nessa: retire the API copy now served by nessa-api.freno.me
The Nessa API (nessaDb.*, nessa.community.*, Clerk auth and the Clerk user
webhook) lives in the Nessa repo's server/ on pan. This copy never served
the app: RemoteAPIClient wraps every input in {"input": …}, which the stock
tRPC adapter here reads as the input itself (queries 404, writes no-op).
Clerk's webhook already targets nessa-api.freno.me.

Drops the routers, nessa-auth, the webhook, NessaConnectionFactory, the
NESSA_* env and the now-unused @clerk/backend and svix. Nessa's marketing,
privacy and deletion pages stay.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 13:54:14 -04:00

89 lines
5.1 KiB
Plaintext

# ──────────────────────────────────────────────────────────────────────────
# freno-dev environment variables — example / template
# ──────────────────────────────────────────────────────────────────────────
# Copy this file to `.env` and fill in real values.
# `.env` is gitignored and MUST NEVER be committed. Real secret values must
# come from your local environment or your team's secret manager — never from
# git history. See the root `AGENTS.md` "Secret Management & Rotation" section
# and `docs/security/secret-rotation-runbook.md`.
#
# The schema in `src/env/server.ts` validates PRESENCE + min length for every
# variable below. Do not leave production values blank.
# ──────────────────────────────────────────────────────────────────────────
# ── Frontend / public (safe to expose to the browser, VITE_* is shipped) ──
VITE_DOMAIN="http://localhost:3000"
VITE_AWS_BUCKET_STRING="https://example-bucket.s3.amazonaws.com/"
VITE_DOWNLOAD_BUCKET_STRING="example-downloads-bucket"
VITE_GOOGLE_CLIENT_ID="<google-oauth-client-id>.apps.googleusercontent.com"
VITE_GOOGLE_CLIENT_ID_DEV="<google-oauth-client-id-dev>.apps.googleusercontent.com"
VITE_GOOGLE_CLIENT_ID_MAGIC_DELVE="<google-oauth-client-id-magicdelve>.apps.googleusercontent.com"
VITE_GITHUB_CLIENT_ID="<github-oauth-client-id>"
VITE_GITHUB_CLIENT_ID_DEV="<github-oauth-client-id-dev>"
VITE_INFILL_ENDPOINT="https://infill.example.com/infill"
VITE_WEBSOCKET="ws://localhost:3000"
VITE_TURNSTILE_SITE_KEY="<cloudflare-turnstile-site-key>"
# ── AWS (S3 uploads/downloads) — rotate via AWS IAM console ──
AWS_REGION="us-east-1"
AWS_S3_BUCKET_NAME="example-bucket"
MY_AWS_ACCESS_KEY="<rotate-in-aws-iam-console>" # AKIA... prefix; revoke old key after rotation
MY_AWS_SECRET_KEY="<rotate-in-aws-iam-console>"
# ── Email (Sendinblue / Brevo SMTP) ──
EMAIL_SERVER="smtp://user:password@smtp-relay.sendinblue.com:587"
EMAIL_FROM="you@example.com"
SENDINBLUE_KEY="<rotate-in-brevo-console>"
# ── Auth / signing secrets (generate with: openssl rand -base64 64) ──
JWT_SECRET_KEY="<generate-64-byte-base64>" # web JWT (HS256) signing
LINEAGE_JWT_SECRET="<generate-64-byte-base64>" # Lineage game JWT (HS256) signing — isolated from web (p8-005)
LINEAGE_OFFLINE_SERIALIZATION_SECRET="<generate-64-byte-base64>" # offline lineage blob signing
# ── OAuth client secrets — rotate in provider consoles ──
GOOGLE_CLIENT_SECRET="<rotate-in-google-cloud-console>" # GOCSPX-...
GOOGLE_CLIENT_SECRET_DEV="<rotate-in-google-cloud-console>"
GITHUB_CLIENT_SECRET="<rotate-in-github-oauth-apps>"
GITHUB_CLIENT_SECRET_DEV="<rotate-in-github-oauth-apps>"
# ── Cloudflare Turnstile ──
TURNSTILE_SECRET_KEY="<rotate-in-cloudflare-dashboard>" # 0x...
# ── Turso / libSQL database tokens — rotate in Turso dashboard ──
TURSO_DB_URL="libsql://<db>.turso.io"
TURSO_DB_TOKEN="<rotate-in-turso-dashboard>" # eyJ...
TURSO_DB_API_TOKEN="<rotate-in-turso-dashboard>" # org-level API token
TURSO_LINEAGE_URL="libsql://<lineage-db>.turso.io"
TURSO_LINEAGE_TOKEN="<rotate-in-turso-dashboard>"
APPLE_CLIENT_ID_LINEAGE=com...
# ── Infra / integration tokens ──
INFILL_BEARER_TOKEN="<rotate-at-infill-service>"
GITEA_URL="https://gitea.example.com"
GITEA_TOKEN="<rotate-in-gitea>"
GITHUB_API_TOKEN="<rotate-in-github-settings>" # ghp_... / github_pat_...
# ── Sentry (error tracking + source maps) ──
# Source maps upload — create a token at: Settings > Projects > freno-dev > Client Keys (DSN) > Auth Token
# or generate an internal auth token at: https://sentry.io/settings/account/api/keys/
SENTRY_AUTH_TOKEN="sntrys_<generate-in-sentry-dashboard>"
# ── The Nook licensing ──
NOOK_DB_URL="libsql://<nook-db>.turso.io"
NOOK_DB_TOKEN="<rotate-in-turso-dashboard>" # eyJ...
NOOK_LICENSE_PRIVATE_KEY="<generate-license-keypair>" # base64 PKCS8 Ed25519 private key (scripts/generate-license-keys.ts)
NOOK_STRIPE_SK="sk_live_<rotate-in-stripe-dashboard>"
NOOK_STRIPE_WEBHOOK_SECRET="whsec_<rotate-in-stripe-dashboard>"
NOOK_STRIPE_PRICE_ID="price_<from-stripe-dashboard>"
# ── The Nook lifecycle emails ──
# Daily cron (vercel.json → /api/the-nook/lifecycle) requires a Bearer secret.
# Set CRON_SECRET and Vercel attaches it automatically to scheduled runs.
# Generate: openssl rand -base64 64 | tr -d '\n'
CRON_SECRET="<openssl-rand-base64>"
# Optional override for the secret the endpoint accepts (falls back to CRON_SECRET).
NOOK_LIFECYCLE_SECRET=""
# Optional Brevo list id trial-start emails are added to (the lifecycle audience).
NOOK_TRIAL_LIST_ID=""