# Google Secret Manager Integration Guide

This guide explains how to integrate Google Cloud Secret Manager with your Node.js application to securely manage environment variables.

## Overview

The Google Secret Manager integration allows you to:
- Store sensitive configuration values (passwords, API keys, tokens) in Google Cloud Secret Manager
- Load secrets at application startup and merge them with your existing environment variables
- Maintain backward compatibility with `.env` files for local development
- Use minimal code changes - existing `process.env.VARIABLE_NAME` access continues to work

## Prerequisites

1. **Google Cloud Project** with Secret Manager API enabled
2. **Service Account** with Secret Manager Secret Accessor role
3. **Authentication** - Service account credentials configured (via `GCP_KEY_FILE` or default credentials)

## Setup Instructions

### 1. Enable Secret Manager API

```bash
gcloud services enable secretmanager.googleapis.com --project=YOUR_PROJECT_ID
```

### 2. Create Secrets in Google Secret Manager

Create secrets using the Google Cloud Console or gcloud CLI:

```bash
# Example: Create a database password secret
echo -n "your-secure-password" | gcloud secrets create DB_PASSWORD \
  --project=YOUR_PROJECT_ID \
  --data-file=-

# Example: Create a JWT secret
echo -n "your-jwt-secret-key" | gcloud secrets create JWT_SECRET \
  --project=YOUR_PROJECT_ID \
  --data-file=-

# Grant service account access to secrets
gcloud secrets add-iam-policy-binding DB_PASSWORD \
  --member="serviceAccount:YOUR_SERVICE_ACCOUNT@YOUR_PROJECT.iam.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor" \
  --project=YOUR_PROJECT_ID
```

### 3. Configure Environment Variables

Add the following to your `.env` file:

```env
# Google Secret Manager Configuration
USE_GOOGLE_SECRET_MANAGER=true
GCP_PROJECT_ID=your-project-id

# Optional: Prefix for all secret names (e.g., "prod" -> looks for "prod-DB_PASSWORD")
GCP_SECRET_PREFIX=

# Optional: JSON file mapping secret names to env var names
GCP_SECRET_MAP_FILE=./secret-map.json
```

**Important Notes:**
- Set `USE_GOOGLE_SECRET_MANAGER=true` to enable the integration
- `GCP_PROJECT_ID` must be set (same as used for GCS/Vertex AI)
- `GCP_KEY_FILE` should already be configured for other GCP services
- When `USE_GOOGLE_SECRET_MANAGER=false` or not set, the app uses `.env` file only

### 4. Secret Name Mapping

By default, secrets in Google Secret Manager are automatically mapped to environment variables:
- Secret name: `DB_PASSWORD` → Environment variable: `DB_PASSWORD`
- Secret name: `db-password` → Environment variable: `DB_PASSWORD` (hyphens converted to underscores, uppercase)
- Secret name: `jwt-secret-key` → Environment variable: `JWT_SECRET_KEY`

#### Custom Mapping (Optional)

If you need custom mappings, create a JSON file (e.g., `secret-map.json`):

```json
{
  "db-password-prod": "DB_PASSWORD",
  "jwt-secret-key": "JWT_SECRET",
  "okta-client-secret-prod": "OKTA_CLIENT_SECRET"
}
```

Then set in `.env`:
```env
GCP_SECRET_MAP_FILE=./secret-map.json
```

### 5. Secret Prefix (Optional)

If all your secrets share a common prefix:

```env
GCP_SECRET_PREFIX=prod
```

This will look for secrets named `prod-DB_PASSWORD`, `prod-JWT_SECRET`, etc.

## How It Works

1. **Application Startup:**
   - `.env` file is loaded first (provides fallback values)
   - If `USE_GOOGLE_SECRET_MANAGER=true`, secrets are fetched from Google Secret Manager
   - Secrets are merged into `process.env`, overriding `.env` values if they exist
   - Application continues with merged environment variables

2. **Fallback Behavior:**
   - If Secret Manager is disabled or fails, the app falls back to `.env` file
   - No errors are thrown - the app continues with available configuration
   - Logs indicate whether secrets were loaded successfully

3. **Existing Code Compatibility:**
   - No changes needed to existing code
   - Continue using `process.env.VARIABLE_NAME` as before
   - Secrets from GCS automatically populate `process.env`

## Default Secrets Loaded

The service automatically attempts to load these common secrets (if they exist in Secret Manager):

**Database:**
- `DB_HOST`, `DB_PORT`, `DB_NAME`, `DB_USER`, `DB_PASSWORD`

**Authentication:**
- `JWT_SECRET`, `REFRESH_TOKEN_SECRET`, `SESSION_SECRET`

