homelab/.github/workflows/security-checks.yml
Claude 1c3b7e53a1
feat: Add comprehensive GitHub Actions CI/CD pipeline
GitHub Actions Workflows:
- docker-compose-validation.yml: Validates all compose files
  - Syntax validation
  - Network configuration checks
  - Traefik label validation
  - Port exposure warnings
  - Domain consistency checks
  - File naming convention enforcement

- security-checks.yml: Security scanning and validation
  - Gitleaks secret detection
  - Environment file validation
  - Placeholder password checks
  - Container image vulnerability scanning with Trivy
  - Dependency review for pull requests
  - Security report generation

- yaml-lint.yml: YAML formatting and validation
  - yamllint with custom configuration
  - File extension consistency checks
  - YAML structure validation
  - Service naming convention checks
  - Docker Compose version validation

- documentation.yml: Documentation quality checks
  - Markdown linting
  - Link validation
  - README completeness verification
  - Service documentation checks
  - Domain URL validation

- auto-label.yml: Automated PR labeling
  - Category-based labeling (core/media/services)
  - File type detection
  - Size-based labeling
  - Security-related changes detection

Configuration Files:
- .yamllint.yml: YAML linting rules for Docker Compose
- .markdownlint.json: Markdown formatting rules
- .markdown-link-check.json: Link checking configuration
- .pre-commit-config.yaml: Pre-commit hooks setup
- .github/labeler.yml: Auto-labeler configuration
- .github/CODEOWNERS: Code ownership definitions

Templates:
- pull_request_template.md: Comprehensive PR checklist
- ISSUE_TEMPLATE/bug-report.md: Bug report template
- ISSUE_TEMPLATE/service-request.md: New service request template

Documentation:
- SECURITY.md: Security policy and best practices
- CONTRIBUTING.md: Contribution guidelines

Benefits:
- Automated validation of all compose files
- Security scanning on every PR
- Consistent code formatting
- Documentation quality assurance
- Automated issue/PR management
- Pre-commit hooks for local validation
- Comprehensive security policy
- Clear contribution guidelines
2025-11-05 20:09:33 +00:00

193 lines
6 KiB
YAML

name: Security Checks
on:
pull_request:
push:
branches:
- main
jobs:
secret-scanning:
name: Secret Detection
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_ENABLE_COMMENTS: false
env-file-validation:
name: Environment File Validation
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Check for placeholder passwords
run: |
echo "Checking for placeholder passwords in .env files..."
exit_code=0
# Find all .env files
env_files=$(find compose -name ".env" -type f)
for env_file in $env_files; do
echo "Checking: $env_file"
# Check for common placeholder passwords
if grep -E "(changeme|password123|admin123|test123|example)" "$env_file" > /dev/null 2>&1; then
echo "⚠️ WARNING: $env_file contains placeholder passwords"
echo " This is expected in the repository template."
echo " Users should change these before deployment."
fi
# Check for actual leaked passwords (common patterns)
if grep -E "PASSWORD=.{20,}" "$env_file" | grep -v "changeme" > /dev/null 2>&1; then
echo "❌ ERROR: $env_file may contain a real password!"
exit_code=1
fi
done
exit $exit_code
- name: Validate environment file format
run: |
echo "Validating .env file format..."
exit_code=0
env_files=$(find compose -name ".env" -type f)
for env_file in $env_files; do
# Check for common .env issues
if grep -E "^\s+[A-Z_]+=.*" "$env_file" > /dev/null 2>&1; then
echo "❌ $env_file: Contains indented variables (should not be indented)"
exit_code=1
fi
if grep -E "^[A-Z_]+=\s+.*" "$env_file" > /dev/null 2>&1; then
echo "⚠️ $env_file: Contains space after = (may cause issues)"
fi
# Check for commented-out critical variables
if grep -E "^#\s*(DATABASE_URL|POSTGRES_PASSWORD|JWT_SECRET|SESSION_SECRET)=" "$env_file" > /dev/null 2>&1; then
echo "⚠️ $env_file: Critical variables are commented out"
fi
done
if [ $exit_code -eq 0 ]; then
echo "✅ All .env files are properly formatted"
fi
exit $exit_code
dockerfile-security:
name: Dockerfile Security Scan
runs-on: ubuntu-latest
if: false # Disabled since we use pre-built images, enable if you add custom Dockerfiles
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Hadolint
uses: hadolint/hadolint-action@v3.1.0
with:
dockerfile: "**/Dockerfile"
failure-threshold: warning
container-image-scan:
name: Container Image Vulnerability Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract images from compose files
id: extract-images
run: |
echo "Extracting container images..."
# Extract unique images from all compose files
images=$(grep -h "^\s*image:" compose/**/compose.yaml | \
awk '{print $2}' | \
grep -v "^$" | \
sort -u)
echo "Found images:"
echo "$images"
# Save to file for next step
echo "$images" > images.txt
# Count images
image_count=$(echo "$images" | wc -l)
echo "total_images=$image_count" >> $GITHUB_OUTPUT
- name: Scan critical images with Trivy
run: |
# Install Trivy
sudo apt-get install wget apt-transport-https gnupg lsb-release
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo gpg --dearmor -o /usr/share/keyrings/trivy.gpg
echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/trivy.list
sudo apt-get update
sudo apt-get install trivy
# Scan a sample of critical images (to avoid long CI times)
critical_images=(
"traefik:v3.3"
"lldap/lldap:stable"
"ghcr.io/steveiliop56/tinyauth:latest"
"postgres:16-alpine"
"postgres:18"
"redis:alpine"
)
echo "Scanning critical images for HIGH and CRITICAL vulnerabilities..."
for image in "${critical_images[@]}"; do
# Check if image is used in our compose files
if grep -q "$image" images.txt 2>/dev/null; then
echo "Scanning: $image"
trivy image --severity HIGH,CRITICAL --exit-code 0 "$image" || true
fi
done
- name: Generate security report
if: always()
run: |
echo "# Security Scan Summary" > security-report.md
echo "" >> security-report.md
echo "## Images Scanned" >> security-report.md
echo "Total unique images: $(cat images.txt | wc -l)" >> security-report.md
echo "" >> security-report.md
echo "See job logs for detailed vulnerability information." >> security-report.md
- name: Upload security report
if: always()
uses: actions/upload-artifact@v4
with:
name: security-report
path: security-report.md
dependency-review:
name: Dependency Review
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Dependency Review
uses: actions/dependency-review-action@v4
with:
fail-on-severity: moderate