Integrations & Environment Variables
This article documents the major third-party integrations used by shenoylabs-web, where they are wired in the codebase, required environment variables (server vs public), common failure modes, and recommended security and operational practices.
Overview
Request flow patterns: Client -> Next.js (App Router + Route Handlers) -> External services (Upstash, Resend, GitHub, Vercel, Turnstile). Some components run at the Edge (middleware) while API route handlers use Node-capable runtimes; see the Architecture section for runtime details.
Per-integration summary
TinaCMS
- Purpose: content authoring and schema-driven editing.
- Key files:
tina/config.ts, generated schema intina/__generated__/. - Env:
TINA_TOKEN(server),NEXT_PUBLIC_TINA_CLIENT_ID(public). - Failure modes: missing/invalid token at build/admin time → admin/CI failures.
- Recommendation: use minimal-scope Tina tokens stored in platform secrets; run admin build in CI.
Upstash (Redis KV via REST)
- Purpose: rate-limiting buckets, consent event queue, DSR queues, ephemeral token storage.
- Key file:
src/lib/upstash.ts. - Env:
KV_REST_API_URL,KV_REST_API_TOKEN(write),KV_REST_API_READ_ONLY_TOKEN. - Failure modes: auth failures, high latencies, throttling causing API timeouts.
- Recommendation: use separate read/write tokens, monitor latency/error metrics, set TTLs for ephemeral keys, rotate tokens regularly.
Cloudflare Turnstile
- Purpose: bot protection on contact form.
- Key files:
src/components/contact/contact-form.tsx(client) andsrc/app/api/contact/route.ts(server). - Env:
NEXT_PUBLIC_TURNSTILE_SITE_KEY(public),TURNSTILE_SECRET_KEY(server). - Failure modes: misconfigured keys, token replay or missing verification.
- Recommendation: always verify tokens server-side, use test keys in dev, log and alert on verification failure spikes.
Resend (email delivery)
- Purpose: sending contact emails.
- Key file:
src/app/api/contact/route.ts. - Env:
RESEND_API_KEY,CONTACT_FROM_EMAIL,CONTACT_TO_EMAIL. - Failure modes: API key revoked, quota exceeded, bounces/unhandled rejections.
- Recommendation: monitor send errors, implement retries/backoff, use proper email auth (SPF/DKIM).
Google Analytics
- Purpose: client-side analytics.
- Key file:
src/components/analytics/google-analytics.tsx. - Env:
NEXT_PUBLIC_GA_ID. - Recommendation: only initialize after user consent; avoid sending PII.
Vercel automation
- Purpose: programmatic env updates and admin automation (scripts).
- Key file:
scripts/set_vercel_env.sh. - Env:
VERCEL_TOKEN,PROJECT_ID. - Recommendation: keep
VERCEL_TOKENin CI secrets with minimal scope and audit usage.
GitHub (Tina helpers, media PRs)
- Purpose: create branches/commits/PRs for media and CMS edits.
- Key files:
src/app/api/tina/github/route.ts,src/app/api/media/prs/route.ts. - Env:
GITHUB_TOKEN,GITHUB_REPOSITORY,GITHUB_BASE_BRANCH. - Recommendation: prefer a GitHub App or fine-grained PAT, grant minimal scopes, log all repo-write events.
Admin / DSR & Consent
- Purpose: ingest consent events, export/delete DSR data.
- Key files:
src/app/api/consent/route.ts,src/app/api/dsr/route.ts. - Env:
CONSENT_ADMIN_KEY. - Recommendation: require
CONSENT_ADMIN_KEYheader for admin routes, rotate key regularly, log all exports/deletes.
Environment variable catalogue (high level)
Server-only (must be stored as secrets)
GITHUB_TOKEN,GITHUB_REPOSITORY,GITHUB_BASE_BRANCHTINA_TOKEN,TINA_GITHUB_TOKENKV_REST_API_URL,KV_REST_API_TOKEN,KV_REST_API_READ_ONLY_TOKENTURNSTILE_SECRET_KEYRESEND_API_KEYCONSENT_ADMIN_KEYVERCEL_TOKEN,PROJECT_IDRATE_LIMIT_COOKIE_SECRET,UPSTASH_CONSENT_KEY,CONSENT_RETENTION_DAYS
Public (safe to be exposed client-side)
NEXT_PUBLIC_TINA_CLIENT_IDNEXT_PUBLIC_TURNSTILE_SITE_KEYNEXT_PUBLIC_GA_IDNEXT_PUBLIC_RAZORPAY_PAYMENT_BUTTON_IDNEXT_PUBLIC_SITE_URL,NEXT_PUBLIC_BASE_URL
Sanitized .env example (DO NOT COMMIT)
KV_REST_API_URL=https://us1-kv.upstash.io/v1/xxxxx
KV_REST_API_TOKEN=REDACTED_WRITE_TOKEN
KV_REST_API_READ_ONLY_TOKEN=REDACTED_READ_TOKEN
NEXT_PUBLIC_TURNSTILE_SITE_KEY=REDACTED_SITE_KEY
TURNSTILE_SECRET_KEY=REDACTED_TURNSTILE_SECRET
RESEND_API_KEY=REDACTED_RESEND_KEY
CONTACT_FROM_EMAIL=hello@example.com
CONTACT_TO_EMAIL=ops@example.com
GITHUB_TOKEN=REDACTED_GITHUB_TOKEN
CONSENT_ADMIN_KEY=REDACTED_ADMIN_KEY
NEXT_PUBLIC_GA_ID=G-XXXXXXXXX
NEXT_PUBLIC_SITE_URL=https://example.com
Security & operational recommendations
- Secrets storage: keep production secrets in the platform secret store (Vercel/GitHub Actions/HashiCorp Vault). Never commit secrets.
- Least privilege: use read/write separation for Upstash, scoped API keys for emails, and GitHub App / minimal PAT for repo writes.
- Rotation: rotate high-risk tokens (GitHub, Upstash write token, Resend) every 60–90 days; rotate
CONSENT_ADMIN_KEYmore frequently if human-accessed. - Logging & audit: log admin/DSR operations and PR/commit events; redact token-like strings from logs.
- Edge caution: confirm that Edge env vars are not leaked into client bundles; validate provider-specific behavior.
- Dev fallbacks: local file fallbacks for consent/DSR exist for dev; ensure these are disabled in production (
VERCEL=1orNODE_ENV=productionchecks).
Monitoring & alerts (ops checklist)
- Alert on Upstash error rate or latency spikes.
- Alert on Turnstile verification failure surge (possible bot attack).
- Alert on Resend send failures and bounce rates.
- Monitor GitHub API errors and rate-limit warnings.
- Schedule periodic Playwright E2E runs in CI to validate contact, consent, and admin flows.
References (code pointers)
- Upstash wrapper:
src/lib/upstash.ts - Contact UI:
src/components/contact/contact-form.tsx - Contact API:
src/app/api/contact/route.ts - Consent & DSR:
src/app/api/consent/route.ts,src/app/api/dsr/route.ts - Tina helpers:
src/app/api/tina/github/route.ts - Media PRs:
src/app/api/media/prs/route.ts - Vercel scripts:
scripts/set_vercel_env.sh
Diagrams

