Security scanning (SAST, secrets, SCA)
Internal ops note — not linked from the public docs sidebar. Describes the Cirra AI security-scan stack for this repository.
docs uses the shared Cirra AI security-scan reusable workflow (private repos keep SARIF as artifacts; no GHAS required).
Severity model
| Tool | Critical / High (blocks PRs) | Medium (weekly tracker) | Low / info |
|---|---|---|---|
| Semgrep | ERROR, HIGH, or CRITICAL | WARNING / MEDIUM | INFO / LOW: ignore |
| gitleaks | every finding is Critical | n/a | n/a |
| OSV-Scanner | SARIF security-severity ≥ 7.0 | 4.0–6.9, or no score | < 4.0: ignore |
Trivy (config) | n/a (disabled for this repo) | n/a | n/a |
| njsscan | n/a (not enabled for this repo) | n/a | n/a |
Gates read the tool's JSON/SARIF output (not the tool exit code alone).
What runs
| Layer | Tool | Role |
|---|---|---|
| CI (PR) | Semgrep (diff-aware), gitleaks (PR commits), OSV (new highs only) | block new critical/high |
| CI (push / weekly) | Full Semgrep, full-history gitleaks, OSV | artifacts + tracker issues |
| GitHub | Dependabot (npm + Actions → main) | dependency CVEs + version bumps |
Semgrep packs: p/default p/secrets p/owasp-top-ten p/typescript p/react.
Trivy and njsscan are not enabled for this Docusaurus docs site.
Medium findings tracker
On push to main, schedule, and workflow_dispatch, the reusable workflow's
report job maintains:
Security scan: open medium findings(security-hygiene)Security scan: critical/high on main(security-high) when a full scan still finds gated severity
SARIF/JSON artifacts are retained 90 days (audit evidence). Private repos do not upload SARIF to the GitHub Security tab (GHAS required).
Suppressions
- Semgrep:
// nosemgrep: <full.rule.id> -- <reason>,.semgrepignore, or repo-level--exclude-rule(none currently). - gitleaks:
gitleaks:allowon the line; historical findings in.gitleaksignore(fingerprints). Real secrets stay commented until rotated.
Never suppress a finding you have not read.
Repo-level Semgrep --exclude-rule
None currently. Prefer a code fix or an inline nosemgrep with a reason.
gitleaks targetRules note
Rule-scoped allowlists (targetRules) are silently ignored by gitleaks
(https://github.com/gitleaks/gitleaks/issues/1919). This repo does not use
targetRules. Test/fixture fakes use gitleaks:allow or .gitleaksignore
fingerprints.
Local runs
pipx install "semgrep==1.168.0"
semgrep scan --config p/default --config p/typescript --config p/react \
--config p/secrets --config p/owasp-top-ten
# Secrets (full history)
gitleaks git --config .gitleaks.toml --redact
docker run --rm -v "$PWD:/repo" ghcr.io/google/osv-scanner:v2.4.0 \
scan source --recursive /repo
CI workflow
.github/workflows/security.yml calls the shared reusable workflow in
cirra-ai/processes (pinned by commit SHA). Scanner versions and gate logic
live there — see cirra-ai/processes/security/README.md.