Add comprehensive security enhancements to build pipeline
Security Improvements: - Fork PR Protection: Builds from forks require manual 'safe-to-build' label approval - Trivy Vulnerability Scanning: Scan all images for CRITICAL/HIGH vulnerabilities - SHA-Pinned Actions: All GitHub Actions pinned to specific commits for supply chain security - SBOM Generation: Generate Software Bill of Materials for all builds - Provenance Attestation: Record build provenance for supply chain verification - Security Events Upload: Upload scan results to GitHub Security tab - Platform Optimization: Single-platform builds for PRs for faster feedback Additional Security: - Created SECURITY.md with vulnerability reporting process and security practices - Added Dependabot configuration for automated dependency updates - Limited permissions model (contents:read, packages:write, security-events:write) - No registry push from PR builds (load-only for security scanning) This addresses concerns about malicious PR builds by: 1. Requiring manual approval for fork PRs 2. Scanning all images before they could be pushed 3. Preventing PR builds from pushing to registry 4. Using verified, SHA-pinned actions
This commit is contained in:
79
.github/dependabot.yml
vendored
Normal file
79
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
version: 2
|
||||
updates:
|
||||
# GitHub Actions updates
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- "fuomag9"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "github-actions"
|
||||
- "security"
|
||||
commit-message:
|
||||
prefix: "ci"
|
||||
include: "scope"
|
||||
|
||||
# NPM dependencies updates
|
||||
- package-ecosystem: "npm"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- "fuomag9"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "npm"
|
||||
commit-message:
|
||||
prefix: "deps"
|
||||
include: "scope"
|
||||
# Group non-security updates
|
||||
groups:
|
||||
development-dependencies:
|
||||
dependency-type: "development"
|
||||
update-types:
|
||||
- "minor"
|
||||
- "patch"
|
||||
production-dependencies:
|
||||
dependency-type: "production"
|
||||
update-types:
|
||||
- "minor"
|
||||
- "patch"
|
||||
# Security updates always get their own PR
|
||||
versioning-strategy: increase
|
||||
|
||||
# Docker base images updates
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/docker/web"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
open-pull-requests-limit: 5
|
||||
reviewers:
|
||||
- "fuomag9"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "docker"
|
||||
- "security"
|
||||
commit-message:
|
||||
prefix: "docker"
|
||||
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/docker/caddy"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
open-pull-requests-limit: 5
|
||||
reviewers:
|
||||
- "fuomag9"
|
||||
labels:
|
||||
- "dependencies"
|
||||
- "docker"
|
||||
- "security"
|
||||
commit-message:
|
||||
prefix: "docker"
|
||||
75
.github/workflows/docker-build.yml
vendored
75
.github/workflows/docker-build.yml
vendored
@@ -11,6 +11,8 @@ on:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
pull_request_target:
|
||||
types: [labeled]
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
@@ -18,11 +20,37 @@ env:
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
# Security check for fork PRs
|
||||
security-check:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request'
|
||||
permissions:
|
||||
pull-requests: read
|
||||
outputs:
|
||||
is_fork: ${{ steps.check.outputs.is_fork }}
|
||||
steps:
|
||||
- name: Check if PR is from fork
|
||||
id: check
|
||||
run: |
|
||||
if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then
|
||||
echo "is_fork=true" >> $GITHUB_OUTPUT
|
||||
echo "::warning::This PR is from a fork. Builds from forks require manual approval for security."
|
||||
else
|
||||
echo "is_fork=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
build-and-push:
|
||||
needs: [security-check]
|
||||
# Only run on non-fork PRs, or if manually approved (has 'safe-to-build' label)
|
||||
if: |
|
||||
github.event_name != 'pull_request' ||
|
||||
needs.security-check.outputs.is_fork == 'false' ||
|
||||
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.labels.*.name, 'safe-to-build'))
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
security-events: write # For Trivy to upload SARIF results
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -36,14 +64,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
# For pull_request_target, checkout the PR head
|
||||
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || '' }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: docker/login-action@v3
|
||||
if: github.event_name != 'pull_request' && github.event_name != 'pull_request_target'
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
@@ -51,7 +82,7 @@ jobs:
|
||||
|
||||
- name: Extract metadata (tags, labels)
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}-${{ matrix.service }}
|
||||
tags: |
|
||||
@@ -64,13 +95,41 @@ jobs:
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
id: build
|
||||
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
|
||||
with:
|
||||
context: ${{ matrix.context }}
|
||||
file: ${{ matrix.dockerfile }}
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
push: ${{ github.event_name != 'pull_request' && github.event_name != 'pull_request_target' }}
|
||||
load: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
platforms: linux/amd64,linux/arm64
|
||||
platforms: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' && 'linux/amd64' || 'linux/amd64,linux/arm64' }}
|
||||
sbom: true
|
||||
provenance: true
|
||||
|
||||
- name: Run Trivy vulnerability scanner
|
||||
uses: aquasecurity/trivy-action@595be6a0f6560a0a8fc419ddf630567fc623531d # 0.22.0
|
||||
with:
|
||||
image-ref: ${{ steps.meta.outputs.tags }}
|
||||
format: 'sarif'
|
||||
output: 'trivy-results-${{ matrix.service }}.sarif'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
exit-code: '1' # Fail the build on critical/high vulnerabilities
|
||||
|
||||
- name: Upload Trivy results to GitHub Security
|
||||
if: always()
|
||||
uses: github/codeql-action/upload-sarif@e8893c57a1f3a2b659b6b55564fdfdbbd2982911 # v3.24.0
|
||||
with:
|
||||
sarif_file: 'trivy-results-${{ matrix.service }}.sarif'
|
||||
category: 'trivy-${{ matrix.service }}'
|
||||
|
||||
- name: Run Trivy in table format
|
||||
if: always()
|
||||
uses: aquasecurity/trivy-action@595be6a0f6560a0a8fc419ddf630567fc623531d # 0.22.0
|
||||
with:
|
||||
image-ref: ${{ steps.meta.outputs.tags }}
|
||||
format: 'table'
|
||||
severity: 'CRITICAL,HIGH,MEDIUM'
|
||||
|
||||
85
SECURITY.md
Normal file
85
SECURITY.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We release patches for security vulnerabilities for the following versions:
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| latest | :white_check_mark: |
|
||||
| < 1.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you discover a security vulnerability, please report it by:
|
||||
|
||||
1. **DO NOT** open a public issue
|
||||
2. Email the maintainers or use GitHub's private vulnerability reporting
|
||||
3. Include detailed information about the vulnerability:
|
||||
- Type of vulnerability
|
||||
- Steps to reproduce
|
||||
- Potential impact
|
||||
- Suggested fix (if any)
|
||||
|
||||
We will respond within 48 hours and provide regular updates on the fix progress.
|
||||
|
||||
## Security Measures
|
||||
|
||||
### Build Pipeline Security
|
||||
|
||||
Our CI/CD pipeline implements multiple security layers:
|
||||
|
||||
1. **Fork PR Protection**: Pull requests from forks require manual approval (via `safe-to-build` label) before builds run
|
||||
2. **Vulnerability Scanning**: All images are scanned with Trivy for CRITICAL and HIGH vulnerabilities
|
||||
3. **SBOM Generation**: Software Bill of Materials is generated for all builds
|
||||
4. **Provenance Attestation**: Build provenance is recorded for supply chain security
|
||||
5. **SHA-Pinned Actions**: All GitHub Actions are pinned to specific SHA commits
|
||||
6. **Limited Permissions**: Workflows use minimal required permissions
|
||||
7. **No Push from PRs**: Pull requests only build images locally, never push to registry
|
||||
|
||||
### Container Security
|
||||
|
||||
- Multi-architecture support (amd64, arm64)
|
||||
- Regular base image updates
|
||||
- Minimal attack surface
|
||||
- Non-root user execution where possible
|
||||
|
||||
### Dependency Management
|
||||
|
||||
- Automated dependency updates via Dependabot
|
||||
- Security alerts enabled
|
||||
- Regular security audits
|
||||
|
||||
## Security Best Practices for Contributors
|
||||
|
||||
When contributing:
|
||||
|
||||
1. Never commit secrets, tokens, or credentials
|
||||
2. Use environment variables for sensitive configuration
|
||||
3. Keep dependencies up to date
|
||||
4. Follow principle of least privilege
|
||||
5. Validate and sanitize all user inputs
|
||||
6. Use parameterized queries for database operations
|
||||
|
||||
## Automated Security Checks
|
||||
|
||||
Our repository includes:
|
||||
|
||||
- **Trivy vulnerability scanning** on every build
|
||||
- **Dependabot** for dependency updates
|
||||
- **GitHub Security Advisories** monitoring
|
||||
- **SARIF upload** to GitHub Security tab for vulnerability tracking
|
||||
|
||||
## Safe-to-Build Label
|
||||
|
||||
For maintainers reviewing fork PRs:
|
||||
|
||||
1. Review the PR code thoroughly for malicious content
|
||||
2. Check for suspicious file modifications
|
||||
3. Verify no secrets or credentials are exposed
|
||||
4. Only add `safe-to-build` label if code is verified safe
|
||||
5. Remove label immediately if concerns arise
|
||||
|
||||
## Security Updates
|
||||
|
||||
Security updates are prioritized and released as soon as possible. Subscribe to repository releases to stay informed.
|
||||
Reference in New Issue
Block a user