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
193 lines
6 KiB
YAML
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
|