CI Integration
Wire scan4secrets into your pipeline. Three patterns: pre-commit, on-PR scan, scheduled DAST.
pre-commit
.pre-commit-hooks.yaml ships in the repo. Add to your project:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/m14r41/scan4secrets
rev: v2.1.0
hooks:
- id: scan4secrets
Then:
pre-commit install
pre-commit run --all-files
GitHub Actions. SAST + SARIF upload
# .github/workflows/secrets.yml
name: Secret scan
on:
push:
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.12' }
- run: pip install git+https://github.com/m14r41/scan4secrets
- name: scan4secrets
run: |
scan4secrets --path . \
--report sarif json \
--fail-on high \
--output reports/scan
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: reports/scan.sarif
- name: Archive JSON
if: always()
uses: actions/upload-artifact@v4
with:
name: scan4secrets-report
path: reports/
GitHub Actions. Secrets + vulnerabilities (SAST --misconfig)
Scan for both secrets and code vulnerabilities/misconfigurations so vulnerability findings (with CWE and OWASP mappings) also land in your code-scanning dashboard.
# .github/workflows/sast.yml
name: SAST secrets + vulns
on:
push:
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.12' }
- run: pip install git+https://github.com/m14r41/scan4secrets
- name: scan4secrets (secrets + misconfig)
run: |
scan4secrets --path . \
--misconfig \
--report sarif \
--fail-on high \
--output results
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
Use --misconfig-only to scan for vulnerabilities/misconfigurations without secret detection.
GitHub Actions. Scheduled DAST on staging
# .github/workflows/dast.yml
name: DAST secret sweep
on:
schedule: [{ cron: '0 6 * * *' }] # daily 06:00 UTC
workflow_dispatch:
jobs:
dast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.12' }
- run: pip install git+https://github.com/m14r41/scan4secrets
- name: Scan staging
env:
STAGING_COOKIE: ${{ secrets.STAGING_COOKIE }}
run: |
scan4secrets --url https://staging.example.com \
--cookie "$STAGING_COOKIE" \
--verify \
--report html sarif jsonl \
--fail-on medium \
--output reports/dast
- uses: actions/upload-artifact@v4
if: always()
with: { name: dast-report, path: reports/ }
GitLab CI
# .gitlab-ci.yml
secret-scan:
image: python:3.12-slim
stage: test
script:
- pip install git+https://github.com/m14r41/scan4secrets
- scan4secrets --path . --report sarif json --fail-on high --output reports/scan
artifacts:
when: always
paths: [ reports/ ]
reports:
sast: reports/scan.sarif
Jenkins (declarative)
pipeline {
agent { docker { image 'python:3.12-slim' } }
stages {
stage('Scan') {
steps {
sh 'pip install git+https://github.com/m14r41/scan4secrets'
sh 'scan4secrets --path . --report sarif json --fail-on high --output reports/scan'
}
}
}
post {
always { archiveArtifacts artifacts: 'reports/**', allowEmptyArchive: true }
}
}
Docker in CI
docker run --rm -v "$PWD:/scan" ghcr.io/m14r41/scan4secrets:latest \
--path /scan --report sarif --fail-on high --output /scan/reports/scan