Skip to content

Security Audit

Security Audit #61

name: Security Audit
on:
pull_request:
push:
branches:
- master
schedule:
- cron: "0 5 * * 1"
permissions:
contents: read
pull-requests: read
concurrency:
group: security-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changes:
name: Change classification
if: github.event_name != 'schedule'
uses: ./.github/workflows/change-classification.yml
dependency-audit:
name: Dependency Audit
runs-on: ubuntu-latest
needs: changes
if: >-
always() && (
github.event_name == 'schedule' ||
needs.changes.outputs.dependencies == 'true' ||
needs.changes.outputs.automation == 'true'
)
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.4"
tools: composer
extensions: mbstring, sqlite, pdo_sqlite
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version: "24"
cache: npm
- name: Install PHP dependencies
run: composer install --no-interaction --no-progress --prefer-dist
- name: Install Node dependencies
run: npm ci --no-audit --fund=false
- name: Run Composer Audit
run: composer audit --no-interaction --abandoned=report
- name: Run NPM Audit (production)
run: npm audit --omit=dev --audit-level=high
secret-scan:
name: Secret Scan
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
sast:
name: SAST
runs-on: ubuntu-latest
needs: changes
if: >-
always() && (
github.event_name == 'schedule' ||
(github.ref == 'refs/heads/master' && needs.changes.outputs.source == 'true')
)
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: |
p/php
p/owasp-top-ten
p/secrets
gate:
name: Security gate
runs-on: ubuntu-latest
if: always()
needs:
- changes
- dependency-audit
- secret-scan
- sast
steps:
- name: Require successful executed checks
if: >-
contains(needs.*.result, 'failure') ||
contains(needs.*.result, 'cancelled')
run: exit 1