> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://help-legacy.galaxycloud.app/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Secrets Management: How to Secure Your settings.json and Deploy Meteor Safely

Storing secrets in your repository is a security risk. If your repository is accidentally made public, forked, or your Docker image is pushed to a public registry, your credentials will be exposed.

This guide covers best practices for managing secrets when deploying Meteor applications to Galaxy.

|| Coming soon: Galaxy will support METEOR_SETTINGS as an environment variable in the dashboard. This will simplify secrets management for Push to Deploy users.

## The Problem with settings.json

The typical Meteor workflow involves storing credentials in a `settings.json` file:
```
{
  "galaxy.meteor.com": {
    "env": {
      "MONGO_URL": "mongodb://user:password@host/db",
      "MAIL_URL": "smtp://user:password@smtp.example.com:587"
    }
  },
  "private": {
    "stripeKey": "sk_live_xxx"
  },
  "public": {
    "appName": "My App"
  }
}
```
If this file is committed to your repository, it creates several risks:
* **Repository made public by mistake**: A misconfiguration can expose your secrets
* **Public forks**: Forking to a public repository exposes the entire commit history
* **Git history**: Deleted files remain in Git history and can be recovered
* **Docker images**: Files copied during build are baked into image layers

## Recommended Setup
### 1. Update .gitignore
Add these entries to ensure secrets files are never committed:
```
# Secret files
settings.json
settings-*.json
.settings-*.json

# Environment directories with secrets
env/
```

### 2. Create a settings template
Keep a `settings.example.json` in your repository as documentation:
```
{
  "galaxy.meteor.com": {
    "env": {
      "MONGO_URL": "YOUR_MONGO_URL",
      "MAIL_URL": "YOUR_MAIL_URL"
    }
  },
  "private": {
    "stripeKey": "YOUR_STRIPE_KEY"
  },
  "public": {
    "appName": "My App"
  }
}
```
This file is safe to commit since it contains no real secrets.