**SSO/Okta:**
- `OKTA_DOMAIN`, `OKTA_CLIENT_ID`, `OKTA_CLIENT_SECRET`, `OKTA_API_TOKEN`

**Email:**
- `SMTP_HOST`, `SMTP_PORT`, `SMTP_USER`, `SMTP_PASSWORD`

**Web Push (VAPID):**
- `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`

**Logging:**
- `LOKI_HOST`, `LOKI_USER`, `LOKI_PASSWORD`

### Loading Custom Secrets

To load additional secrets, modify the code:

```typescript
// In server.ts or app.ts
import { googleSecretManager } from './services/googleSecretManager.service';

// Load default secrets + custom ones
await googleSecretManager.loadSecrets([
  'DB_PASSWORD',
  'JWT_SECRET',
  'CUSTOM_API_KEY',  // Your custom secret
  'CUSTOM_SECRET_2'
]);
```

Or load a single secret on-demand:

```typescript
import { googleSecretManager } from './services/googleSecretManager.service';

const apiKey = await googleSecretManager.getSecretValue('CUSTOM_API_KEY', 'API_KEY');
```

## Security Best Practices

1. **Service Account Permissions:**
   - Grant only `roles/secretmanager.secretAccessor` role
   - Use separate service accounts for different environments
   - Never grant `roles/owner` or `roles/editor` to service accounts

2. **Secret Rotation:**
   - Rotate secrets regularly in Google Secret Manager
   - The app automatically uses the `latest` version of each secret
   - No code changes needed when secrets are rotated

3. **Environment Separation:**
   - Use different Google Cloud projects for dev/staging/prod
   - Use `GCP_SECRET_PREFIX` to namespace secrets by environment
   - Never commit `.env` files with production secrets to version control

4. **Access Control:**
   - Use IAM policies to control who can read secrets
   - Enable audit logging for secret access
   - Regularly review secret access logs

## Troubleshooting

### Secrets Not Loading

**Check logs for:**
```
[Secret Manager] Google Secret Manager is disabled (USE_GOOGLE_SECRET_MANAGER != true)
[Secret Manager] GCP_PROJECT_ID not set, skipping Google Secret Manager
[Secret Manager] Failed to load secrets: [error message]
```

**Common issues:**
1. `USE_GOOGLE_SECRET_MANAGER` not set to `true`
2. `GCP_PROJECT_ID` not configured
3. Service account lacks Secret Manager permissions
4. Secrets don't exist in Secret Manager
5. Incorrect secret names (check case sensitivity)

### Service Account Authentication

Ensure service account credentials are available:
- Set `GCP_KEY_FILE` to point to service account JSON file
- Or configure Application Default Credentials (ADC)
- Test with: `gcloud auth application-default login`

### Secret Not Found

If a secret doesn't exist in Secret Manager:
- The app logs a debug message and continues
- Falls back to `.env` file value
- This is expected behavior - not all secrets need to be in GCS

### Debugging

Enable debug logging by setting:
```env
LOG_LEVEL=debug
```

This will show detailed logs about which secrets are being loaded.

## Example Configuration

**Local Development (.env):**
```env
USE_GOOGLE_SECRET_MANAGER=false
DB_PASSWORD=local-dev-password
JWT_SECRET=local-jwt-secret
```

**Production (.env):**
```env
USE_GOOGLE_SECRET_MANAGER=true
GCP_PROJECT_ID=re-platform-workflow-dealer
GCP_SECRET_PREFIX=prod
GCP_KEY_FILE=./credentials/service-account.json
# DB_PASSWORD and other secrets loaded from GCS
```

## Migration Strategy

1. **Phase 1: Setup**
   - Create secrets in Google Secret Manager
   - Keep `.env` file with current values (as backup)

2. **Phase 2: Test**
   - Set `USE_GOOGLE_SECRET_MANAGER=true` in development
   - Verify secrets are loaded correctly
   - Test application functionality

3. **Phase 3: Production**
   - Deploy with `USE_GOOGLE_SECRET_MANAGER=true`
   - Monitor logs for secret loading success
   - Remove sensitive values from `.env` file (keep placeholders)

4. **Phase 4: Cleanup**
   - Remove production secrets from `.env` file
   - Ensure all secrets are in Secret Manager
   - Document secret names and mappings

## Additional Resources

- [Google Secret Manager Documentation](https://cloud.google.com/secret-manager/docs)
- [Secret Manager Client Library](https://cloud.google.com/nodejs/docs/reference/secret-manager/latest)
- [Service Account Best Practices](https://cloud.google.com/iam/docs/best-practices-service-accounts)

