Security #57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # yaml-language-server: $schema=https://www.schemastore.org/github-workflow.json | |
| # | |
| # Security Review: This workflow does NOT use any untrusted user inputs in run commands. | |
| # All GitHub context usage is limited to safe values: needs.*.result and secrets. | |
| name: Security | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| # Manual trigger from GitHub UI (runs on selected branch, typically main) | |
| schedule: | |
| # Run weekly on Monday at 6am UTC for drift detection | |
| - cron: "0 6 * * 1" | |
| # Cancel in-progress runs when new commits are pushed | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Trivy IaC scanning for misconfigurations | |
| trivy-iac: | |
| name: Trivy IaC Scan | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout code | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| - name: Run Trivy IaC scanner (Terraform) | |
| uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 | |
| with: | |
| scan-type: "config" | |
| scan-ref: "terraform/" | |
| format: "sarif" | |
| output: "trivy-terraform.sarif" | |
| severity: "CRITICAL,HIGH,MEDIUM" | |
| exit-code: "0" | |
| version: "v0.60.0" # Pin to stable version (v0.65.0 has panic bugs) | |
| - name: Run Trivy IaC scanner (Kubernetes) | |
| uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # 0.33.1 | |
| with: | |
| scan-type: "config" | |
| scan-ref: "flux/" | |
| format: "sarif" | |
| output: "trivy-kubernetes.sarif" | |
| severity: "CRITICAL,HIGH,MEDIUM" | |
| exit-code: "0" | |
| version: "v0.60.0" # Pin to stable version (v0.65.0 has panic bugs) | |
| - name: Upload Trivy Terraform results | |
| uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 | |
| with: | |
| sarif_file: "trivy-terraform.sarif" | |
| category: "trivy-terraform" | |
| - name: Upload Trivy Kubernetes results | |
| uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 | |
| with: | |
| sarif_file: "trivy-kubernetes.sarif" | |
| category: "trivy-kubernetes" | |
| # Checkov compliance scanning | |
| checkov: | |
| name: Checkov Compliance | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout code | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| - name: Run Checkov on Terraform | |
| uses: bridgecrewio/checkov-action@8f61ce5b8a3afb4ca94d236b75201878ded6d2cd # v12.3077.0 | |
| with: | |
| directory: terraform/ | |
| framework: terraform | |
| output_format: sarif | |
| output_file_path: checkov-terraform.sarif | |
| soft_fail: true | |
| compact: true | |
| quiet: true | |
| skip_check: CKV_TF_1 | |
| - name: Run Checkov on Kubernetes | |
| uses: bridgecrewio/checkov-action@8f61ce5b8a3afb4ca94d236b75201878ded6d2cd # v12.3077.0 | |
| with: | |
| directory: flux/ | |
| framework: kubernetes | |
| output_format: sarif | |
| output_file_path: checkov-kubernetes.sarif | |
| soft_fail: true | |
| compact: true | |
| quiet: true | |
| # Skip Flux-generated gotk-components, flux-system directories (vendor code), | |
| # and auto-generated dev registry patches (local development only) | |
| skip_path: flux/clusters/dev-local/flux-system,flux/clusters/staging/flux-system,flux/clusters/production/flux-system,flux/apps/dev/registry-patch.yaml | |
| # Skip checks that are handled elsewhere or intentional design choices: | |
| # - CKV_K8S_14/43: Image tags managed by Flux image automation | |
| # - CKV2_K8S_6: NetworkPolicies are CiliumNetworkPolicy in policies/ | |
| # - CKV_K8S_22: Dashboard needs writable fs for Next.js | |
| # - CKV_K8S_35: Secrets as env vars is acceptable for optional config | |
| skip_check: CKV_K8S_14,CKV_K8S_43,CKV2_K8S_6,CKV_K8S_22,CKV_K8S_35 | |
| - name: Upload Checkov Terraform results | |
| uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 | |
| if: always() | |
| with: | |
| sarif_file: checkov-terraform.sarif | |
| category: "checkov-terraform" | |
| - name: Upload Checkov Kubernetes results | |
| uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 | |
| if: always() | |
| with: | |
| sarif_file: checkov-kubernetes.sarif | |
| category: "checkov-kubernetes" | |
| # KICS (Keeping Infrastructure as Code Secure) scanning | |
| kics: | |
| name: KICS Security Scan | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 | |
| with: | |
| egress-policy: audit | |
| - name: Checkout code | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | |
| - name: Run KICS scan | |
| uses: Checkmarx/kics-github-action@00def9108246ec656aea725db2167522d26a99d2 # v2.1.3 | |
| with: | |
| path: "terraform/,flux/,policies/" | |
| output_path: kics-results/ | |
| output_formats: "sarif" | |
| fail_on: high | |
| enable_comments: true | |
| continue-on-error: true | |
| - name: Upload KICS results | |
| uses: github/codeql-action/upload-sarif@5d4e8d1aca955e8d8589aabd499c5cae939e33c7 # v4.31.9 | |
| if: always() | |
| with: | |
| sarif_file: kics-results/results.sarif | |
| category: "kics" | |
| # Security scan summary | |
| security-summary: | |
| name: Security Summary | |
| needs: [trivy-iac, checkov, kics] | |
| runs-on: ubuntu-latest | |
| if: always() | |
| permissions: | |
| contents: read | |
| steps: | |
| - name: Harden the runner (Audit all outbound calls) | |
| uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 | |
| with: | |
| egress-policy: audit | |
| - name: Check security scan results | |
| env: | |
| TRIVY_RESULT: ${{ needs.trivy-iac.result }} | |
| CHECKOV_RESULT: ${{ needs.checkov.result }} | |
| KICS_RESULT: ${{ needs.kics.result }} | |
| run: | | |
| echo "## Security Scan Results" | |
| echo "" | |
| echo "| Scanner | Status |" | |
| echo "|---------|--------|" | |
| echo "| Trivy IaC | $TRIVY_RESULT |" | |
| echo "| Checkov | $CHECKOV_RESULT |" | |
| echo "| KICS | $KICS_RESULT |" | |
| echo "" | |
| echo "Secret scanning is handled by GitHub's native push protection." | |
| # Fail if any security job failed | |
| failed=false | |
| if [[ "$TRIVY_RESULT" != "success" && "$TRIVY_RESULT" != "skipped" ]]; then | |
| echo "❌ Trivy IaC scan failed" | |
| failed=true | |
| fi | |
| if [[ "$CHECKOV_RESULT" != "success" && "$CHECKOV_RESULT" != "skipped" ]]; then | |
| echo "❌ Checkov compliance scan failed" | |
| failed=true | |
| fi | |
| if [[ "$KICS_RESULT" != "success" && "$KICS_RESULT" != "skipped" ]]; then | |
| echo "❌ KICS security scan failed" | |
| failed=true | |
| fi | |
| if [[ "$failed" == "true" ]]; then | |
| echo "" | |
| echo "❌ One or more security checks failed" | |
| exit 1 | |
| fi | |
| echo "✅ All security checks passed!" |