Migrated from design-system-swarm with fresh git history.
Old project history preserved in /home/overbits/apps/design-system-swarm
Core components:
- MCP Server (Python FastAPI with mcp 1.23.1)
- Claude Plugin (agents, commands, skills, strategies, hooks, core)
- DSS Backend (dss-mvp1 - token translation, Figma sync)
- Admin UI (Node.js/React)
- Server (Node.js/Express)
- Storybook integration (dss-mvp1/.storybook)
Self-contained configuration:
- All paths relative or use DSS_BASE_PATH=/home/overbits/dss
- PYTHONPATH configured for dss-mvp1 and dss-claude-plugin
- .env file with all configuration
- Claude plugin uses ${CLAUDE_PLUGIN_ROOT} for portability
Migration completed: $(date)
🤖 Clean migration with full functionality preserved
118 lines
3.1 KiB
Bash
Executable File
118 lines
3.1 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# DSS - Secret Scanner
|
|
# Non-destructive scan for potential exposed secrets
|
|
# Outputs JSON with risk report (no actual secret values)
|
|
#
|
|
|
|
set -e
|
|
|
|
PROJECT_PATH="${1:-.}"
|
|
|
|
# Patterns to detect (regex)
|
|
SECRET_PATTERNS=(
|
|
"password\s*[:=]\s*['\"][^'\"]+['\"]"
|
|
"api[_-]?key\s*[:=]\s*['\"][^'\"]+['\"]"
|
|
"secret[_-]?key\s*[:=]\s*['\"][^'\"]+['\"]"
|
|
"access[_-]?token\s*[:=]\s*['\"][^'\"]+['\"]"
|
|
"private[_-]?key\s*[:=]\s*['\"][^'\"]+['\"]"
|
|
"aws[_-]?access"
|
|
"AKIA[0-9A-Z]{16}"
|
|
"ghp_[a-zA-Z0-9]{36}"
|
|
"sk-[a-zA-Z0-9]{48}"
|
|
)
|
|
|
|
# Files to ignore
|
|
IGNORE_DIRS="node_modules|\.git|dist|build|__pycache__|\.next|venv"
|
|
|
|
# Initialize results
|
|
declare -a findings
|
|
|
|
scan_for_secrets() {
|
|
local pattern="$1"
|
|
local results
|
|
|
|
results=$(grep -rEil "$pattern" "$PROJECT_PATH" \
|
|
--include="*.js" --include="*.ts" --include="*.py" \
|
|
--include="*.json" --include="*.yaml" --include="*.yml" \
|
|
--include="*.env*" --include="*.config.*" \
|
|
2>/dev/null | grep -vE "$IGNORE_DIRS" | head -20 || true)
|
|
|
|
if [[ -n "$results" ]]; then
|
|
while IFS= read -r file; do
|
|
if [[ -n "$file" ]]; then
|
|
# Get line count without revealing content
|
|
local count=$(grep -cEi "$pattern" "$file" 2>/dev/null || echo 0)
|
|
findings+=("{\"file\":\"${file#$PROJECT_PATH/}\",\"pattern\":\"${pattern:0:30}...\",\"matches\":$count}")
|
|
fi
|
|
done <<< "$results"
|
|
fi
|
|
}
|
|
|
|
# Check for common secret files
|
|
check_secret_files() {
|
|
local risky_files=(
|
|
".env"
|
|
".env.local"
|
|
".env.production"
|
|
"credentials.json"
|
|
"secrets.json"
|
|
"config/secrets.yml"
|
|
".aws/credentials"
|
|
"id_rsa"
|
|
"id_ed25519"
|
|
"*.pem"
|
|
"*.key"
|
|
)
|
|
|
|
for pattern in "${risky_files[@]}"; do
|
|
local found=$(find "$PROJECT_PATH" -name "$pattern" -type f ! -path "*/$IGNORE_DIRS/*" 2>/dev/null | head -5)
|
|
if [[ -n "$found" ]]; then
|
|
while IFS= read -r file; do
|
|
if [[ -n "$file" ]]; then
|
|
# Check if file is in .gitignore
|
|
local in_gitignore="false"
|
|
if [[ -f "$PROJECT_PATH/.gitignore" ]]; then
|
|
grep -q "$(basename "$file")" "$PROJECT_PATH/.gitignore" 2>/dev/null && in_gitignore="true"
|
|
fi
|
|
findings+=("{\"file\":\"${file#$PROJECT_PATH/}\",\"type\":\"risky_file\",\"in_gitignore\":$in_gitignore}")
|
|
fi
|
|
done <<< "$found"
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Run scans
|
|
for pattern in "${SECRET_PATTERNS[@]}"; do
|
|
scan_for_secrets "$pattern"
|
|
done
|
|
|
|
check_secret_files
|
|
|
|
# Calculate risk score
|
|
total_findings=${#findings[@]}
|
|
risk_score="low"
|
|
[[ $total_findings -gt 5 ]] && risk_score="medium"
|
|
[[ $total_findings -gt 15 ]] && risk_score="high"
|
|
[[ $total_findings -gt 30 ]] && risk_score="critical"
|
|
|
|
# Output JSON
|
|
joined=$(IFS=,; echo "${findings[*]}")
|
|
|
|
cat <<EOF
|
|
{
|
|
"scan_type": "secrets",
|
|
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
"project_path": "$PROJECT_PATH",
|
|
"risk_level": "$risk_score",
|
|
"total_findings": $total_findings,
|
|
"findings": [${joined:-}],
|
|
"recommendations": [
|
|
"Review all findings and remove hardcoded secrets",
|
|
"Use environment variables for sensitive data",
|
|
"Add secret files to .gitignore",
|
|
"Consider using a secrets manager"
|
|
]
|
|
}
|
|
EOF
|