chore: add CVE audit skill and scheduled GitLab CI jobs (#704)
Closes #704 (closed)
Adds a CVE audit protocol with two entry points:
- local:
/cve-auditslash command (.claude/commands/cve-audit.md). runs the three scanners, writes artifacts tocve-reports/, producesSUMMARY.mdwith fixable vs unfixed CRITICAL/HIGH grouped by remediation. - CI: new
.gitlab-ci-security.yml, included from root.gitlab-ci.yml. four jobs in asecuritystage (govulncheck, pnpm-audit, trivy-image, summary). gated onSECURITY_AUDIT=1so it only runs on dedicated schedules or manual triggers.
Files
.claude/commands/cve-audit.md(new) — local skill.gitlab-ci-security.yml(new) — CI jobs.gitlab-ci.yml— include the security file withinclude:rules:gated onSECURITY_AUDIT.gitignore— excludecve-reports/and.trivycache/ui/.gitlab-ci.yml,ui/packages/ce/.gitlab-ci.yml,ui/packages/shared/.gitlab-ci.yml— see UI CI cleanup below
UI CI cleanup (bundled)
.ui_checks, .only_ui_feature, and .only_ui_master had no changes: filter, so UI build, lint, and e2e jobs ran on every MR regardless of diff. Added changes: ui/**/* guards to mirror engine's .only_engine pattern. After merge, MRs that don't touch ui/** will skip UI jobs.
Run locally
prereqs: govulncheck, pnpm, trivy, jq
- build the image once:
cd engine && make build-image(tagsdblab_server:local) - in Claude Code:
/cve-audit(or/cve-audit some-image:tag) - report at
cve-reports/SUMMARY.md; raw JSON/text artifacts alongside
sample on current master:
- trivy: 5 CRITICAL / 40 HIGH / 91 MEDIUM
- govulncheck: 7 called / 13 imported
- pnpm audit: 1 moderate
- 0 unfixed CRITICAL/HIGH in the image — all findings have upstream fixes
Set up on CI
- Settings → CI/CD → Schedules → New schedule
- cron (UTC): e.g.
0 3 * * 1(Mondays 03:00 UTC) - variables:
SECURITY_AUDIT=1(required — gates all security jobs)- optional:
CVE_SCAN_IMAGE=registry.gitlab.com/postgres-ai/database-lab/dblab-server:master(default) or another tag
artifacts retained: 90 days for raw scans, 365 days for SUMMARY.md (for trend/diff).
Notes
- trivy pulls from GitLab registry via
\$CI_REGISTRY_USER/PASSWORD(in-scope for CI jobs). - scanner jobs are
allow_failure: true— a registry blip or single scanner error won't break the pipeline. - follow-ups (not here): auto-open issues on new CRITICAL; extend to
dblab-rds-refresh,dblab-ci-checker,dblab-clientimages.
Edited by Artyom Kartasov