external/anthropic-cybersecurity-skills/skills/implementing-devsecops-security-scanning/SKILL.md
Integrates SAST, DAST, and SCA into CI/CD pipelines using Semgrep for SAST, Trivy for SCA and container scanning, OWASP ZAP for DAST, and Gitleaks for secrets detection. Use when setting up automated security scanning in CI/CD, shifting security left, meeting compliance mandates (SOC 2, PCI-DSS, ISO 27001), or gating deployments on critical vulnerabilities.
npx skillsauth add seikaikyo/dash-skills implementing-devsecops-security-scanningInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Do not use as a replacement for manual penetration testing. Automated scanning catches common vulnerability patterns but cannot replace human-driven security assessments for business logic flaws and complex attack chains.
p/security-audit, p/owasp-top-ten)Secrets detection runs first because leaked credentials are the highest-priority finding. Add to .github/workflows/security.yml:
name: DevSecOps Security Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
secrets-scan:
name: Secrets Detection (Gitleaks)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for scanning all commits
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Configure .gitleaks.toml in the repository root for custom rules and allowlists:
[extend]
useDefault = true
[allowlist]
description = "Global allowlist"
paths = [
'''\.gitleaks\.toml''',
'''test/fixtures/.*''',
'''docs/examples/.*'''
]
[[rules]]
id = "custom-internal-api-key"
description = "Internal API key pattern"
regex = '''INTERNAL_KEY_[A-Za-z0-9]{32}'''
tags = ["internal", "api-key"]
Semgrep performs static code analysis to find security vulnerabilities, bugs, and code patterns:
sast-scan:
name: SAST (Semgrep)
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep SAST scan
run: |
semgrep scan \
--config p/security-audit \
--config p/owasp-top-ten \
--config p/secrets \
--severity ERROR \
--error \
--json \
--output semgrep-results.json \
.
- name: Upload SAST results
if: always()
uses: actions/upload-artifact@v4
with:
name: semgrep-results
path: semgrep-results.json
For custom rules, create .semgrep/custom-rules.yml:
rules:
- id: no-exec-user-input
patterns:
- pattern: exec($INPUT)
- pattern-not: exec("...")
message: >
User input passed to exec(). This is a command injection vulnerability.
severity: ERROR
languages: [python]
metadata:
cwe: "CWE-78: OS Command Injection"
owasp: "A03:2021 - Injection"
- id: no-raw-sql-queries
patterns:
- pattern: cursor.execute(f"...")
- pattern: cursor.execute("..." + ...)
message: >
SQL query built with string concatenation or f-strings. Use parameterized queries.
severity: ERROR
languages: [python]
metadata:
cwe: "CWE-89: SQL Injection"
owasp: "A03:2021 - Injection"
Trivy scans dependencies, container images, IaC files, and generates SBOM:
sca-scan:
name: SCA & Container Scan (Trivy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Trivy filesystem scan (dependencies)
uses: aquasecurity/[email protected]
with:
scan-type: 'fs'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
exit-code: '1'
format: 'json'
output: 'trivy-fs-results.json'
- name: Run Trivy IaC scan (Terraform, CloudFormation)
uses: aquasecurity/[email protected]
with:
scan-type: 'config'
scan-ref: '.'
severity: 'CRITICAL,HIGH'
exit-code: '1'
format: 'json'
output: 'trivy-iac-results.json'
- name: Upload SCA results
if: always()
uses: actions/upload-artifact@v4
with:
name: trivy-results
path: trivy-*.json
container-scan:
name: Container Image Scan (Trivy)
runs-on: ubuntu-latest
needs: [sast-scan] # Build image only after SAST passes
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t app:${{ github.sha }} .
- name: Scan container image
uses: aquasecurity/[email protected]
with:
image-ref: 'app:${{ github.sha }}'
severity: 'CRITICAL,HIGH'
exit-code: '1'
format: 'json'
output: 'trivy-image-results.json'
- name: Generate SBOM
uses: aquasecurity/[email protected]
with:
image-ref: 'app:${{ github.sha }}'
format: 'cyclonedx'
output: 'sbom.json'
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.json
DAST runs against a deployed staging environment. It is slower than SAST/SCA and should run asynchronously or on a schedule:
dast-scan:
name: DAST (OWASP ZAP)
runs-on: ubuntu-latest
needs: [deploy-staging] # Must run after app is deployed to staging
steps:
- uses: actions/checkout@v4
- name: Run ZAP Baseline Scan (fast, suitable for CI)
uses: zaproxy/[email protected]
with:
target: ${{ vars.STAGING_URL }}
rules_file_name: '.zap/rules.tsv'
cmd_options: '-a -j'
# For nightly full scans, use action-full-scan instead:
# - name: Run ZAP Full Scan (comprehensive, 30-60 min)
# uses: zaproxy/[email protected]
# with:
# target: ${{ vars.STAGING_URL }}
Create .zap/rules.tsv to configure alert thresholds:
10010 IGNORE (Cookie No HttpOnly Flag - acceptable for non-sensitive cookies)
10011 IGNORE (Cookie Without Secure Flag - staging uses HTTP)
90033 WARN (Loosely Scoped Cookie)
10038 FAIL (Content Security Policy Header Not Set)
40012 FAIL (Cross Site Scripting - Reflected)
40014 FAIL (Cross Site Scripting - Persistent)
40018 FAIL (SQL Injection)
90019 FAIL (Server Side Code Injection)
90020 FAIL (Remote OS Command Injection)
Create a summary job that aggregates all scan results and enforces pass/fail gates:
security-gate:
name: Security Gate
runs-on: ubuntu-latest
needs: [secrets-scan, sast-scan, sca-scan, container-scan]
if: always()
steps:
- name: Check scan results
run: |
echo "Checking security scan results..."
# Fail the pipeline if any upstream job failed
if [[ "${{ needs.secrets-scan.result }}" == "failure" ]]; then
echo "BLOCKED: Secrets detected in repository"
exit 1
fi
if [[ "${{ needs.sast-scan.result }}" == "failure" ]]; then
echo "BLOCKED: SAST found critical/high vulnerabilities"
exit 1
fi
if [[ "${{ needs.sca-scan.result }}" == "failure" ]]; then
echo "BLOCKED: SCA found critical/high vulnerable dependencies"
exit 1
fi
if [[ "${{ needs.container-scan.result }}" == "failure" ]]; then
echo "BLOCKED: Container image has critical/high vulnerabilities"
exit 1
fi
echo "All security gates passed"
Enforce the security pipeline as a required status check:
GitHub Repository > Settings > Branches > Branch Protection Rules
Branch name pattern: main
Require status checks to pass before merging: Enabled
Required status checks:
- Secrets Detection (Gitleaks)
- SAST (Semgrep)
- SCA & Container Scan (Trivy)
- Security Gate
Require branches to be up to date before merging: Enabled
Configure pre-commit hooks so developers catch issues before pushing:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.22.1
hooks:
- id: gitleaks
- repo: https://github.com/semgrep/semgrep
rev: v1.102.0
hooks:
- id: semgrep
args: ['--config', 'p/security-audit', '--config', 'p/owasp-top-ten', '--error']
Install and activate pre-commit:
pip install pre-commit
pre-commit install
pre-commit run --all-files # Test against existing codebase
| Term | Definition | |------|------------| | SAST (Static Application Security Testing) | Analyzes source code without executing it to find security vulnerabilities; runs fast, catches issues early, but cannot find runtime flaws | | DAST (Dynamic Application Security Testing) | Tests a running application by sending requests and analyzing responses; finds runtime issues but requires a deployed environment | | SCA (Software Composition Analysis) | Scans project dependencies against vulnerability databases (NVD, GitHub Advisory) to find known-vulnerable libraries | | SBOM (Software Bill of Materials) | Machine-readable inventory of all components and dependencies in an application, used for vulnerability tracking and compliance | | Shift Left | Security practice of moving security testing earlier in the SDLC, from post-deployment to pre-commit and CI stages | | Security Gate | A CI/CD pipeline checkpoint that blocks deployment if security scan results exceed defined severity thresholds | | Pre-commit Hook | Local Git hook that runs security checks before code is committed, providing the fastest developer feedback loop |
tools
Conduct comprehensive GDPR compliance assessments by evaluating data processing activities against EU Regulation 2016/679, including Article 30 records of processing, lawful basis validation, data subject rights implementation, Data Protection Impact Assessments (DPIAs) under Article 35, breach notification procedures, international transfer safeguards (SCCs, adequacy decisions), and technical/organizational measures under Article 32. Use when processing personal data of EU residents, preparing for supervisory authority audits, implementing privacy-by-design for new systems, scoping compliance gaps for M&A due diligence, assessing third-party processors, or responding to data subject access requests at scale. Incorporates 2026 guidance from ICO, EDPB, and post-Data (Use and Access) Act 2025 UK-GDPR considerations. Do not use for implementing specific Article 32 controls — use implementing-gdpr-data-protection-controls; or for DSAR automation — use implementing-gdpr-data-subject-access-request.
tools
Parse Windows forensic artifacts—$MFT/$J (MFTECmd), Prefetch (PECmd), registry hives (RECmd), shellbags, and Amcache—into normalized CSV/JSON with Eric Zimmerman's EZ Tools, then load results into Timeline Explorer for analysis. Use during DFIR/incident-response investigations, after triage collection (e.g. with KAPE), to establish program execution, file/folder access, and persistence evidence from acquired forensic images.
development
Build automated multi-turn adversarial attacks against conversational LLM targets using Microsoft PyRIT's RedTeamingOrchestrator, CrescendoOrchestrator (gradual escalation), and TreeOfAttacksWithPruningOrchestrator (adaptive branching), with scorer feedback loops and persisted conversation memory. Use when single-shot LLM scanning is insufficient and you need multi-turn, scorer-driven AI red-team campaigns against a chatbot or agent.
testing
Stand up MISP, enable and cache curated threat feeds (CIRCL, abuse.ch, Feodo Tracker), apply warninglists to suppress false positives, query indicators with PyMISP, and export attributes as auto-generated Suricata/Sigma/Wazuh detection rules. Use when maturing a MISP instance to actively drive detection, curating threat feeds with quality controls, or automating IOC-to-detection pipelines for the SIEM/IDS.