Skip to content

Security Checks

Security Checks #114

Workflow file for this run

name: Security Checks
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
schedule:
# Run security checks weekly on Monday at 00:00 UTC
- cron: '0 0 * * 1'
permissions:
contents: read
security-events: write
jobs:
secret-scanning:
name: Secret Scanning
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Check for initial commit (Push)
if: github.event_name == 'push'
id: check_initial
run: |
if [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then
echo "is_initial=true" >> $GITHUB_OUTPUT
FIRST_COMMIT=$(git rev-list --max-parents=0 HEAD)
echo "first_commit=$FIRST_COMMIT" >> $GITHUB_OUTPUT
else
echo "is_initial=false" >> $GITHUB_OUTPUT
fi
- name: TruffleHog OSS (Push - Initial Commit)
if: github.event_name == 'push' && steps.check_initial.outputs.is_initial == 'true'
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ steps.check_initial.outputs.first_commit }}
head: ${{ github.sha }}
extra_args: --only-verified
- name: TruffleHog OSS (Push - Regular)
if: github.event_name == 'push' && steps.check_initial.outputs.is_initial == 'false'
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.before }}
head: ${{ github.sha }}
extra_args: --only-verified
- name: TruffleHog OSS (Pull Request)
if: github.event_name == 'pull_request'
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.event.pull_request.head.sha }}
extra_args: --only-verified
- name: TruffleHog OSS (Scheduled)
if: github.event_name == 'schedule'
uses: trufflesecurity/trufflehog@main
with:
path: ./
extra_args: --only-verified
license-check:
name: License Compliance
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up JDK 21
uses: actions/setup-java@v5
with:
java-version: '21'
distribution: 'temurin'
cache: gradle
- name: Validate Gradle wrapper
uses: gradle/actions/wrapper-validation@v5
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
with:
gradle-home-cache-cleanup: true
- name: Check license headers with Spotless
run: |
echo "Checking for Apache License headers using Spotless..."
./gradlew spotlessCheck --no-daemon
if [ $? -eq 0 ]; then
echo "✅ All Java files have proper license headers and formatting"
else
echo "❌ Spotless check failed!"
echo ""
echo "Some files are missing license headers or need formatting."
echo "To fix, run locally:"
echo " ./gradlew spotlessApply"
echo "Then commit and push the changes."
exit 1
fi
- name: Verify required files exist
run: |
echo "Checking for required legal files..."
required_files=(
"LICENSE"
"NOTICE"
"SECURITY.md"
"CODE_OF_CONDUCT.md"
"CONTRIBUTING.md"
)
missing=0
for file in "${required_files[@]}"; do
if [ ! -f "$file" ]; then
echo "❌ Missing required file: $file"
missing=$((missing + 1))
else
echo "✅ Found: $file"
fi
done
if [ $missing -gt 0 ]; then
echo "⚠️ Missing $missing required file(s)"
exit 1
fi
sensitive-data-check:
name: Sensitive Data Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Check for accidentally committed secrets
run: |
echo "Checking for sensitive files that should not be committed..."
sensitive_patterns=(
"config.json"
"service-account.json"
"*.key"
"*.pem"
"*.p12"
".env"
"id_rsa"
"id_dsa"
"*.ppk"
"database.properties"
"oauth-secrets.json"
"client_secret*.json"
)
found_sensitive=0
for pattern in "${sensitive_patterns[@]}"; do
files=$(find . -name "$pattern" -not -path "*/build/*" -not -path "*/.gradle/*" 2>/dev/null || true)
if [ -n "$files" ]; then
echo "⚠️ Found potentially sensitive file(s) matching pattern: $pattern"
echo "$files"
found_sensitive=1
fi
done
if [ $found_sensitive -eq 1 ]; then
echo ""
echo "❌ Sensitive files detected in repository!"
echo "These files should be in .gitignore and removed from git history"
echo "If these files were committed, they should be removed and credentials rotated"
exit 1
else
echo "✅ No sensitive files detected in repository"
fi
- name: Check for hardcoded secrets in code
run: |
echo "Checking for potential hardcoded secrets..."
# Search for common secret patterns
secrets_found=0
# Discord bot tokens
if grep -r "discord.*token.*=.*[\"'][A-Za-z0-9._-]\{50,\}[\"']" --include="*.java" --exclude-dir="build" . ; then
echo "⚠️ Possible Discord token found in code"
secrets_found=1
fi
# Database passwords
if grep -r "password.*=.*[\"'][^\"']\{8,\}[\"']" --include="*.java" --include="*.properties" --exclude-dir="build" . | grep -v "example" | grep -v "your_password"; then
echo "⚠️ Possible hardcoded password found"
secrets_found=1
fi
# API keys
if grep -r "api[_-]key.*=.*[\"'][A-Za-z0-9]\{20,\}[\"']" --include="*.java" --exclude-dir="build" . ; then
echo "⚠️ Possible API key found in code"
secrets_found=1
fi
if [ $secrets_found -eq 1 ]; then
echo ""
echo "❌ Potential secrets detected in code!"
echo "Please use environment variables or config files (that are gitignored)"
exit 1
else
echo "✅ No obvious hardcoded secrets detected"
fi
security-summary:
name: Security Summary
runs-on: ubuntu-latest
needs: [secret-scanning, license-check, sensitive-data-check]
if: always()
steps:
- name: Check results
run: |
echo "🔒 Security scan completed"
echo ""
echo "Results:"
echo "- Secret Scanning: ${{ needs.secret-scanning.result }}"
echo "- License Compliance: ${{ needs.license-check.result }}"
echo "- Sensitive Data Check: ${{ needs.sensitive-data-check.result }}"
echo ""
if [ "${{ needs.secret-scanning.result }}" == "failure" ] || \
[ "${{ needs.license-check.result }}" == "failure" ] || \
[ "${{ needs.sensitive-data-check.result }}" == "failure" ]; then
echo "❌ Security checks failed! Please review and fix issues."
exit 1
else
echo "✅ All critical security checks passed!"
fi
echo ""
echo "ℹ️ Note: Dependency security is handled by GitHub's Dependabot and Dependency Review Action"