ci: add semgrep SAST scanning to CI and pre-commit (#14964)

* ci: add semgrep SAST scanning to CI and pre-commit

Add semgrep static analysis to the security workflow and pre-commit
hooks. Uses `--config auto` for comprehensive coverage across Python,
Dockerfile, and GitHub Actions. The intentional `USER root` in the
Dockerfile (required for bind mount compatibility) is excluded via
`--exclude-rule`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci: pin semgrep container image to digest for zizmor

Pin semgrep/semgrep to sha256 digest (v1.151.0) to satisfy
zizmor's unpinned-images audit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* ci: add zizmor pre-commit hook for Actions security audit

Matches the existing actionlint pattern — gracefully skips if zizmor
is not installed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Dan Guido
2026-02-08 11:59:30 -05:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 984831bcab
commit bdc03d0a7f
3 changed files with 37 additions and 1 deletions
+16
View File
@@ -10,6 +10,22 @@ permissions:
contents: read contents: read
jobs: jobs:
semgrep:
name: Semgrep SAST
runs-on: ubuntu-22.04
container:
image: semgrep/semgrep@sha256:d3d1be3a3770514d16a6a57b9761575d7536d70f45a5220274f4ec7d55c442b9 # v1.151.0
steps:
- uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # v5.0.1
with:
persist-credentials: false
- name: Run semgrep
run: >
semgrep --config auto
--exclude-rule dockerfile.security.last-user-is-root.last-user-is-root
--error --quiet .
pip-audit: pip-audit:
name: Python dependency audit name: Python dependency audit
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04
+19
View File
@@ -76,6 +76,18 @@ repos:
files: 'main\.yml|server\.yml|users\.yml' files: 'main\.yml|server\.yml|users\.yml'
pass_filenames: false pass_filenames: false
- id: semgrep
name: Semgrep security scan
entry: >
bash -c '
command -v semgrep >/dev/null &&
semgrep --config auto
--exclude-rule dockerfile.security.last-user-is-root.last-user-is-root
--error --quiet --skip-unknown-extensions .
|| echo "semgrep not installed - skipping"'
language: system
pass_filenames: false
- id: actionlint - id: actionlint
name: GitHub Actions lint name: GitHub Actions lint
entry: bash -c 'command -v actionlint >/dev/null && actionlint .github/workflows/ || echo "actionlint not installed - skipping"' entry: bash -c 'command -v actionlint >/dev/null && actionlint .github/workflows/ || echo "actionlint not installed - skipping"'
@@ -83,6 +95,13 @@ repos:
files: '^\.github/workflows/.*\.yml$' files: '^\.github/workflows/.*\.yml$'
pass_filenames: false pass_filenames: false
- id: zizmor
name: GitHub Actions security audit
entry: bash -c 'command -v zizmor >/dev/null && zizmor .github/workflows/ || echo "zizmor not installed - skipping"'
language: system
files: '^\.github/workflows/.*\.yml$'
pass_filenames: false
# Configuration for prek # Configuration for prek
# Files to exclude globally # Files to exclude globally
+2 -1
View File
@@ -54,7 +54,7 @@ algo/
```bash ```bash
# Run the full lint suite (same as CI) # Run the full lint suite (same as CI)
ansible-lint . && yamllint . && ruff check . && shellcheck scripts/*.sh ansible-lint . && yamllint . && ruff check . && shellcheck scripts/*.sh && semgrep --config auto --exclude-rule dockerfile.security.last-user-is-root.last-user-is-root --error --quiet .
ansible-playbook main.yml --syntax-check ansible-playbook main.yml --syntax-check
ansible-playbook users.yml --syntax-check ansible-playbook users.yml --syntax-check
pytest tests/unit/ -q pytest tests/unit/ -q
@@ -101,6 +101,7 @@ When adding or modifying features, verify these before requesting review:
| `yamllint` | All YAML | Document start `---`, quote `'on':` in workflows | | `yamllint` | All YAML | Document start `---`, quote `'on':` in workflows |
| `ruff` | Python | Line length 120, target Python 3.11 | | `ruff` | Python | Line length 120, target Python 3.11 |
| `shellcheck` | Shell scripts | Quote variables, use `set -euo pipefail` | | `shellcheck` | Shell scripts | Quote variables, use `set -euo pipefail` |
| `semgrep` | All code | SAST scanner, `--config auto`, suppress with `# nosemgrep: rule-id` |
### Git Workflow ### Git Workflow