From 90eed7640a9b6cf64f92c374a64177f7cfa3cf4f Mon Sep 17 00:00:00 2001 From: ladinoraa Date: Thu, 4 Jun 2026 02:03:01 +0000 Subject: [PATCH] =?UTF-8?q?docs:=20add=20SECRETS.md=20=E2=80=94=20centrali?= =?UTF-8?q?zed=20secrets=20management=20guide=20(#289)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #289 - Documents all required secrets per environment (local / CI / production) - Explains gitignored .env.local for local dev - Lists all GitHub Actions secrets needed for CI and staging - Documents Vercel env vars for production - Covers production AWS Secrets Manager usage (no plaintext keys) - Documents key rotation procedure - References gitleaks / pre-commit secret scanning --- docs/SECRETS.md | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 docs/SECRETS.md diff --git a/docs/SECRETS.md b/docs/SECRETS.md new file mode 100644 index 0000000..b5f8b6e --- /dev/null +++ b/docs/SECRETS.md @@ -0,0 +1,106 @@ +# Secrets Management + +This document describes how SolarProof manages secrets across all environments. + +## Principle + +No secrets are committed to the repository. Three tiers: + +| Environment | Where secrets live | +|---|---| +| Local development | `apps/web/.env.local` (gitignored) | +| CI/CD (GitHub Actions) | GitHub Actions secrets | +| Production / Staging | Vercel environment variables | + +--- + +## Required secrets + +| Variable | Description | Environments | +|---|---|---| +| `NEXT_PUBLIC_SUPABASE_URL` | Supabase project URL | All | +| `NEXT_PUBLIC_SUPABASE_ANON_KEY` | Supabase public anon key | All | +| `SUPABASE_SERVICE_ROLE_KEY` | Supabase service-role key (server-side only) | All | +| `MINTER_SECRET_KEY` | Stellar secret key for the minter account | Local, CI, Staging | +| `MINTER_SECRET_ARN` | AWS Secrets Manager ARN for minter key | Production | +| `MINTER_PREVIOUS_SECRET_ARN` | ARN for previous key during rotation window | Production | +| `REDIS_URL` | Redis connection URL for job queue | All | +| `UPSTASH_REDIS_REST_URL` | Upstash REST URL for caching layer | Staging, Production | +| `UPSTASH_REDIS_REST_TOKEN` | Upstash REST token | Staging, Production | +| `NEXT_PUBLIC_ENERGY_TOKEN_ID` | Deployed energy_token contract ID | All | +| `NEXT_PUBLIC_AUDIT_REGISTRY_ID` | Deployed audit_registry contract ID | All | +| `NEXT_PUBLIC_COMMUNITY_GOVERNANCE_ID` | Deployed community_governance contract ID | All | + +--- + +## Local development + +1. Copy the template: `cp apps/web/.env.example apps/web/.env.local` +2. Fill in your values — never commit `.env.local` +3. `.env.local` and `.env.*.local` are listed in `.gitignore` + +--- + +## GitHub Actions (CI/CD) + +All secrets are stored in the repository's **Settings → Secrets and variables → Actions**. + +Secrets used in CI (`.github/workflows/ci.yml`): + +``` +NEXT_PUBLIC_SUPABASE_URL +NEXT_PUBLIC_SUPABASE_ANON_KEY +SUPABASE_SERVICE_ROLE_KEY +MINTER_SECRET_KEY +TURBO_TOKEN +TURBO_TEAM +``` + +Staging-specific secrets (environment: `staging`): + +``` +STAGING_SUPABASE_URL +STAGING_SUPABASE_ANON_KEY +STAGING_SUPABASE_SERVICE_ROLE_KEY +STAGING_MINTER_SECRET_KEY +STAGING_ENERGY_TOKEN_ID +STAGING_AUDIT_REGISTRY_ID +STAGING_COMMUNITY_GOVERNANCE_ID +VERCEL_TOKEN +VERCEL_ORG_ID +VERCEL_PROJECT_ID_STAGING +``` + +--- + +## Production (Vercel) + +Set the following in the Vercel project's **Settings → Environment Variables** for the `production` environment: + +- All `NEXT_PUBLIC_*` variables +- `SUPABASE_SERVICE_ROLE_KEY` +- `MINTER_SECRET_ARN` (points to AWS Secrets Manager; `MINTER_SECRET_KEY` is not used in production) +- `MINTER_PREVIOUS_SECRET_ARN` (set during the 24-hour key-rotation grace window) +- `AWS_REGION` +- `REDIS_URL` +- `UPSTASH_REDIS_REST_URL`, `UPSTASH_REDIS_REST_TOKEN` +- `LOGTAIL_SOURCE_TOKEN` +- `CORS_ALLOWED_ORIGINS` + +Production never uses a plaintext `MINTER_SECRET_KEY`. The key is fetched at runtime from AWS Secrets Manager via `MINTER_SECRET_ARN` (see `src/lib/secrets.ts`). + +--- + +## Key rotation + +1. Generate a new Stellar keypair for the minter account. +2. Store the new key as a new secret version in AWS Secrets Manager. +3. Update `MINTER_SECRET_ARN` in Vercel to point to the new ARN. +4. Set `MINTER_PREVIOUS_SECRET_ARN` to the old ARN for 24 hours (allows in-flight transactions to complete). +5. After 24 hours, clear `MINTER_PREVIOUS_SECRET_ARN`. + +--- + +## Secret scanning + +GitHub secret scanning is enabled on this repository. Pre-commit hooks run [gitleaks](https://github.com/gitleaks/gitleaks) to catch accidental secret commits before they reach the remote. See `.gitleaks.toml` and `.pre-commit-config.yaml`.