chore(security): enhance environment configuration, CI workflows, and wallet daemon with security improvements
- Restructure .env.example with security-focused documentation, service-specific environment file references, and AWS Secrets Manager integration - Update CLI tests workflow to single Python 3.13 version, add pytest-mock dependency, and consolidate test execution with coverage - Add comprehensive security validation to package publishing workflow with manual approval gates, secret scanning, and release
This commit is contained in:
253
.github/workflows/dotenv-check.yml
vendored
Normal file
253
.github/workflows/dotenv-check.yml
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
name: Dotenv Configuration Check
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["**"]
|
||||
paths:
|
||||
- '.env.example'
|
||||
- 'scripts/focused_dotenv_linter.py'
|
||||
- '**/*.py'
|
||||
- '**/*.yml'
|
||||
- '**/*.yaml'
|
||||
- '**/*.toml'
|
||||
- '**/*.sh'
|
||||
- '**/*.bash'
|
||||
- '**/*.zsh'
|
||||
pull_request:
|
||||
branches: ["**"]
|
||||
paths:
|
||||
- '.env.example'
|
||||
- 'scripts/focused_dotenv_linter.py'
|
||||
- '**/*.py'
|
||||
- '**/*.yml'
|
||||
- '**/*.yaml'
|
||||
- '**/*.toml'
|
||||
- '**/*.sh'
|
||||
- '**/*.bash'
|
||||
- '**/*.zsh'
|
||||
|
||||
jobs:
|
||||
dotenv-check:
|
||||
runs-on: ubuntu-latest
|
||||
name: Check .env.example Configuration Drift
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.13'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
|
||||
- name: Check .env.example drift
|
||||
run: |
|
||||
python scripts/focused_dotenv_linter.py --check --verbose
|
||||
|
||||
- name: Generate configuration report
|
||||
run: |
|
||||
python scripts/focused_dotenv_linter.py > dotenv-report.txt
|
||||
|
||||
- name: Upload configuration report
|
||||
uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: dotenv-configuration-report
|
||||
path: dotenv-report.txt
|
||||
retention-days: 30
|
||||
|
||||
- name: Comment PR with configuration issues
|
||||
if: failure() && github.event_name == 'pull_request'
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const fs = require('fs');
|
||||
|
||||
try {
|
||||
const report = fs.readFileSync('dotenv-report.txt', 'utf8');
|
||||
|
||||
const comment = `## 🔍 Configuration Drift Detected
|
||||
|
||||
The focused dotenv linter found configuration drift between \`.env.example\` and actual environment variable usage in the codebase.
|
||||
|
||||
<details>
|
||||
<summary>Click to see full report</summary>
|
||||
|
||||
\`\`\`
|
||||
${report}
|
||||
\`\`\`
|
||||
|
||||
</details>
|
||||
|
||||
### 🔧 How to Fix
|
||||
|
||||
1. **Auto-fix missing variables:**
|
||||
\`\`\`bash
|
||||
python scripts/focused_dotenv_linter.py --fix
|
||||
\`\`\`
|
||||
|
||||
2. **Review unused variables:**
|
||||
- Remove variables from \`.env.example\` that are no longer used
|
||||
- Or add them to the linter's exclusion list if they're needed for external tools
|
||||
|
||||
3. **Run locally:**
|
||||
\`\`\`bash
|
||||
python scripts/focused_dotenv_linter.py --verbose
|
||||
\`\`\`
|
||||
|
||||
This prevents silent configuration drift and ensures all environment variables are properly documented.`;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment
|
||||
});
|
||||
} catch (error) {
|
||||
console.log('Could not read dotenv report:', error);
|
||||
}
|
||||
|
||||
dotenv-validation:
|
||||
runs-on: ubuntu-latest
|
||||
name: Validate .env.example Format
|
||||
needs: dotenv-check
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Validate .env.example format
|
||||
run: |
|
||||
# Check if .env.example exists and is readable
|
||||
if [ ! -f ".env.example" ]; then
|
||||
echo "❌ .env.example file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for common format issues
|
||||
echo "🔍 Validating .env.example format..."
|
||||
|
||||
# Check for lines without equals signs (excluding comments and empty lines)
|
||||
invalid_lines=$(grep -v '^#' .env.example | grep -v '^$' | grep -v '=' | wc -l)
|
||||
if [ "$invalid_lines" -gt 0 ]; then
|
||||
echo "❌ Found $invalid_lines lines without '=' in .env.example"
|
||||
grep -v '^#' .env.example | grep -v '^$' | grep -v '=' | head -5
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for variables with spaces (should be uppercase with underscores)
|
||||
invalid_vars=$(grep -v '^#' .env.example | grep -v '^$' | cut -d'=' -f1 | grep -E '[a-z]' | grep -v '^HTTP_PROXY$' | grep -v '^HTTPS_PROXY$' | grep -v '^NO_PROXY$' | wc -l)
|
||||
if [ "$invalid_vars" -gt 0 ]; then
|
||||
echo "⚠️ Found $invalid_vars variables with lowercase letters (should be uppercase):"
|
||||
grep -v '^#' .env.example | grep -v '^$' | cut -d'=' -f1 | grep -E '[a-z]' | grep -v '^HTTP_PROXY$' | grep -v '^HTTPS_PROXY$' | grep -v '^NO_PROXY$' | head -5
|
||||
echo "Consider using uppercase variable names for consistency."
|
||||
fi
|
||||
|
||||
# Check for duplicate variables
|
||||
duplicates=$(grep -v '^#' .env.example | grep -v '^$' | cut -d'=' -f1 | sort | uniq -d | wc -l)
|
||||
if [ "$duplicates" -gt 0 ]; then
|
||||
echo "❌ Found $duplicates duplicate variable names:"
|
||||
grep -v '^#' .env.example | grep -v '^$' | cut -d'=' -f1 | sort | uniq -d
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ .env.example format validation passed"
|
||||
|
||||
dotenv-security:
|
||||
runs-on: ubuntu-latest
|
||||
name: Security Check for .env.example
|
||||
needs: dotenv-check
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Security check for sensitive data
|
||||
run: |
|
||||
echo "🔒 Checking .env.example for sensitive data..."
|
||||
|
||||
# Check for potential secrets (should be placeholder values)
|
||||
sensitive_patterns=(
|
||||
"password="
|
||||
"secret="
|
||||
"key="
|
||||
"token="
|
||||
"private_key="
|
||||
"api_key="
|
||||
"dsn="
|
||||
)
|
||||
|
||||
found_issues=false
|
||||
|
||||
for pattern in "${sensitive_patterns[@]}"; do
|
||||
# Look for lines that might contain actual secrets (not placeholders)
|
||||
if grep -i "$pattern" .env.example | grep -v -E "(your-|placeholder|example|test|dummy|change-|xxx|yyy|zzz)" | grep -v -E "^#" | head -3; then
|
||||
echo "⚠️ Potential actual secrets found with pattern: $pattern"
|
||||
found_issues=true
|
||||
fi
|
||||
done
|
||||
|
||||
# Check for common placeholder patterns
|
||||
placeholder_count=$(grep -c -E "(your-|placeholder|example|test|dummy|change-|xxx|yyy|zzz)" .env.example || true)
|
||||
echo "📊 Found $placeholder_count placeholder values (good!)"
|
||||
|
||||
if [ "$found_issues" = true ]; then
|
||||
echo "❌ Please replace actual secrets with placeholder values in .env.example"
|
||||
echo " Use patterns like: your-secret-here, placeholder-value, change-me"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Security check passed"
|
||||
|
||||
dotenv-summary:
|
||||
runs-on: ubuntu-latest
|
||||
name: Configuration Summary
|
||||
needs: [dotenv-check, dotenv-validation, dotenv-security]
|
||||
if: always()
|
||||
|
||||
steps:
|
||||
- name: Generate summary
|
||||
run: |
|
||||
echo "# 📋 .env.example Configuration Summary" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Check results from previous jobs
|
||||
if [ "${{ needs.dotenv-check.result }}" == "success" ]; then
|
||||
echo "✅ **Configuration Drift Check**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Configuration Drift Check**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [ "${{ needs.dotenv-validation.result }}" == "success" ]; then
|
||||
echo "✅ **Format Validation**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Format Validation**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
if [ "${{ needs.dotenv-security.result }}" == "success" ]; then
|
||||
echo "✅ **Security Check**: Passed" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "❌ **Security Check**: Failed" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 📊 Configuration Statistics" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Count variables in .env.example
|
||||
var_count=$(grep -v '^#' .env.example | grep -v '^$' | wc -l)
|
||||
echo "- **Variables in .env.example**: $var_count" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Count sections (based on comment headers)
|
||||
sections=$(grep '^# ====' .env.example | wc -l)
|
||||
echo "- **Configuration Sections**: $sections" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🔧 Maintenance" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Linter**: \`python scripts/focused_dotenv_linter.py\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Auto-fix**: \`python scripts/focused_dotenv_linter.py --fix\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Verbose**: \`python scripts/focused_dotenv_linter.py --verbose\`" >> $GITHUB_STEP_SUMMARY
|
||||
Reference in New Issue
Block a user