Skip to content

chore(security): extend license allowlist with BSL-1.0, CC0-1.0, 0BSD #10

chore(security): extend license allowlist with BSL-1.0, CC0-1.0, 0BSD

chore(security): extend license allowlist with BSL-1.0, CC0-1.0, 0BSD #10

Workflow file for this run

name: security
# Supply-chain and license-policy gate for quantcli repos.
# Source of truth lives in quantcli/common; export-clis carry a copy of this file.
# When updating, propagate the change to every *-export-cli repo (see CONTRIBUTING.md).
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
# Default-deny at workflow level; each job re-grants only what it needs.
permissions: {}
jobs:
govulncheck:
name: govulncheck (Go vuln DB)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Detect Go module
id: detect
run: |
if [ -f go.mod ]; then
echo "has_go=true" >> "$GITHUB_OUTPUT"
else
echo "has_go=false" >> "$GITHUB_OUTPUT"
echo "::notice::No go.mod present; skipping govulncheck."
fi
- name: Set up Go
if: steps.detect.outputs.has_go == 'true'
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version-file: go.mod
cache: true
- name: Install govulncheck
if: steps.detect.outputs.has_go == 'true'
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run govulncheck
if: steps.detect.outputs.has_go == 'true'
run: govulncheck ./...
osv-scanner:
name: osv-scanner (transitive vulns)
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Detect Go module
id: detect
run: |
# osv-scanner exits non-zero with "No package sources found" if there is
# nothing to scan. The quantcli org is Go-only today, so gate on go.mod.
# If a non-Go manifest (package.json, requirements.txt, Cargo.toml, …) is
# ever introduced, broaden this check.
if [ -f go.mod ]; then
echo "has_manifests=true" >> "$GITHUB_OUTPUT"
else
echo "has_manifests=false" >> "$GITHUB_OUTPUT"
echo "::notice::No go.mod found; skipping osv-scanner."
fi
- name: Set up Go
if: steps.detect.outputs.has_manifests == 'true'
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version: stable
cache: false
- name: Install osv-scanner
if: steps.detect.outputs.has_manifests == 'true'
run: go install github.com/google/osv-scanner/v2/cmd/osv-scanner@latest
- name: Run osv-scanner
if: steps.detect.outputs.has_manifests == 'true'
run: osv-scanner scan source --recursive .
license-policy:
name: license policy (allowlist)
runs-on: ubuntu-latest
permissions:
contents: read
env:
# Policy: every direct + transitive Go dep must resolve to one of these SPDX ids.
# Keep this list sorted by SPDX id; SECURITY.md "License allowlist" must match exactly.
# See SECURITY.md "Supply-chain policy" for the rationale.
ALLOWED_LICENSES: "0BSD,Apache-2.0,BSD-2-Clause,BSD-3-Clause,BSL-1.0,CC0-1.0,ISC,MIT,MPL-2.0,Unlicense"
steps:
- name: Checkout
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
- name: Detect Go module
id: detect
run: |
if [ -f go.mod ]; then
echo "has_go=true" >> "$GITHUB_OUTPUT"
else
echo "has_go=false" >> "$GITHUB_OUTPUT"
echo "::notice::No go.mod present; skipping license-policy check."
fi
- name: Set up Go
if: steps.detect.outputs.has_go == 'true'
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
with:
go-version-file: go.mod
cache: true
- name: Install go-licenses
if: steps.detect.outputs.has_go == 'true'
run: go install github.com/google/go-licenses@latest
- name: Check licenses against allowlist
if: steps.detect.outputs.has_go == 'true'
shell: bash
run: |
set -euo pipefail
report=$(mktemp)
# go-licenses csv emits: module,license-url,license-id (one per line).
# Warnings (e.g. license-url not found) go to stderr and are non-fatal here.
go-licenses csv ./... > "$report"
IFS=',' read -ra ALLOWED <<< "$ALLOWED_LICENSES"
is_allowed() {
local needle="$1"
for a in "${ALLOWED[@]}"; do
if [ "$needle" = "$a" ]; then return 0; fi
done
return 1
}
bad=0
while IFS=',' read -r module url license; do
[ -z "$module" ] && continue
if ! is_allowed "$license"; then
echo "::error::Disallowed license: module=$module license=$license"
bad=1
fi
done < "$report"
if [ "$bad" -ne 0 ]; then
echo "::error::License policy violated. Allowlist: ${ALLOWED_LICENSES}"
echo "::error::See SECURITY.md for the policy and how to request an exception."
exit 1
fi
echo "All dependency licenses are within policy."