> ## Documentation Index
> Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets Management Guide

> Version: 1.0.0 Last Updated: 2025-01-07

**Version:** 1.0.0\
**Last Updated:** 2025-01-07

This guide documents the secrets management strategy for the Encore Health OS Platform, covering development, staging, and production environments.

***

## Table of Contents

1. [Overview](#overview)
2. [Secrets Inventory](#secrets-inventory)
3. [Development Secrets](#development-secrets)
4. [Production Secrets](#production-secrets)
5. [Key Rotation Procedures](#key-rotation-procedures)
6. [Access Control](#access-control)
7. [Audit Logging](#audit-logging)
8. [Emergency Procedures](#emergency-procedures)
9. [Best Practices](#best-practices)
10. [Troubleshooting](#troubleshooting)

***

## Overview

Secrets management is critical for security and compliance. This guide covers:

* Where secrets are stored
* How to access secrets
* Key rotation procedures
* Access control policies
* Audit logging requirements

**Principle:** Never commit secrets to version control. Always use secure secret management systems.

***

## Secrets Inventory

### Client-Side Secrets (Environment Variables)

**Location:** `.env.local` (development) or Vercel Environment Variables (production)

| Secret                          | Purpose              | Client Access | Security Level     |
| ------------------------------- | -------------------- | ------------- | ------------------ |
| `VITE_SUPABASE_URL`             | Supabase project URL | ✅ Public      | Low (public URL)   |
| `VITE_SUPABASE_PUBLISHABLE_KEY` | Supabase anon key    | ✅ Public      | Low (RLS enforced) |

**Note:** All `VITE_*` variables are exposed to the client bundle. Never put sensitive secrets in `VITE_*` variables.

### Server-Side Secrets (Supabase Edge Functions)

**Location:** Supabase Secrets (set via CLI or Dashboard)

| Secret                       | Purpose                      | Function                              | Security Level  |
| ---------------------------- | ---------------------------- | ------------------------------------- | --------------- |
| `SUPABASE_SERVICE_ROLE_KEY`  | Bypass RLS (edge functions)  | All functions                         | ⚠️ **CRITICAL** |
| `ENTRA_CLIENT_SECRET`        | Entra ID / Graph API (email) | Email provider (Entra)                | High            |
| `GMAIL_SERVICE_ACCOUNT_JSON` | Gmail API (org-level email)  | Email provider (Gmail)                | High            |
| `TWILIO_ACCOUNT_SID`         | SMS delivery                 | `send-sms-notification`               | High            |
| `TWILIO_AUTH_TOKEN`          | SMS delivery                 | `send-sms-notification`               | ⚠️ **CRITICAL** |
| `TWILIO_PHONE_NUMBER`        | SMS sender number            | `send-sms-notification`               | Medium          |
| `LOVABLE_API_KEY`            | AI Gateway access            | `ai-assistant`, `ai-document-analyze` | High            |

Email (notifications, HR, automation, and signature flows) uses the shared org-level provider (Entra or Gmail).

### Testing Secrets (Development Only)

**Location:** `.env.local` (gitignored)

| Secret                      | Purpose              | Usage          | Security Level  |
| --------------------------- | -------------------- | -------------- | --------------- |
| `SUPABASE_SERVICE_ROLE_KEY` | Test database access | RLS tests only | ⚠️ **CRITICAL** |

**⚠️ NEVER use service role key in client code, even in development!**

***

## Development Secrets

### Local Development Setup

**1. Create `.env.local` file:**

```bash theme={null}
# Copy from template
cp .env.example .env.local

# Edit with your values
# ⚠️ NEVER commit .env.local
```

**2. Add to `.gitignore`:**

```gitignore theme={null}
# Already in .gitignore
.env.local
.env*.local
```

**3. Required Variables:**

```bash theme={null}
# Supabase (Required)
VITE_SUPABASE_URL=https://your-project.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=your-anon-key

# Testing Only (Development)
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
```

### Local Supabase Secrets

**For Local Edge Functions:**

```bash theme={null}
# Start Supabase locally
supabase start

# Secrets are auto-provided for local functions
# No manual setup needed
```

***

## Production Secrets

### Supabase Edge Function Secrets

**Set via Supabase CLI:**

```bash theme={null}
# Link to production project
supabase link --project-ref {project-ref}

# Set secrets (email: use Entra and/or Gmail)
supabase secrets set TWILIO_ACCOUNT_SID=ACxxxxx
supabase secrets set TWILIO_AUTH_TOKEN=xxxxx
supabase secrets set TWILIO_PHONE_NUMBER=+1234567890
supabase secrets set LOVABLE_API_KEY=xxxxx
```

**Set via Supabase Dashboard:**

1. Go to **Project Settings** → **Edge Functions** → **Secrets**
2. Click **Add Secret**
3. Enter key and value
4. Click **Save**

**List Secrets:**

```bash theme={null}
supabase secrets list
```

**Unset Secret:**

```bash theme={null}
supabase secrets unset GMAIL_SERVICE_ACCOUNT_JSON
```

### Vercel Environment Variables

**For Client Application:**

1. Go to Vercel Dashboard → Project → Settings → Environment Variables
2. Add variables:
   * `VITE_SUPABASE_URL` (Production)
   * `VITE_SUPABASE_PUBLISHABLE_KEY` (Production)
3. **Do NOT** add `SUPABASE_SERVICE_ROLE_KEY` (never in client)

**Environment-Specific:**

* Set variables per environment (Production, Preview, Development)
* Use Production values for production deployments

***

## Key Rotation Procedures

### Supabase Service Role Key

**⚠️ CRITICAL:** Service role key bypasses all RLS policies. Rotate immediately if compromised.

**Rotation Steps:**

1. **Generate New Key:**
   * Go to Supabase Dashboard → Settings → API
   * Click **Reset service\_role key**
   * Copy new key (save securely)

2. **Update Edge Functions:**
   ```bash theme={null}
   supabase secrets set SUPABASE_SERVICE_ROLE_KEY={new-key}
   ```

3. **Update Test Environment:**
   * Update `.env.local` with new key
   * Verify tests still pass

4. **Verify Functions Work:**
   * Test edge functions that use service role key
   * Check function logs for errors

5. **Revoke Old Key:**
   * Old key is automatically invalidated when reset

**Rotation Frequency:** Every 90 days (or immediately if compromised)

### Entra Client Secret / Gmail Service Account

**Entra:** Rotate in Azure Portal (App registration → Certificates & secrets). Update `ENTRA_CLIENT_SECRET` in Supabase secrets. **Rotation frequency:** Per Microsoft guidance (e.g. before expiry).

**Gmail:** Create a new service account key in Google Cloud Console, set `GMAIL_SERVICE_ACCOUNT_JSON`, then remove the old key. **Rotation frequency:** Every 180 days (or if compromised).

### Twilio Credentials

**Rotation Steps:**

1. **Generate New Auth Token:**
   * Go to Twilio Console → Account → API Keys & Tokens
   * Click **Create** new Auth Token
   * Copy new token

2. **Update Supabase Secrets:**
   ```bash theme={null}
   supabase secrets set TWILIO_AUTH_TOKEN={new-token}
   ```

3. **Deploy Edge Function:**
   ```bash theme={null}
   supabase functions deploy send-sms-notification
   ```

4. **Test SMS Delivery:**
   * Send test SMS
   * Verify delivery

5. **Revoke Old Token:**
   * Delete old token in Twilio console

**Rotation Frequency:** Every 180 days (or if compromised)

**Note:** Account SID and Phone Number don't need rotation (not secrets).

### Supabase Anon Key

**Rotation Steps:**

1. **Generate New Key:**
   * Go to Supabase Dashboard → Settings → API
   * Click **Reset anon key**
   * Copy new key

2. **Update Environment Variables:**
   * Vercel: Update `VITE_SUPABASE_PUBLISHABLE_KEY`
   * Local: Update `.env.local`

3. **Redeploy Application:**
   * Vercel will auto-deploy with new key
   * Or manually trigger deployment

4. **Verify Application Works:**
   * Test authentication
   * Test database queries
   * Check for errors

**Rotation Frequency:** Every 90 days (or if compromised)

**Note:** Anon key is safe to expose (RLS enforced), but rotation is good practice.

***

## Access Control

### Who Can Access Secrets?

**Development Secrets (`.env.local`):**

* Local developers only
* Never shared via chat/email
* Stored locally only

**Production Secrets (Supabase):**

* Platform team members only
* Access via Supabase CLI (authenticated)
* Or Supabase Dashboard (with 2FA)

**Vercel Environment Variables:**

* Team members with project access
* Set via Vercel Dashboard
* Access logged in Vercel audit log

### Access Policies

**Principle of Least Privilege:**

* Only grant access to those who need it
* Use separate accounts for different environments
* Require 2FA for production access
* Review access quarterly

**Access Review:**

* Quarterly review of who has access
* Remove access for team members who left
* Document access in secure location (not in code)

***

## Audit Logging

### Secret Access Logging

**Supabase:**

* Edge function invocations logged
* Secret access not directly logged (functions use secrets)
* Function execution logs available in dashboard

**Vercel:**

* Environment variable changes logged
* Access via Vercel audit log
* Review quarterly

### What to Log

**Secret Operations:**

* Secret creation
* Secret updates
* Secret deletion
* Key rotations
* Access attempts (if available)

**Log Retention:**

* 90 days for secret operations
* 1 year for security incidents
* Permanent for key rotations

### Monitoring

**Set up alerts for:**

* Unusual secret access patterns
* Failed authentication attempts
* Secret rotation events
* Edge function errors (may indicate secret issues)

***

## Emergency Procedures

### Compromised Secret

**If a secret is compromised:**

1. **Immediately Rotate:**
   * Generate new secret
   * Update in all locations
   * Revoke old secret

2. **Assess Impact:**
   * What data was accessible?
   * When was secret compromised?
   * Who had access?

3. **Notify Team:**
   * Alert security team
   * Document incident
   * Update security procedures if needed

4. **Monitor:**
   * Watch for unauthorized access
   * Review audit logs
   * Check for data breaches

### Lost Secret

**If a secret is lost:**

1. **Regenerate:**
   * Create new secret
   * Update all systems
   * Test functionality

2. **Document:**
   * Record when secret was lost
   * Document recovery steps
   * Update procedures if needed

### Secret Rotation Failure

**If rotation fails:**

1. **Rollback:**
   * Revert to previous secret
   * Verify system works
   * Investigate failure

2. **Fix Issue:**
   * Identify root cause
   * Fix configuration
   * Retry rotation

3. **Document:**
   * Record failure and resolution
   * Update procedures
   * Add monitoring if needed

***

## Best Practices

### 1. Secret Storage

**✅ DO:**

* Store secrets in secure systems (Supabase Secrets, Vercel)
* Use `.env.local` for local development (gitignored)
* Rotate secrets regularly
* Use different secrets per environment

**❌ DON'T:**

* Commit secrets to version control
* Share secrets via chat/email
* Hardcode secrets in code
* Use same secrets across environments

### 2. Secret Access

**✅ DO:**

* Use principle of least privilege
* Require 2FA for production access
* Review access quarterly
* Document who has access

**❌ DON'T:**

* Grant access unnecessarily
* Share accounts
* Store secrets in plain text files
* Leave secrets in code comments

### 3. Secret Rotation

**✅ DO:**

* Rotate secrets regularly (90-180 days)
* Rotate immediately if compromised
* Test rotation in staging first
* Document rotation procedures

**❌ DON'T:**

* Skip rotation
* Rotate without testing
* Use same secret forever
* Forget to update all locations

### 4. Monitoring

**✅ DO:**

* Monitor secret access (if available)
* Set up alerts for unusual activity
* Review audit logs regularly
* Track secret rotation dates

**❌ DON'T:**

* Ignore security alerts
* Skip audit log reviews
* Forget to monitor
* Assume secrets are safe

***

## Troubleshooting

### Issue: Edge Function Can't Access Secret

**Symptoms:**

* Function fails with "not configured" error
* Function returns 500 error

**Solutions:**

1. Verify secret is set:
   ```bash theme={null}
   supabase secrets list
   ```
2. Check secret name matches exactly (case-sensitive)
3. Redeploy function after setting secret:
   ```bash theme={null}
   supabase functions deploy {function-name}
   ```
4. Check function logs in Supabase dashboard

### Issue: Secret Not Found in Production

**Symptoms:**

* Function works locally but fails in production
* "Environment variable not set" error

**Solutions:**

1. Verify you're linked to correct project:
   ```bash theme={null}
   supabase projects list
   supabase link --project-ref {project-ref}
   ```
2. Set secret in production:
   ```bash theme={null}
   supabase secrets set KEY=value --project-ref {project-ref}
   ```
3. Redeploy function to production

### Issue: Service Role Key in Client Code

**Symptoms:**

* Build warnings about service role key
* Security audit flags

**Solutions:**

1. Remove `SUPABASE_SERVICE_ROLE_KEY` from `.env.local`
2. Only use in test files: `tests/**/*.ts`
3. Never import in client code: `src/**/*.tsx`
4. Use `VITE_SUPABASE_PUBLISHABLE_KEY` in client

### Issue: Secret Rotation Broke Function

**Symptoms:**

* Function fails after secret rotation
* Authentication errors

**Solutions:**

1. Verify new secret is correct
2. Check secret name matches exactly
3. Redeploy function after rotation
4. Test function with new secret
5. Rollback if needed (revert to old secret)

***

## Secret Management Checklist

### Development Setup

* [ ] `.env.local` created from `.env.example`
* [ ] `.env.local` in `.gitignore`
* [ ] No secrets committed to version control
* [ ] Service role key only in test files

### Production Setup

* [ ] All edge function secrets set in Supabase
* [ ] Vercel environment variables configured
* [ ] No service role key in client code
* [ ] Secrets rotated within last 90 days
* [ ] Access control reviewed
* [ ] 2FA enabled for production access

### Ongoing Maintenance

* [ ] Quarterly secret rotation
* [ ] Quarterly access review
* [ ] Audit logs reviewed
* [ ] Monitoring alerts configured
* [ ] Emergency procedures documented

***

## Related Documentation

* **Environment Variables:** `docs/development/ENVIRONMENT_VARIABLES.md`
* **Supabase Setup:** `docs/integrations/SUPABASE_SETUP.md`
* **Edge Functions:** `docs/integrations/EDGE_FUNCTIONS.md`
* **Constitution:** `constitution.md` §4.1 (Security)

***

**Document Owner:** Platform Security Team\
**Review Frequency:** Quarterly\
**Last Updated:** 2025-01-07
