# Secrets Installer Guide

This program uploads environment secret keys and config files to AWS Secrets Manager.

This replaces the `ServerEnvironmentBuilder` which would generate .env files and upload those to the jenkins build server.

## Overview

The Secrets Installer uploads specific configuration files to AWS Secrets Manager using command-line parameters. Each file is uploaded based on its parameter name, with two special cases that expand JSON entries into separate secrets.

## Installation

```bash
# Install dependencies
pnpm install
```

## Command-Line Parameters

All parameters are optional, but at least one config file must be specified:

| Parameter | Description | Upload Behavior |
|-----------|-------------|-----------------|
| `--NETWORK="dev\|test\|main"` | Network environment (default: `dev`) | Used in secret path |
| `--FIREBASE_JSON_FILE="path"` | Firebase configuration | Uploaded as string to `/cloud/{network}/FIREBASE_JSON` |
| `--FIREBASE_READONLY_JSON_FILE="path"` | Firebase readonly config | Uploaded as string to `/cloud/{network}/FIREBASE_READONLY_JSON` |
| `--FIREBASE_ANALYTICS_JSON_FILE="path"` | Firebase analytics config | Uploaded as string to `/cloud/{network}/FIREBASE_ANALYTICS_JSON` |
| `--BRIGHTCOVE_JWT_PRIVATE_KEY_FILE="path"` | Brightcove JWT private key | Uploaded as string to `/cloud/{network}/BRIGHTCOVE_JWT_PRIVATE_KEY` |
| `--JWT_PRIVATE_KEY_FILE="path"` | JWT private key | Uploaded as string to `/cloud/{network}/JWT_PRIVATE_KEY` |
| `--JWT_PUBLIC_KEY_FILE="path"` | JWT public key | Uploaded as string to `/cloud/{network}/JWT_PUBLIC_KEY` |
| `--NETWORK_CONFIG_FILE="path"` | Network configuration (JSON) | **Each JSON key/value becomes a separate secret** at `/cloud/{network}/{key}` |
| `--DEFAULT_CONFIG_FILE="path"` | Default configuration (JSON) | **Each JSON key/value becomes a separate secret** at `/cloud/{network}/{key}` |
| `--dry-run` | Preview without uploading | Shows what would be uploaded |

### Special Handling for Config Files

**Standard Files** (Firebase, JWT keys, etc.):
- File contents uploaded as-is (as a string)
- Secret path: `/cloud/{network}/{PARAM_NAME}`

**Expanded Files** (`--NETWORK_CONFIG_FILE` and `--DEFAULT_CONFIG_FILE`):
- JSON file is parsed
- Each top-level key becomes a separate secret
- Secret path: `/cloud/{network}/{key}`
- Values are stored as strings (or JSON if object/array)

## Usage Examples

### 1. Dry Run (Preview Only)

```bash
npx ts-node SecretsInstaller.ts --NETWORK="dev" \
  --FIREBASE_JSON_FILE="./firebase.json" \
  --JWT_PRIVATE_KEY_FILE="./jwt.key" \
  --dry-run
```

### 2. Upload Individual Config Files

```bash
# Set AWS credentials
export AWS_PROFILE=dev
# or
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...

# Upload to development
npx ts-node SecretsInstaller.ts --NETWORK="dev" \
  --FIREBASE_JSON_FILE="./configs/firebase.json" \
  --FIREBASE_READONLY_JSON_FILE="./configs/firebase-readonly.json" \
  --JWT_PRIVATE_KEY_FILE="./keys/jwt.key" \
  --JWT_PUBLIC_KEY_FILE="./keys/jwt.pub"
```

### 3. Upload Expanded Config Files

```bash
# Upload default and network configs
npx ts-node SecretsInstaller.ts --NETWORK="main" \
  --DEFAULT_CONFIG_FILE="./configs/default.json" \
  --NETWORK_CONFIG_FILE="./configs/network.json"
```

If `default.json` contains:
```json
{
  "database_url": "postgresql://...",
  "api_key": "secret-key",
  "log_level": "info"
}
```

This creates three separate secrets:
- `/cloud/main/database_url` → `"postgresql://..."`
- `/cloud/main/api_key` → `"secret-key"`
- `/cloud/main/log_level` → `"info"`

### 4. Upload All Config Types Together

```bash
npx ts-node SecretsInstaller.ts --NETWORK="test" \
  --FIREBASE_JSON_FILE="./firebase.json" \
  --BRIGHTCOVE_JWT_PRIVATE_KEY_FILE="./brightcove.pem" \
  --JWT_PRIVATE_KEY_FILE="./jwt.key" \
  --JWT_PUBLIC_KEY_FILE="./jwt.pub" \
  --DEFAULT_CONFIG_FILE="./config.json" \
  --NETWORK_CONFIG_FILE="./network.json"
```

