
Sast Scanning
- 101 installs
- 44 repo stars
- Updated May 22, 2026
- bagelhole/devops-security-agent-skills
SAST Scanning is a Claude Code skill that runs static application security testing with Semgrep, CodeQL, and SonarQube to find source-code vulnerabilities before deployment.
About
This skill performs static application security testing with Semgrep, CodeQL, and SonarQube. A developer uses it to find vulnerabilities in source code before deployment, write custom rules for issues like SQL injection and hardcoded passwords, and add security gates to CI/CD. It includes tool comparisons and GitHub Actions workflows.
- Static analysis with Semgrep, CodeQL, and SonarQube
- Custom rules and queries for SQL injection and hardcoded secrets
- CI integration and security gates in GitHub Actions
Sast Scanning by the numbers
- 101 all-time installs (skills.sh)
- Ranked #1,002 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Jul 28, 2026 (Skillselion catalog sync)
sast-scanning capabilities & compatibility
Core tools are open source; Semgrep CI uses a SEMGREP_APP_TOKEN and some tools have commercial tiers.
- Capabilities
- security audit · code review · ci cd
- Works with
- github
- Use cases
- security audit · code review · ci cd
- Pricing
- Freemium
What sast-scanning says it does
Identify security vulnerabilities in source code through static analysis.
Finding vulnerabilities before deployment
message: Hardcoded password detected
npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill sast-scanningAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 101 |
|---|---|
| repo stars | ★ 44 |
| Last updated | May 22, 2026 |
| Repository | bagelhole/devops-security-agent-skills ↗ |
What it does
Run SAST with Semgrep, CodeQL, or SonarQube to catch code vulnerabilities before deploy and gate CI/CD.
Who is it for?
Developers adding static-analysis security gates to a secure SDLC.
Skip if: Runtime or dependency/supply-chain scanning outside source code.
When should I use this skill?
You need to scan source code for vulnerabilities or add a SAST gate to CI/CD.
What you get
Code vulnerabilities are caught by SAST before deployment.
- Semgrep custom rules
- CodeQL workflow
- SonarQube scanner config
By the numbers
- tool comparison table covers 5 SAST tools
- Semgrep supports 30+ languages per the comparison table
Files
SAST Scanning
Identify security vulnerabilities in source code through static analysis.
When to Use This Skill
Use this skill when:
- Implementing secure SDLC practices
- Adding security gates to CI/CD
- Automating code security reviews
- Finding vulnerabilities before deployment
- Meeting compliance requirements
Prerequisites
- Source code access
- CI/CD pipeline
- SAST tool installation
Tool Comparison
| Tool | License | Languages | Best For |
|---|---|---|---|
| Semgrep | OSS/Commercial | 30+ | Custom rules, speed |
| CodeQL | Free (GitHub) | 10+ | Deep analysis |
| SonarQube | OSS/Commercial | 25+ | Quality + Security |
| Bandit | OSS | Python | Python projects |
| Brakeman | OSS | Ruby | Rails apps |
Semgrep
Installation
# Install via pip
pip install semgrep
# Or via Homebrew
brew install semgrepBasic Usage
# Run with default rules
semgrep --config auto .
# Run specific rulesets
semgrep --config p/security-audit .
semgrep --config p/owasp-top-ten .
semgrep --config p/ci .
# Scan specific languages
semgrep --config p/python .
semgrep --config p/javascript .
# Output formats
semgrep --config auto --json -o results.json .
semgrep --config auto --sarif -o results.sarif .Custom Rules
# .semgrep/custom-rules.yaml
rules:
- id: hardcoded-password
patterns:
- pattern-either:
- pattern: password = "..."
- pattern: PASSWORD = "..."
- pattern: passwd = "..."
message: Hardcoded password detected
severity: ERROR
languages: [python, javascript, java]
metadata:
cwe: "CWE-798"
owasp: "A3:2017"
- id: sql-injection
patterns:
- pattern: |
$QUERY = "..." + $USER_INPUT + "..."
$DB.execute($QUERY)
message: Potential SQL injection
severity: ERROR
languages: [python]
metadata:
cwe: "CWE-89"
- id: insecure-random
pattern: random.random()
message: Use secrets module for security-sensitive randomness
severity: WARNING
languages: [python]
fix: secrets.token_hex()CI Configuration
# .github/workflows/semgrep.yml
name: Semgrep
on:
push:
branches: [main]
pull_request:
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: semgrep ci
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}CodeQL
Setup
# .github/workflows/codeql.yml
name: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 0 * * 0'
jobs:
analyze:
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
matrix:
language: ['javascript', 'python']
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 }}"Custom Queries
// queries/sql-injection.ql
/**
* @name SQL Injection
* @description User input in SQL query
* @kind path-problem
* @problem.severity error
* @security-severity 9.0
* @precision high
* @id py/sql-injection
* @tags security
*/
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import semmle.python.security.dataflow.SqlInjectionQuery
from SqlInjectionConfiguration config, DataFlow::PathNode source, DataFlow::PathNode sink
where config.hasFlowPath(source, sink)
select sink.getNode(), source, sink, "SQL injection from $@.", source.getNode(), "user input"SonarQube
Docker Setup
# docker-compose.yml
version: '3.8'
services:
sonarqube:
image: sonarqube:lts-community
ports:
- "9000:9000"
environment:
- SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonar
- SONAR_JDBC_USERNAME=sonar
- SONAR_JDBC_PASSWORD=sonar
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_logs:/opt/sonarqube/logs
depends_on:
- db
db:
image: postgres:15
environment:
- POSTGRES_USER=sonar
- POSTGRES_PASSWORD=sonar
- POSTGRES_DB=sonar
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_logs:
postgresql_data:Scanner Configuration
# sonar-project.properties
sonar.projectKey=myproject
sonar.projectName=My Project
sonar.projectVersion=1.0
sonar.sources=src
sonar.tests=tests
sonar.exclusions=**/node_modules/**,**/vendor/**
sonar.language=py
sonar.python.coverage.reportPaths=coverage.xml
sonar.qualitygate.wait=trueCI Integration
# GitHub Actions
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@master
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- name: Quality Gate
uses: sonarsource/sonarqube-quality-gate-action@master
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}Language-Specific Tools
Python (Bandit)
# Install
pip install bandit
# Run scan
bandit -r src/ -f json -o bandit-report.json
# With configuration
bandit -r src/ -c bandit.yaml# bandit.yaml
skips: ['B101', 'B601']
exclude_dirs: ['tests', 'venv']
assert_used:
skips: ['*_test.py', '*_tests.py']JavaScript (ESLint Security)
# Install
npm install eslint eslint-plugin-security --save-dev// .eslintrc.js
module.exports = {
plugins: ['security'],
extends: ['plugin:security/recommended'],
rules: {
'security/detect-object-injection': 'error',
'security/detect-non-literal-regexp': 'warn',
'security/detect-unsafe-regex': 'error',
'security/detect-buffer-noassert': 'error',
'security/detect-eval-with-expression': 'error',
'security/detect-no-csrf-before-method-override': 'error',
'security/detect-possible-timing-attacks': 'warn'
}
};Ruby (Brakeman)
# Install
gem install brakeman
# Run scan
brakeman -o brakeman-report.json -f json
# CI configuration
brakeman --no-exit-on-warn --no-exit-on-error -o report.htmlQuality Gates
SonarQube Quality Gate
{
"name": "Security Gate",
"conditions": [
{
"metric": "new_security_rating",
"op": "GT",
"error": "1"
},
{
"metric": "new_vulnerabilities",
"op": "GT",
"error": "0"
},
{
"metric": "new_security_hotspots_reviewed",
"op": "LT",
"error": "100"
}
]
}Custom Gate Script
#!/bin/bash
# security-gate.sh
CRITICAL=$(cat results.json | jq '[.results[] | select(.severity == "critical")] | length')
HIGH=$(cat results.json | jq '[.results[] | select(.severity == "high")] | length')
echo "Critical: $CRITICAL, High: $HIGH"
if [ "$CRITICAL" -gt 0 ]; then
echo "FAILED: Critical vulnerabilities found"
exit 1
fi
if [ "$HIGH" -gt 5 ]; then
echo "FAILED: Too many high severity vulnerabilities"
exit 1
fi
echo "PASSED: Security gate"
exit 0Common Issues
Issue: Too Many False Positives
Problem: Alerts on safe code patterns Solution: Tune rules, add suppressions, use baseline
Issue: Slow Scans
Problem: SAST taking too long in CI Solution: Incremental scanning, parallel execution, exclude test files
Issue: Missing Coverage
Problem: Vulnerabilities not detected Solution: Add custom rules, combine multiple tools
Best Practices
- Run on every PR/commit
- Establish baseline for existing code
- Prioritize by severity and exploitability
- Maintain custom rules for your codebase
- Integrate with IDE for early feedback
- Track trends over time
- Document false positive suppressions
- Combine with DAST for comprehensive coverage
Related Skills
- dast-scanning - Dynamic testing
- dependency-scanning - Dependency vulnerabilities
- github-actions - CI integration
SAST Tools Reference
Tool Comparison
| Tool | Languages | License | CI Integration |
|---|---|---|---|
| Semgrep | 30+ | LGPL/Commercial | Excellent |
| SonarQube | 30+ | LGPL/Commercial | Excellent |
| CodeQL | 10+ | MIT | GitHub native |
| Bandit | Python | Apache 2.0 | Good |
| ESLint Security | JavaScript | MIT | Good |
| Brakeman | Ruby | MIT | Good |
Semgrep
# Install
pip install semgrep
# Scan with default rules
semgrep --config auto .
# Scan with specific ruleset
semgrep --config p/owasp-top-ten .
semgrep --config p/security-audit .
# Output JSON
semgrep --config auto --json -o results.json .Custom Rules
rules:
- id: sql-injection
patterns:
- pattern: |
$QUERY = "..." + $INPUT + "..."
- metavariable-regex:
metavariable: $QUERY
regex: (?i)(select|insert|update|delete)
message: "Potential SQL injection"
severity: ERROR
languages: [python]SonarQube
# Scanner CLI
sonar-scanner \
-Dsonar.projectKey=myproject \
-Dsonar.sources=src \
-Dsonar.host.url=http://sonarqube:9000 \
-Dsonar.token=$SONAR_TOKENQuality Gate
# sonar-project.properties
sonar.projectKey=myproject
sonar.sources=src
sonar.tests=tests
sonar.coverage.exclusions=**/test/**
sonar.qualitygate.wait=trueCodeQL
# .github/workflows/codeql.yml
- uses: github/codeql-action/init@v2
with:
languages: javascript, python
- uses: github/codeql-action/analyze@v2Bandit (Python)
# Run scan
bandit -r ./src -f json -o bandit-report.json
# With severity filter
bandit -r ./src -ll # Medium and aboveESLint Security
// .eslintrc
{
"plugins": ["security"],
"extends": ["plugin:security/recommended"]
}CI Integration
# GitHub Actions
- name: Run Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: p/security-auditRelated skills
FAQ
Which SAST tools does it cover?
Semgrep, CodeQL, SonarQube, plus Bandit for Python and Brakeman for Rails.
Can it write custom rules?
Yes, it shows custom Semgrep rules and CodeQL queries for patterns like SQL injection and hardcoded passwords.