### 3. Remove secrets from Git history
||| If you have previously committed secrets, removing them from current files is not enough. Use tools like [BFG Repo-Cleaner](https://rtyley.github.io/bfg-repo-cleaner/) to scrub them from history. Rotate any credentials that were ever committed.

## Using a Secrets Manager
A secrets manager stores your credentials securely and allows you to inject them at deploy time. Popular options include:
* [Infisical](https://infisical.com/) (open source)
* [Doppler](https://doppler.com/)
* [HashiCorp Vault](https://vaultproject.io/)
* [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/)

### Infisical Setup
1. Create an account at [app.infisical.com](https://app.infisical.com/)
2. Create a new project for your app
3. Install the CLI (see [installation docs](https://infisical.com/docs/cli/overview))
4. Authenticate and initialize your project:
```
infisical login
cd ~/projects/my-meteor-app
infisical init
```
5. Add your secrets in the Infisical dashboard. Store the entire settings object as a single `SETTINGS_JSON` variable.

## Deploy Script
Create a `deploy.sh` script that fetches secrets and deploys to Galaxy:
```
#!/bin/bash

# Exit immediately if any command fails
set -e

# ===========================================
# CONFIGURATION
# ===========================================
# Change these values for your app
APP_NAME="my-app.meteorapp.com"
ENVIRONMENT="prod"

echo "Deploying $APP_NAME ($ENVIRONMENT)"

# ===========================================
# STEP 1: Verify Infisical authentication
# ===========================================
# Tries to fetch secrets from Infisical
# If it fails, the user is not logged in or the project is not initialized
if ! infisical secrets --env=$ENVIRONMENT &> /dev/null; then
    echo "Not authenticated. Run: infisical login"
    exit 1
fi

# ===========================================
# STEP 2: Export secrets to temporary file
# ===========================================
# Creates a unique temporary filename using the process ID ($$)
# This avoids conflicts if multiple deploys run at the same time
TEMP_SETTINGS=".settings-deploy-$$.json"

# Fetches the SETTINGS_JSON secret from Infisical and saves to the temp file
infisical secrets get SETTINGS_JSON --env=$ENVIRONMENT --plain > $TEMP_SETTINGS

# ===========================================
# STEP 3: Validate JSON
# ===========================================
# Uses Python to check if the file contains valid JSON
if ! python3 -c "import json; json.load(open('$TEMP_SETTINGS'))" 2>/dev/null; then
    echo "Invalid JSON in SETTINGS_JSON"
    rm -f $TEMP_SETTINGS
    exit 1
fi

# ===========================================
# STEP 4: Deploy to Galaxy
# ===========================================
meteor deploy $APP_NAME --settings $TEMP_SETTINGS

# ===========================================
# STEP 5: Clean up
# ===========================================
# Removes the temporary file so secrets don't stay on disk
rm -f $TEMP_SETTINGS

echo "Done!"
```
Make it executable and deploy:
```
chmod +x deploy.sh
./deploy.sh
```

## Multiple Environments
Configure different secrets in Infisical for each environment (dev, staging, prod). Deploy to different environments by changing the parameters:
```
# Deploy to staging
ENVIRONMENT=staging APP_NAME=staging.myapp.com ./deploy.sh

# Deploy to production
ENVIRONMENT=prod APP_NAME=myapp.com ./deploy.sh
```

## CI/CD with GitHub Actions
For automated deployments, create `.github/workflows/deploy.yml`:
```
name: Deploy to Galaxy

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  APP_NAME: my-app.meteorapp.com
  INFISICAL_ENV: prod

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Meteor
        run: curl https://install.meteor.com/ | sh

      - name: Install Infisical CLI
        run: |
          curl -1sLf 'https://dl.cloudsmith.io/public/infisical/infisical-cli/setup.deb.sh' | sudo -E bash
          sudo apt-get update && sudo apt-get install -y infisical

      - name: Login to Infisical
        run: |
          infisical login --method=universal-auth \
            --client-id=${{ secrets.INFISICAL_CLIENT_ID }} \
            --client-secret=${{ secrets.INFISICAL_CLIENT_SECRET }}

      - name: Fetch secrets from Infisical
        run: |
          infisical secrets get SETTINGS_JSON \
            --env=${{ env.INFISICAL_ENV }} \
            --projectId=${{ secrets.INFISICAL_PROJECT_ID }} \
            --plain > settings.json

      - name: Validate settings.json
        run: python3 -c "import json; json.load(open('settings.json'))"

      - name: Setup Meteor credentials
        run: |
          mkdir -p ~/.meteor
          echo '${{ secrets.METEOR_TOKEN }}' > ~/.meteor/meteor_token.json

      - name: Deploy to Galaxy
        run: meteor deploy ${{ env.APP_NAME }} --settings settings.json

      - name: Clean up
        if: always()
        run: rm -f settings.json
```

### Required GitHub Secrets
Add these secrets in your repository settings (Settings > Secrets and variables > Actions):
| Secret | Description |
| ---- |
| INFISICAL_CLIENT_ID | Machine Identity client ID from Infisical |
| INFISICAL_CLIENT_SECRET | Machine Identity client secret from Infisical |
| INFISICAL_PROJECT_ID | Your Infisical project ID |
| METEOR_TOKEN | Contents of ~/.meteor/meteor_token.json after running meteor login |

### Creating a Machine Identity in Infisical
1. In the Infisical dashboard, go to **Project Settings > Machine Identities**
2. Create a new identity
3. Add it to your project with access to the appropriate environment
4. Copy the **Client ID** and **Client Secret**

## Local Development
For local development, create a `dev.sh` script:
```
#!/bin/bash
set -e

# Fetch development secrets
infisical secrets get SETTINGS_JSON --env=dev --plain > .settings-local.json

# Run Meteor
meteor run --settings .settings-local.json

# Clean up when Meteor exits
rm -f .settings-local.json
```
| Don't forget to add `.settings-local.json` to your `.gitignore`.

## Security Best Practices
* **Rotate secrets regularly**: Set a reminder to rotate credentials every 90-180 days
* **Use least privilege access**: Not everyone needs access to production secrets
* **Audit access logs**: Periodically check who is accessing your secrets
* **Don't trust private repositories completely**: They can become public by accident