How to run & test locally
Sanity commands to run this site locally for development and testing:
pnpm install
pnpm build
PORT=3001 pnpm start
# unit tests
pnpm test
# playwright E2E (requires running server)
npx playwright test
Set only sanitized env values in .env.local when testing locally. See the Sanitized .env example earlier in this article.
Runbooks
Detailed runbooks have been moved to the docs/runbooks/ folder. Use the
following links for step-by-step diagnostics and mitigation actions:
- Upstash KV runbook
- Cloudflare Turnstile runbook
- Resend (email) runbook
- GitHub PR/commit runbook
- Consent / DSR runbook
You can also view the runbook index at docs/runbooks/README.md.
Short, sanitized code examples
Upstash REST read (sanitized)
const res = await fetch(`${process.env.KV_REST_API_URL}/string/example`, {
headers: { Authorization: `Bearer ${process.env.KV_REST_API_READ_ONLY_TOKEN}` }
});
const data = await res.json();
Safe logging & redaction
function redactToken(t) {
if (!t) return t;
return `${t.slice(0,4)}…${t.slice(-4)}`;
}
console.log('Upstash token (partial):', redactToken(process.env.KV_REST_API_TOKEN));
Observability & Alerts (recommendations)
- Track request latency (p50/p95/p99) for
POST /api/contactand for middleware path handlers. - Monitor Upstash: error rate, latency, and throttle counts.
- Monitor Turnstile verification failure rate and token replay patterns.
- Monitor Resend: send error rate, bounce percentage, and DKIM/SPF failures.
- Monitor GitHub API errors (401/403/429) for repository operations.
- Add alerts for sudden spikes in blocked requests or consent exports.
CI: nightly/scheduled Playwright runs (example)
Add a scheduled job to run critical E2E flows nightly. Example GitHub Actions job snippet:
name: Nightly Playwright
on:
schedule:
- cron: '0 2 * * *' # daily at 02:00 UTC
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- run: pnpm install
- run: pnpm build
- run: PORT=3001 pnpm start & sleep 6
- run: npx playwright test
Accessibility checks
- Integrate
axe-coreor Playwright accessibility checks into CI for article pages and interactive flows (contact form, cookie banner). - Example: use
playwright-axeor run axe assertions inside Playwright tests.
Appendix: environment variables
| Variable | Purpose | Server / Public | Required (prod) | Notes |
|---|---|---|---|---|
GITHUB_TOKEN | GitHub PAT for PRs/commits | Server | Yes | Prefer GitHub App or fine-grained PAT |
GITHUB_REPOSITORY | owner/repo for GitHub API | Server | Yes | e.g. owner/repo |
GITHUB_BASE_BRANCH | base branch for PRs | Server | Yes | |
TINA_TOKEN | Tina admin/build token | Server | Yes | Minimal scope |
NEXT_PUBLIC_TINA_CLIENT_ID | Tina client id (admin UI) | Public | Yes | Safe to expose |
KV_REST_API_URL | Upstash REST base URL | Server | Yes | |
KV_REST_API_TOKEN | Upstash write token | Server | Yes | Rotate regularly |
KV_REST_API_READ_ONLY_TOKEN | Upstash read token | Server | Optional | Use for read-only operations |
NEXT_PUBLIC_TURNSTILE_SITE_KEY | Turnstile client key | Public | Yes | Client-only |
TURNSTILE_SECRET_KEY | Turnstile verification secret | Server | Yes | Server-only |
RESEND_API_KEY | Resend email API key | Server | Yes | Monitor usage |
CONTACT_FROM_EMAIL | Sender address for contact | Server | Yes | |
CONTACT_TO_EMAIL | Destination for contact | Server | Yes | |
CONSENT_ADMIN_KEY | Protects consent/DSR endpoints | Server | Yes | Rotate regularly |
VERCEL_TOKEN | Vercel API token for scripts | Server/CI | Yes | Store in CI secrets |
Ops checklist (pre-release)
- Ensure all required secrets exist in Vercel/GitHub Actions and are not
NEXT_PUBLIC_unless intended. - Run
pnpm buildand verify no build-time secret failures. - Run
pnpm testandnpx playwright testagainst a staging deployment. - Validate Upstash connectivity and quotas.
- Verify Turnstile token verification succeeds in staging.
- Confirm Resend send flow and DKIM/SPF records.
- Run accessibility smoke tests and fix high-severity findings.
Publishing & frontmatter suggestions
- Add
authorandherofrontmatter fields to surface the article in site lists and social previews. For example:
author: "Your Name"
hero: "/images/blueprint/blueprint-hero.png"