## AWS Secrets Created

### Example 1: Individual Files

Command:
```bash
npx ts-node SecretsInstaller.ts --NETWORK="dev" \
  --FIREBASE_JSON_FILE="./firebase.json" \
  --JWT_PRIVATE_KEY_FILE="./jwt.key"
```

Creates:
- `/cloud/dev/FIREBASE_JSON` → entire contents of firebase.json
- `/cloud/dev/JWT_PRIVATE_KEY` → entire contents of jwt.key

### Example 2: Expanded Files

Command:
```bash
npx ts-node SecretsInstaller.ts --NETWORK="dev" \
  --DEFAULT_CONFIG_FILE="./config.json"
```

If `config.json` contains:
```json
{
  "db_host": "localhost",
  "db_port": "5432",
  "redis": {
    "host": "redis.local",
    "port": 6379
  }
}
```

Creates:
- `/cloud/dev/db_host` → `"localhost"`
- `/cloud/dev/db_port` → `"5432"`
- `/cloud/dev/redis` → `{"host": "redis.local", "port": 6379}` (as JSON string)

## Package.json Scripts

Add these to your `package.json`:

```json
{
  "scripts": {
    "secrets:dev": "ts-node SecretsInstaller.ts --NETWORK=\"dev\" --DEFAULT_CONFIG_FILE=\"./configs/dev.json\" --FIREBASE_JSON_FILE=\"./configs/firebase-dev.json\"",
    "secrets:test": "ts-node SecretsInstaller.ts --NETWORK=\"test\" --DEFAULT_CONFIG_FILE=\"./configs/test.json\" --FIREBASE_JSON_FILE=\"./configs/firebase-test.json\"",
    "secrets:main": "ts-node SecretsInstaller.ts --NETWORK=\"main\" --DEFAULT_CONFIG_FILE=\"./configs/main.json\" --FIREBASE_JSON_FILE=\"./configs/firebase-main.json\"",
    "secrets:dry-run": "ts-node SecretsInstaller.ts --NETWORK=\"dev\" --DEFAULT_CONFIG_FILE=\"./configs/dev.json\" --dry-run"
  }
}
```

Then run:
```bash
pnpm secrets:dry-run   # Preview
pnpm secrets:dev       # Apply to dev
pnpm secrets:main      # Apply to production
```

## IAM Permissions Required

Your AWS user/role needs these permissions:

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:CreateSecret",
        "secretsmanager:UpdateSecret",
        "secretsmanager:DescribeSecret",
        "secretsmanager:TagResource"
      ],
      "Resource": "arn:aws:secretsmanager:*:*:secret:/*"
    }
  ]
}
```

## Verification

After uploading, verify secrets in AWS Console:
1. Go to AWS Secrets Manager
2. Check for secrets like `/cloud/dev/FIREBASE_JSON`
3. View the secret value to confirm it's correct

Or use AWS CLI:

```bash
aws secretsmanager get-secret-value --secret-id /cloud/dev/FIREBASE_JSON
aws secretsmanager get-secret-value --secret-id /cloud/dev/database_url
```

## Rollback

If something goes wrong, you can delete secrets:

```bash
aws secretsmanager delete-secret --secret-id /cloud/dev/FIREBASE_JSON --force-delete-without-recovery
```

Or restore the previous version from AWS Secrets Manager version history.

## Migration Summary

After running, you'll see a summary like:

```
🚀 Starting migration to AWS Secrets Manager
   Network Name: dev
   Dry run: NO

   ✓ Processed ./firebase.json -> /cloud/dev/FIREBASE_JSON
   ✓ Processed ./jwt.key -> /cloud/dev/JWT_PRIVATE_KEY
   ✓ Processed database_url from ./config.json
   ✓ Processed api_key from ./config.json

📦 Found 4 secrets to upload

   ✓ Created: /cloud/dev/FIREBASE_JSON
   ✓ Created: /cloud/dev/JWT_PRIVATE_KEY
   ✓ Created: /cloud/dev/database_url
   ✓ Created: /cloud/dev/api_key

📊 Migration Summary
═══════════════════════════════════════
✓ Created:  4 secrets
↻ Updated:  0 secrets
✗ Failed:   0 secrets

✅ Migration complete!
```

## Troubleshooting

### Error: "No config files specified"
- Ensure at least one `--*_FILE` parameter is provided
- Check that file paths are correct and files exist

### Error: "Failed to process {file}"
- Verify the file exists at the specified path
- For JSON files, ensure they contain valid JSON
- Check file permissions

### Error: AWS authentication failed
- Ensure `AWS_PROFILE` or `AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY` are set
- Verify IAM permissions include the required Secrets Manager actions