Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
148 changes: 148 additions & 0 deletions .github/workflows/security-gates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Security gates — MANDATORY, BLOCKING.
#
# Every job here is a required status check on `main` (see
# scripts/ci/enforce-quality-gates.sh). None of these jobs may use
# `continue-on-error` or `allow_failure` semantics: a finding either gets
# fixed, or gets an explicit reviewed suppression in-repo
# (.trivyignore / .semgrepignore / audit.toml). Silent bypass is not a state.
Comment thread
SharedQA marked this conversation as resolved.
Resolved
#
# Rationale: both company reference pipelines (gitlab.constr.dev 931666,
# 929528) carry Trivy scans with allow_failure that have been red for days.
# The Constructor/Virtuozzo CI/CD Master Plan §2 mandates hard-fail gates.
#
# All third-party actions and the SAST container image are pinned to immutable
# commit SHAs / digests (supply-chain hygiene — this gate practises what it preaches).

name: Security Gates

on:
pull_request:
branches: [main]
workflow_dispatch:
schedule:
# Nightly deep sweep (full history / full repo), per Master Plan §2:
# PR runs scan only the diff; the cron run scans everything.
- cron: "0 1 * * *"

permissions:
contents: read

concurrency:
group: security-gates-${{ github.ref }}
cancel-in-progress: true

jobs:
secrets-scan:
name: secrets-scan
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
# PR: fetch enough history to diff base..head. Cron: full history.
# String operands: numeric 0 is falsy in &&/|| so it would collapse to 50.
fetch-depth: ${{ github.event_name == 'schedule' && '0' || '50' }}
Comment thread
SharedQA marked this conversation as resolved.
Resolved
persist-credentials: false
- name: TruffleHog (verified secrets are a hard failure)
uses: trufflesecurity/trufflehog@1aa1871f9ae24a8c8a3a48a9345514acf42beb39 # v3.82.13
with:
base: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || '' }}
head: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || '' }}
extra_args: --results=verified,unknown

sast:
name: sast
runs-on: ubuntu-latest
timeout-minutes: 20
container:
image: semgrep/semgrep:1.131.0@sha256:6bd07d7b166b097e1384f41b94a62d8c8a26a4fff8713992c296e053310da01f
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Semgrep scan (report-only — ratchet to blocking once baseline triaged)
# report-only during ratchet-in: p/default surfaces pre-existing findings (JWT ValidateLifetime,
# Dockerfile USER, …) tracked in TAF for owner triage. Re-add --error to block once the baseline is clean.
run: semgrep scan --config p/default --exclude-rule generic.secrets.security.detected-generic-secret

deps-audit:
name: deps-audit
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Install cargo-audit
uses: taiki-e/install-action@375e0c7f08a66b8c2ba7e7eef31a6f91043a81b0 # v2.44.38
with:
tool: cargo-audit@0.22.2 # >=0.22 parses CVSS 4.0 advisories (RUSTSEC-2026-0124)
- name: Rust dependency audit (RUSTSEC advisories block)
working-directory: src/backend
# Waivers tracked in constructorfabric/insight#1339 — remove each as it is fixed:
# RUSTSEC-2023-0071 (rsa "Marvin", no upstream fix), RUSTSEC-2024-0436 (paste),
# RUSTSEC-2026-0173 (proc-macro-error2) — last two unmaintained, all transitive.
run: cargo audit --deny warnings --ignore RUSTSEC-2023-0071 --ignore RUSTSEC-2024-0436 --ignore RUSTSEC-2026-0173
- name: Set up Python
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
with:
python-version: "3.12"
- name: Python dependency audit (known CVEs block)
run: |
pip install --quiet 'pip-audit==2.10.1'
rc=0
# Transitive advisories we cannot fix from here — same suppression
# policy as the Rust audit above (fix, or tracked in-repo waiver).
# Every connector depends on airbyte-cdk (>=7.23.1,<8.0.0), whose
# latest 7.x (7.23.2) HARD-PINS nltk==3.9.1 and caps cryptography
# <47.0.0, so the upstream fixes (nltk 3.9.4, cryptography 48.0.1) are
# unreachable until airbyte-cdk bumps them. Waivers tracked in
# constructorfabric/insight#1339 — remove each as the CDK fixes it.
IGNORES=(
# nltk 3.9.1 (airbyte-cdk pin: nltk==3.9.1)
--ignore-vuln PYSEC-2026-96
--ignore-vuln PYSEC-2026-97
--ignore-vuln PYSEC-2026-98
--ignore-vuln PYSEC-2026-99
--ignore-vuln GHSA-rf74-v2fm-23pw
--ignore-vuln CVE-2026-33230
--ignore-vuln CVE-2026-33231
# cryptography 46.0.7 (airbyte-cdk cap: cryptography<47.0.0)
--ignore-vuln GHSA-537c-gmf6-5ccf
)
# Audit every Python project manifest in the ingestion tree.
while IFS= read -r f; do
echo "::group::pip-audit $f"
case "$f" in
*requirements*.txt) pip-audit "${IGNORES[@]}" -r "$f" || rc=1 ;;
*pyproject.toml) (cd "$(dirname "$f")" && pip-audit "${IGNORES[@]}" .) || rc=1 ;;
esac
echo "::endgroup::"
done < <(find src/ingestion -name 'pyproject.toml' -o -name 'requirements*.txt' | grep -v node_modules)
exit $rc
Comment thread
SharedQA marked this conversation as resolved.
Resolved

trivy-config:
name: trivy-config
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: Trivy IaC & Dockerfile misconfiguration scan (CRITICAL/HIGH block)
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: config
scan-ref: .
severity: CRITICAL,HIGH
exit-code: "1"
trivyignores: .trivyignore
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
- name: Trivy filesystem vulnerability scan (CRITICAL/HIGH block)
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
with:
scan-type: fs
scan-ref: .
severity: CRITICAL,HIGH
exit-code: "1"
ignore-unfixed: true
trivyignores: .trivyignore
7 changes: 7 additions & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Documented trivy-config waivers — tracked in constructorfabric/insight#1340.
# The gate stays blocking for every other misconfiguration class; remove each
# line as the underlying issue is fixed.
AVD-DS-0002 # container runs as root — build/test/tooling images
AVD-DS-0029 # apt-get without --no-install-recommends — toolbox build image
AVD-KSV-0118 # frontend Deployment missing securityContext — prod hardening backlog
AVD-KSV-0014 # frontend Deployment root FS not read-only — prod hardening backlog
Loading