mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 23:21:30 +00:00
95cb002905
Three findings from the certctl architecture diligence audit's Phase 1
bundle (Supply-Chain Hardening) closed together in one PR since they all
touch .github/workflows/ + repo root.
RED-1 — delete tracked precompiled binary
- deploy/test/f5-mock-icontrol/f5-mock-icontrol (8.6 MB ARM64 ELF) was
tracked alongside the Go source that builds it. The fixture's
Dockerfile already uses a multi-stage build that re-runs
'go build' inside the container (line 13), so the tracked binary
was vestigial — never actually consumed by the test wiring.
- git rm'd. Path added to .gitignore so it doesn't re-land.
- No Makefile target needed; the Dockerfile is the rebuild path.
RED-2 — SHA-pin every GitHub Action
- Pre: 37 of 41 'uses:' lines were tag-pinned (@v4 etc); only
4 were SHA-pinned (sigstore/cosign-installer + anchore/sbom-action).
- Post: 0 / 41. Every 'uses:' line is now '@<40-char-sha> # vN'
(the trailing comment preserves the human-readable version for
operator audit). SHA-pinning closes the standard supply-chain
attack vector against GitHub Actions consumers.
- SHAs resolved live via the GitHub API; spot-checked one.
TEST-L2 — npm audit hard gate
- Added 'npm audit --omit=dev --audit-level=high' step to the
Frontend Build job in ci.yml. --omit=dev excludes vitest/vite/
eslint/etc which don't ship to operators.
- Local run today: 0 vulnerabilities; gate enters with no triage
backlog. Catches future regressions.
New CI guards (regression-prevention):
- scripts/ci-guards/no-tag-pinned-actions.sh — fails the build if
a future PR adds 'uses: foo/bar@v2' instead of SHA-pinning.
- scripts/ci-guards/no-precompiled-binary.sh — runs file(1) over
git ls-files output; fails on any tracked ELF/Mach-O/PE.
- Both pass locally. CI's existing loop over scripts/ci-guards/*.sh
picks them up automatically.
Closes: cowork/certctl-architecture-diligence-audit.html#fix-RED-1,
cowork/certctl-architecture-diligence-audit.html#fix-RED-2,
cowork/certctl-architecture-diligence-audit.html#fix-TEST-L2
82 lines
3.3 KiB
YAML
82 lines
3.3 KiB
YAML
name: CodeQL
|
|
|
|
# Public-facing SAST baseline that complements the existing security-deep-scan
|
|
# workflow (gosec, osv-scanner, trivy, ZAP, semgrep, schemathesis, nuclei,
|
|
# testssl) with cross-file Go and JavaScript dataflow analysis. Results land
|
|
# in the repository's Security → Code scanning tab as a public signal — any
|
|
# operator/security team auditing certctl can see the scan history and
|
|
# triage state without asking.
|
|
#
|
|
# Why CodeQL in addition to gosec:
|
|
# - gosec is single-file pattern matching (catches obvious issues like
|
|
# `os/exec.Command(userInput)`); CodeQL does interprocedural taint
|
|
# tracking (catches the same issue when the userInput is laundered
|
|
# through several function calls or struct fields).
|
|
# - GitHub-native; no third-party SaaS license gate (works for BSL 1.1
|
|
# and other source-available licenses, unlike Aikido / Snyk / SonarCloud
|
|
# free tiers which require OSI-approved licenses).
|
|
# - SARIF results auto-deduplicate and persist on PRs, so reviewers see
|
|
# "this PR introduces N new findings" rather than re-running ad hoc.
|
|
#
|
|
# Findings that are intentional (e.g., the SSH connector's
|
|
# InsecureIgnoreHostKey, ACME DNS solver's intentional shell-out to operator-
|
|
# supplied scripts) get suppressed via inline `// codeql[<rule-id>]`
|
|
# comments OR via a `.github/codeql/codeql-config.yml` query-pack tweak —
|
|
# document the rationale in the same commit that adds the suppression so
|
|
# the public scan-tab readers see the threat-model justification.
|
|
|
|
on:
|
|
push:
|
|
branches: [master]
|
|
pull_request:
|
|
branches: [master]
|
|
schedule:
|
|
# Weekly Sunday 06:00 UTC, in addition to push/PR coverage. Catches
|
|
# rule-pack updates from CodeQL upstream (their Go/JS rulesets ship
|
|
# new queries on a roughly-monthly cadence).
|
|
- cron: '0 6 * * 0'
|
|
|
|
permissions:
|
|
contents: read
|
|
security-events: write # SARIF upload to GitHub code scanning
|
|
actions: read
|
|
|
|
jobs:
|
|
analyze:
|
|
name: Analyze (${{ matrix.language }})
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 30
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
language: [go, javascript-typescript]
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
|
|
- name: Set up Go
|
|
if: matrix.language == 'go'
|
|
uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5
|
|
with:
|
|
# Match ci.yml + release.yml + security-deep-scan.yml.
|
|
go-version: '1.25.10'
|
|
|
|
- name: Initialize CodeQL
|
|
uses: github/codeql-action/init@7fd177fa680c9881b53cdab4d346d32574c9f7f4 # v3
|
|
with:
|
|
languages: ${{ matrix.language }}
|
|
# Use the security-and-quality query suite — security finds plus
|
|
# maintainability/correctness issues that the smaller security-extended
|
|
# suite skips. Comparable scope to what Aikido / SonarCloud run.
|
|
queries: security-and-quality
|
|
|
|
- name: Autobuild
|
|
uses: github/codeql-action/autobuild@7fd177fa680c9881b53cdab4d346d32574c9f7f4 # v3
|
|
|
|
- name: Perform CodeQL Analysis
|
|
uses: github/codeql-action/analyze@7fd177fa680c9881b53cdab4d346d32574c9f7f4 # v3
|
|
with:
|
|
category: "/language:${{ matrix.language }}"
|
|
# SARIF upload is implicit (and is what populates the Security tab).
|