Skip to content

Security - 2x Daily Dependency Scan #100

Security - 2x Daily Dependency Scan

Security - 2x Daily Dependency Scan #100

# ============================================================================
# Security Dependency Scan - 2x Daily Forced Scans
# ============================================================================
#
# This workflow complements Dependabot by forcing additional dependency scans
# 2x per day (midnight and noon UTC) to catch vulnerabilities faster.
#
# Runs: 2x daily (00:00 UTC and 12:00 UTC)
# Action: Triggers Dependabot via API + runs npm audit
# ============================================================================
name: Security - 2x Daily Dependency Scan
on:
schedule:
- cron: '0 0 * * *' # Midnight UTC
- cron: '0 12 * * *' # Noon UTC
workflow_dispatch: # Manual trigger
permissions:
contents: write
issues: write
pull-requests: write
jobs:
# ===================================
# NPM Audit Scan
# ===================================
npm-audit:
name: NPM Audit Security Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9.1.0
- name: Run npm audit
id: audit
continue-on-error: true
run: |
echo "Running npm audit..."
pnpm audit --json > audit-report.json || true
# Check for CRITICAL or HIGH vulnerabilities
CRITICAL=$(cat audit-report.json | jq -r '.metadata.vulnerabilities.critical // 0')
HIGH=$(cat audit-report.json | jq -r '.metadata.vulnerabilities.high // 0')
echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
echo "high=$HIGH" >> $GITHUB_OUTPUT
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "Found $CRITICAL CRITICAL and $HIGH HIGH vulnerabilities"
exit 1
fi
- name: Create security issue if vulnerabilities found
if: failure() && steps.audit.outcome == 'failure'
uses: actions/github-script@v7
with:
script: |
const critical = '${{ steps.audit.outputs.critical }}';
const high = '${{ steps.audit.outputs.high }}';
const title = `🚨 Security Alert: ${critical} CRITICAL + ${high} HIGH vulnerabilities detected`;
const body = `
## Security Vulnerability Alert
**Scan Time:** ${new Date().toUTCString()}
**Scan Type:** Automated 2x Daily Dependency Scan
### Summary
- **CRITICAL:** ${critical}
- **HIGH:** ${high}
### Action Required
1. Review the npm audit report in the workflow logs
2. Check Dependabot PRs for available fixes
3. If no PR exists, manually update vulnerable packages
### View Details
- [Workflow Run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
- [Security Tab](${{ github.server_url }}/${{ github.repository }}/security)
---
*This issue was created automatically by the 2x Daily Security Scan*
`;
// Check if issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'security,automated,dependencies'
});
const existingIssue = issues.data.find(issue =>
issue.title.includes('Security Alert') &&
issue.title.includes('vulnerabilities detected')
);
if (existingIssue) {
// Update existing issue
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: body
});
} else {
// Create new issue
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['security', 'automated', 'dependencies', 'critical']
});
}
# ===================================
# Trigger Dependabot Scan (via API)
# ===================================
trigger-dependabot:
name: Trigger Dependabot Scan
runs-on: ubuntu-latest
needs: npm-audit
steps:
- name: Trigger Dependabot via workflow dispatch
run: |
echo "Dependabot scans are triggered automatically by GitHub"
echo "This job serves as a reminder to check Dependabot PRs"
- name: Check for open Dependabot PRs
uses: actions/github-script@v7
with:
script: |
const prs = await github.rest.pulls.list({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open'
});
const dependabotPRs = prs.data.filter(pr =>
pr.user.login === 'dependabot[bot]'
);
if (dependabotPRs.length > 0) {
console.log(`Found ${dependabotPRs.length} open Dependabot PRs:`);
dependabotPRs.forEach(pr => {
console.log(`- ${pr.title} (#${pr.number})`);
});
} else {
console.log('No open Dependabot PRs found');
}
# ============================================================================
# HOW IT WORKS
# ============================================================================
#
# 1. Runs 2x per day (midnight and noon UTC)
# 2. Executes npm audit to scan for vulnerabilities
# 3. If CRITICAL or HIGH vulnerabilities found:
# a. Creates/updates GitHub Issue with details
# b. Alerts team via issue
# 4. Checks for open Dependabot PRs and logs them
#
# This complements Dependabot's daily scan (6:00 UTC) with additional
# scans at 00:00 and 12:00 UTC for faster vulnerability detection.
#
# Email Notifications:
# - Disable in: Settings > Notifications > Email preferences
# - Or: Settings > Notifications > Watching > Ignore workflow notifications
#
# ============================================================================