name: Security
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# Run security checks daily at 2 AM UTC
- cron: "0 2 * * *"
jobs:
security-audit:
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.x"
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Run npm audit
run: npm audit --audit-level=moderate
- name: Check for known vulnerabilities
run: |
# Check if any high or critical vulnerabilities exist
AUDIT_RESULT=$(npm audit --audit-level=high --json 2>/dev/null || echo '{"vulnerabilities":{}}')
HIGH_VULNS=$(echo $AUDIT_RESULT | node -e "
const data = JSON.parse(require('fs').readFileSync(0, 'utf8'));
const vulns = data.vulnerabilities || {};
const highCritical = Object.values(vulns).filter(v =>
v.severity === 'high' || v.severity === 'critical'
).length;
console.log(highCritical);
")
if [ "$HIGH_VULNS" -gt 0 ]; then
echo "⚠️ Found $HIGH_VULNS high/critical vulnerabilities"
npm audit --audit-level=high
exit 1
else
echo "✅ No high/critical vulnerabilities found"
fi
- name: Scan for secrets
run: |
echo "🔍 Scanning for potential secrets (excluding test files)..."
# Only scan production source files, exclude all test-related files
FOUND_SECRETS=false
# Look for actual secrets in non-test TypeScript files
find src -name "*.ts" -not -path "*/node_modules/*" -not -path "*/__tests__/*" -not -name "*.test.ts" -not -name "*.spec.ts" | while read -r file; do
# Check for real API keys and tokens (20+ chars)
if grep -E "(api[_-]?key|secret[_-]?key|auth[_-]?token|access[_-]?token)['\"]?\s*[:=]\s*['\"][a-zA-Z0-9]{20,}['\"]" "$file" 2>/dev/null; then
echo "⚠️ Potential API key/token in: $file"
FOUND_SECRETS=true
fi
# Check for private keys
if grep -E "-----BEGIN [A-Z ]+PRIVATE KEY-----" "$file" 2>/dev/null; then
echo "⚠️ Private key detected in: $file"
FOUND_SECRETS=true
fi
# Check for database connection strings
if grep -E "(mongodb://|mysql://|postgres://|redis://)[^'\"\s]+" "$file" 2>/dev/null; then
echo "⚠️ Database connection string in: $file"
FOUND_SECRETS=true
fi
done
# Exit with error if secrets found
if [ "$FOUND_SECRETS" = "true" ]; then
echo ""
echo "⚠️ Potential secrets detected in production code"
echo "Please review and remove any sensitive data"
exit 1
else
echo "✅ No secrets detected in production code"
fi