1. Core Security Workflows
Main Security Pipeline
# .github/workflows/security.yml
name: Security Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
schedule:
- cron: '0 0 * * 1' # Weekly security scans
env:
JAVA_VERSION: '17'
MAVEN_VERSION: '3.8.6'
jobs:
sast:
name: Static Application Security Testing
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'temurin'
cache: 'maven'
- name: Run SpotBugs Security Analysis
run: |
mvn compile spotbugs:spotbugs -Dspotbugs.includeTests=true
mvn spotbugs:check
- name: Upload SpotBugs Report
uses: actions/upload-artifact@v4
with:
name: spotbugs-report
path: target/spotbugs.xml
retention-days: 30
sca:
name: Software Composition Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: ${{ env.JAVA_VERSION }}
distribution: 'temurin'
cache: 'maven'
- name: Run OWASP Dependency Check
run: |
mvn org.owasp:dependency-check-maven:check -Dformat=ALL
- name: Upload Dependency Check Report
uses: actions/upload-artifact@v4
with:
name: dependency-check-report
path: target/dependency-check-report.*
retention-days: 30
- name: Run Snyk Security Scan
uses: snyk/actions/maven@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high --sarif-file-output=snyk.sarif
- name: Upload Snyk SARIF Results
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: snyk.sarif
secrets-detection:
name: Secrets Detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect Secrets with Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITLEAKS_VERSION: v8.18.0
with:
config-path: .gitleaks.toml
report-format: sarif
redact: true
- name: Upload Gitleaks Results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: gitleaks-report.sarif
codeql:
name: CodeQL Analysis
runs-on: ubuntu-latest
permissions:
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'java' ]
steps:
- uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{matrix.language}}"
container-security:
name: Container Security Scan
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'schedule'
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
security-summary:
name: Security Summary
runs-on: ubuntu-latest
needs: [sast, sca, secrets-detection, codeql, container-security]
if: always()
steps:
- name: Generate Security Report
uses: actions/github-script@v7
with:
script: |
const { generateSecurityReport } = require('./.github/scripts/security-report.js');
await generateSecurityReport(github, context);
2. Advanced Security Workflows
SAST with Multiple Tools
# .github/workflows/sast-advanced.yml name: Advanced SAST on: pull_request: branches: [ main, develop ] push: branches: [ main ] jobs: spotbugs-security: name: SpotBugs Security runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Java uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Run SpotBugs with Security Rules run: | mvn compile spotbugs:spotbugs -Dspotbugs.includeTests=true \ -Dspotbugs.effort=Max \ -Dspotbugs.threshold=Low \ -Dspotbugs.visitors=FindSecurityBugs - name: Convert to SARIF uses: spotbugs/[email protected] with: path: target/spotbugsXml.xml name: SpotBugs Security Report pmd-security: name: PMD Security Analysis runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Java uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Run PMD Security Rules run: | mvn pmd:pmd -Dpmd.rulesets=category/java/security.xml - name: Upload PMD Report uses: actions/upload-artifact@v4 with: name: pmd-security-report path: target/pmd.xml checkstyle-security: name: CheckStyle Security Checks runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Java uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Run CheckStyle with Security Configuration run: | mvn checkstyle:checkstyle -Dcheckstyle.config.location=google_checks.xml - name: Upload CheckStyle Report uses: actions/upload-artifact@v4 with: name: checkstyle-report path: target/checkstyle-result.xml sonarqube: name: SonarQube Analysis runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Java uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' - name: Cache SonarQube packages uses: actions/cache@v4 with: path: ~/.sonar/cache key: ${{ runner.os }}-sonar restore-keys: ${{ runner.os }}-sonar - name: Run SonarQube Analysis run: | mvn sonar:sonar \ -Dsonar.projectKey=my-java-app \ -Dsonar.host.url=${{ secrets.SONAR_HOST_URL }} \ -Dsonar.login=${{ secrets.SONAR_TOKEN }} \ -Dsonar.java.spotbugs.reportPaths=target/spotbugsXml.xml \ -Dsonar.java.pmd.reportPaths=target/pmd.xml \ -Dsonar.java.checkstyle.reportPaths=target/checkstyle-result.xml
Dependency Vulnerability Management
# .github/workflows/dependency-security.yml
name: Dependency Security
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 6 * * 1' # Weekly on Monday
jobs:
dependency-audit:
name: Dependency Audit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: 'maven'
- name: Run OWASP Dependency Check
run: |
mvn org.owasp:dependency-check-maven:aggregate \
-Dformat=HTML \
-Dformat=JSON \
-Dformat=JUNIT \
-DfailBuildOnCVSS=7 \
-DsuppressionFile=suppressions.xml
- name: Upload Dependency Check Reports
uses: actions/upload-artifact@v4
with:
name: dependency-check-reports
path: |
target/dependency-check-report.html
target/dependency-check-report.json
retention-days: 30
- name: Publish Dependency Check Results
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '🚨 Dependency check failed! Critical vulnerabilities found. Please review the report.'
})
snyk-monitor:
name: Snyk Continuous Monitoring
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Snyk to check for vulnerabilities
uses: snyk/actions/maven@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --all-projects --detection-depth=6
- name: Snyk Monitor
uses: snyk/actions/maven@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: monitor --all-projects
license-compliance:
name: License Compliance Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Run License Maven Plugin
run: |
mvn license:add-third-party \
-Dlicense.thirdPartyFilename=THIRD-PARTY.txt \
-Dlicense.failOnMissing=true \
-Dlicense.failOnBlacklist=true
- name: Check Forbidden Licenses
run: |
if grep -q "GPL" THIRD-PARTY.txt; then
echo "❌ Forbidden GPL license detected"
exit 1
fi
out-of-date-dependencies:
name: Out-of-Date Dependencies
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Check for outdated dependencies
run: |
mvn versions:display-dependency-updates versions:display-plugin-updates
- name: Create Dependency Update Issue
if: failure()
uses: actions/github-script@v7
with:
script: |
const { checkDependencyUpdates } = require('./.github/scripts/dependency-updates.js');
await checkDependencyUpdates(github, context);
3. Secret Management and Detection
# .github/workflows/secrets-management.yml
name: Secrets Management
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
gitleaks:
name: Gitleaks Secret Detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
with:
config-path: .gitleaks.toml
report-format: sarif
no-git: false
redact: true
verbose: true
- name: Upload Gitleaks Results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: gitleaks-report.sarif
trufflehog:
name: TruffleHog Deep Secret Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run TruffleHog
uses: trufflesecurity/trufflehog@main
with:
path: ./
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.event.pull_request.head.sha }}
extra_args: --debug --only-verified
git-secrets:
name: AWS git-secrets
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install git-secrets
run: |
git clone https://github.com/awslabs/git-secrets.git
cd git-secrets && sudo make install
- name: Configure git-secrets
run: |
git secrets --register-aws
git secrets --scan-history
secret-scan-summary:
name: Secret Scan Summary
runs-on: ubuntu-latest
needs: [gitleaks, trufflehog, git-secrets]
if: always()
steps:
- name: Generate Secret Scan Report
uses: actions/github-script@v7
with:
script: |
const { generateSecretScanReport } = require('./.github/scripts/secret-scan-report.js');
await generateSecretScanReport(github, context);
4. Container Security
# .github/workflows/container-security.yml
name: Container Security
on:
push:
branches: [ main ]
tags: [ 'v*' ]
pull_request:
branches: [ main ]
jobs:
trivy-scan:
name: Trivy Vulnerability Scan
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'myapp:${{ github.sha }}'
format: 'sarif'
output: 'trivy-results.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarif
- name: Run Trivy filesystem scan
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'table'
exit-code: 1
dockerfile-lint:
name: Dockerfile Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Hadolint
uses: hadolint/[email protected]
with:
dockerfile: Dockerfile
failure-threshold: warning
- name: Check Dockerfile best practices
run: |
docker run --rm -i hadolint/hadolint < Dockerfile
image-hardening:
name: Image Hardening Check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Check for root user
run: |
if docker run myapp:${{ github.sha }} whoami | grep -q root; then
echo "❌ Container running as root user"
exit 1
fi
- name: Check image size
run: |
SIZE=$(docker images myapp:${{ github.sha }} --format "{{.Size}}")
echo "Image size: $SIZE"
# Add size limits as needed
cosign-sign:
name: Cosign Image Signing
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Install Cosign
uses: sigstore/cosign-installer@main
- name: Sign container image
run: |
cosign sign --key env://COSIGN_PRIVATE_KEY myapp:${{ github.sha }}
env:
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
5. Infrastructure as Code Security
# .github/workflows/iac-security.yml name: IaC Security on: push: paths: - '**.tf' - '**.tfvars' - 'kubernetes/**' pull_request: paths: - '**.tf' - '**.tfvars' - 'kubernetes/**' jobs: terraform-security: name: Terraform Security Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run tfsec uses: aquasecurity/tfsec-action@master with: soft-fail: false output-format: sarif output-file: tfsec.sarif - name: Upload tfsec results uses: github/codeql-action/upload-sarif@v3 with: sarif_file: tfsec.sarif - name: Run Checkov uses: bridgecrewio/checkov-action@master with: directory: . framework: terraform output_format: sarif output_file_path: checkov.sarif - name: Upload Checkov results uses: github/codeql-action/upload-sarif@v3 with: sarif_file: checkov.sarif k8s-security: name: Kubernetes Security Scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run KubeSec uses: controlplaneio/kubectl@master with: args: kubesec scan kubernetes/ - name: Run Kubeaudit uses: controlplaneio/kubectl@master with: args: kubeaudit all -f kubernetes/ - name: Run Polaris uses: FairwindsOps/polaris@master with: audit-path: kubernetes/ output-format: sarif
6. Custom Security Scripts in Java
// .github/scripts/SecurityReportGenerator.java
package com.github.scripts;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
public class SecurityReportGenerator {
public static void main(String[] args) throws IOException {
String workflow = args.length > 0 ? args[0] : "security";
generateSecurityReport(workflow);
}
public static void generateSecurityReport(String workflowName) throws IOException {
Map<String, Object> report = new HashMap<>();
report.put("workflow", workflowName);
report.put("timestamp", System.currentTimeMillis());
report.put("repository", System.getenv("GITHUB_REPOSITORY"));
// Collect security findings
Map<String, Object> findings = collectSecurityFindings();
report.put("findings", findings);
// Calculate security score
double securityScore = calculateSecurityScore(findings);
report.put("securityScore", securityScore);
report.put("securityLevel", getSecurityLevel(securityScore));
// Generate report
String reportJson = new JSONObject(report).toString(2);
Files.write(Paths.get("security-report.json"), reportJson.getBytes());
System.out.println("Security Report Generated:");
System.out.println(reportJson);
}
private static Map<String, Object> collectSecurityFindings() throws IOException {
Map<String, Object> findings = new HashMap<>();
// Check for dependency vulnerabilities
findings.put("dependencyVulnerabilities", checkDependencyVulnerabilities());
// Check for SAST issues
findings.put("sastIssues", checkSastIssues());
// Check for secrets
findings.put("secretsFound", checkSecrets());
// Check for container vulnerabilities
findings.put("containerVulnerabilities", checkContainerVulnerabilities());
// Check for IaC issues
findings.put("iacIssues", checkIacIssues());
return findings;
}
private static Map<String, Object> checkDependencyVulnerabilities() throws IOException {
Map<String, Object> vulnerabilities = new HashMap<>();
// Parse OWASP Dependency Check report
Path reportPath = Paths.get("target/dependency-check-report.json");
if (Files.exists(reportPath)) {
String content = Files.readString(reportPath);
JSONObject report = new JSONObject(content);
JSONArray dependencies = report.getJSONArray("dependencies");
int critical = 0;
int high = 0;
int medium = 0;
for (int i = 0; i < dependencies.length(); i++) {
JSONObject dep = dependencies.getJSONObject(i);
if (dep.has("vulnerabilities")) {
JSONArray vulns = dep.getJSONArray("vulnerabilities");
for (int j = 0; j < vulns.length(); j++) {
JSONObject vuln = vulns.getJSONObject(j);
String severity = vuln.getString("severity");
switch (severity.toUpperCase()) {
case "CRITICAL" -> critical++;
case "HIGH" -> high++;
case "MEDIUM" -> medium++;
}
}
}
}
vulnerabilities.put("critical", critical);
vulnerabilities.put("high", high);
vulnerabilities.put("medium", medium);
vulnerabilities.put("total", critical + high + medium);
}
return vulnerabilities;
}
private static Map<String, Object> checkSastIssues() throws IOException {
Map<String, Object> sastIssues = new HashMap<>();
// Parse SpotBugs report
Path spotbugsPath = Paths.get("target/spotbugsXml.xml");
if (Files.exists(spotbugsPath)) {
// Parse XML and count issues by priority
String content = Files.readString(spotbugsPath);
// Implementation for parsing SpotBugs XML
sastIssues.put("spotbugs", parseSpotBugsReport(content));
}
// Parse PMD report
Path pmdPath = Paths.get("target/pmd.xml");
if (Files.exists(pmdPath)) {
String content = Files.readString(pmdPath);
sastIssues.put("pmd", parsePmdReport(content));
}
return sastIssues;
}
private static Map<String, Object> checkSecrets() {
Map<String, Object> secrets = new HashMap<>();
// Implementation for checking secret detection results
return secrets;
}
private static Map<String, Object> checkContainerVulnerabilities() {
Map<String, Object> containerVulns = new HashMap<>();
// Implementation for checking container scan results
return containerVulns;
}
private static Map<String, Object> checkIacIssues() {
Map<String, Object> iacIssues = new HashMap<>();
// Implementation for checking IaC scan results
return iacIssues;
}
private static double calculateSecurityScore(Map<String, Object> findings) {
double score = 100.0;
// Deduct points based on findings
Map<String, Object> vulnerabilities = (Map<String, Object>) findings.get("dependencyVulnerabilities");
int criticalVulns = (int) vulnerabilities.getOrDefault("critical", 0);
int highVulns = (int) vulnerabilities.getOrDefault("high", 0);
score -= criticalVulns * 10;
score -= highVulns * 5;
// Ensure score doesn't go below 0
return Math.max(score, 0);
}
private static String getSecurityLevel(double score) {
if (score >= 90) return "EXCELLENT";
if (score >= 80) return "GOOD";
if (score >= 70) return "FAIR";
if (score >= 60) return "POOR";
return "CRITICAL";
}
private static Map<String, Object> parseSpotBugsReport(String xmlContent) {
Map<String, Object> spotbugs = new HashMap<>();
// Implementation for parsing SpotBugs XML
return spotbugs;
}
private static Map<String, Object> parsePmdReport(String xmlContent) {
Map<String, Object> pmd = new HashMap<>();
// Implementation for parsing PMD XML
return pmd;
}
}
7. Security Configuration Files
OWASP Dependency Check Configuration
<!-- dependency-check-suppressions.xml --> <?xml version="1.0" encoding="UTF-8"?> <suppressions xmlns="https://jeremylong.github.io/DependencyCheck/dependency-suppression.1.3.xsd"> <!-- Suppress false positives --> <suppress> <notes><![CDATA[False positive per issue #1234]]></notes> <cve>CVE-2021-44228</cve> </suppress> <!-- Suppress by package --> <suppress> <notes><![CDATA[Suppress log4j in test scope]]></notes> <packageUrl regex="true">^pkg:maven/org\.apache\.logging\.log4j.*@.*$</packageUrl> <scope>test</scope> </suppress> </suppressions>
Gitleaks Configuration
# .gitleaks.toml
title = "Gitleaks configuration"
[[rules]]
description = "AWS Access Key"
regex = '''(A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}'''
tags = ["key", "AWS"]
[[rules]]
description = "GitHub Personal Access Token"
regex = '''ghp_[0-9a-zA-Z]{36}'''
tags = ["key", "GitHub"]
[[rules]]
description = "Generic API Key"
regex = '''[a|A][p|P][i|I][_]?[k|K][e|E][y|Y].*[''|"][0-9a-zA-Z]{32,45}[''|"]'''
tags = ["key", "API"]
[[rules]]
description = "Password in URL"
regex = '''[a-zA-Z]{3,10}://[^/\\s:@]{3,20}:[^/\\s:@]{3,20}@.{1,100}["'\\s]'''
tags = ["key", "password"]
# Allow list specific files
[[allowlist]]
files = ['']
SpotBugs Security Configuration
<!-- spotbugs-security.xml --> <FindBugsFilter> <!-- Focus on security-related bugs --> <Match> <Bug category="SECURITY"/> </Match> <Match> <Bug pattern="SQL_INJECTION"/> </Match> <Match> <Bug pattern="COMMAND_INJECTION"/> </Match> <Match> <Bug pattern="PATH_TRAVERSAL_IN"/> </Match> <Match> <Bug pattern="XSS_REQUEST_PARAMETER_TO_SEND_ERROR"/> </Match> <!-- Exclude test code from some checks --> <Match> <Source name="~.*Test\.java"/> <Bug pattern="HARD_CODE_PASSWORD"/> </Match> </FindBugsFilter>
8. Maven Security Configuration
<!-- pom.xml security plugins configuration --> <build> <plugins> <!-- OWASP Dependency Check --> <plugin> <groupId>org.owasp</groupId> <artifactId>dependency-check-maven</artifactId> <version>8.2.1</version> <configuration> <format>ALL</format> <failBuildOnCVSS>7</failBuildOnCVSS> <suppressionFile>dependency-check-suppressions.xml</suppressionFile> <skipTestScope>false</skipTestScope> </configuration> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <!-- SpotBugs Security --> <plugin> <groupId>com.github.spotbugs</groupId> <artifactId>spotbugs-maven-plugin</artifactId> <version>4.7.3.0</version> <configuration> <includeFilterFile>spotbugs-security.xml</includeFilterFile> <excludeFilterFile>spotbugs-excludes.xml</excludeFilterFile> <effort>Max</effort> <threshold>Low</threshold> <failOnError>true</failOnError> </configuration> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <!-- PMD Security Rules --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.20.0</version> <configuration> <rulesets> <ruleset>category/java/security.xml</ruleset> </rulesets> <failOnViolation>true</failOnViolation> <printFailingErrors>true</printFailingErrors> </configuration> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> <!-- CheckStyle Security --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>3.2.1</version> <configuration> <configLocation>google_checks.xml</configLocation> <failOnViolation>true</failOnViolation> </configuration> <executions> <execution> <goals> <goal>check</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
Key Security Workflow Features:
- Comprehensive SAST: Multiple static analysis tools (SpotBugs, PMD, CheckStyle)
- SCA Integration: OWASP Dependency Check, Snyk, and license compliance
- Secret Detection: Gitleaks, TruffleHog, and AWS git-secrets
- Container Security: Trivy vulnerability scanning and Docker best practices
- IaC Security: Terraform and Kubernetes security scanning
- CodeQL Integration: GitHub's advanced code analysis
- Automated Reporting: Custom security reports and score calculation
- CI/CD Integration: Seamless integration with development workflows
These workflows provide enterprise-grade security scanning for Java projects, ensuring code quality, dependency security, and compliance with security best practices.