feat: enforce live supply chain provenance gates

This commit is contained in:
thanhnv
2026-07-10 16:47:45 +09:00
parent aa284e9bd4
commit 040af64191
8 changed files with 351 additions and 0 deletions
+97
View File
@@ -0,0 +1,97 @@
name: CASAN Supply Chain and Provenance
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
verify-scan-attest:
runs-on: ci-runner
timeout-minutes: 60
env:
CASAN_CI_RUN_FRONTEND: "1"
CASAN_CI_RUN_BACKEND: "1"
CASAN_CI_RUN_INFRA_LAB: "0"
CASAN_REQUIRE_LIVE_SCANNERS: "1"
CASAN_TOOLCHAIN_TRUSTED_DIRS: /usr/bin:/bin:/usr/local/bin
steps:
- name: Checkout full signed history
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Verify trusted toolchain
run: |
set -euo pipefail
bash packages/casan-harness/scripts/bash/toolchain-verify.sh npm osv-scanner trivy docker openssl python3 git
- name: Enforce signed commits on main
if: github.ref == 'refs/heads/main'
run: |
set -euo pipefail
RANGE="${{ github.event.before }}..${{ github.sha }}"
if [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then RANGE="${{ github.sha }}"; fi
bash packages/casan-harness/scripts/bash/verify-signed-commits.sh "$RANGE"
- name: Install locked dependencies
run: npm ci
- name: Run governed test gate
run: bash packages/casan-harness/scripts/bash/ci-harness-gate.sh
- name: Build immutable candidate images
run: |
set -euo pipefail
docker build --pull -t casan-control-panel-api:${GITHUB_SHA} -f Dockerfile.control-panel-api .
docker build --pull -t casan-control-panel-ui:${GITHUB_SHA} -f Dockerfile.control-panel-ui .
- name: Live CVE, secret and misconfiguration scan
run: |
set -euo pipefail
mkdir -p dist/security
bash packages/casan-harness/scripts/bash/live-supply-chain-scan.sh dist/security \
casan-control-panel-api:${GITHUB_SHA} casan-control-panel-ui:${GITHUB_SHA}
- name: Push scanned images by immutable digest (main only)
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
CASAN_REGISTRY: ${{ vars.CASAN_REGISTRY }}
run: |
set -euo pipefail
[ -n "${GITEA_TOKEN:-}" ] || { echo 'missing GITEA_TOKEN'; exit 1; }
REGISTRY="${CASAN_REGISTRY:-${GITHUB_SERVER_URL#https://}}"
API_IMAGE="$REGISTRY/${GITHUB_REPOSITORY_OWNER}/casan-control-panel-api:${GITHUB_SHA}"
UI_IMAGE="$REGISTRY/${GITHUB_REPOSITORY_OWNER}/casan-control-panel-ui:${GITHUB_SHA}"
printf '%s' "$GITEA_TOKEN" | docker login "$REGISTRY" -u "$GITHUB_ACTOR" --password-stdin
docker tag casan-control-panel-api:${GITHUB_SHA} "$API_IMAGE"
docker tag casan-control-panel-ui:${GITHUB_SHA} "$UI_IMAGE"
docker push "$API_IMAGE"; docker push "$UI_IMAGE"
docker image inspect --format '{{index .RepoDigests 0}}' "$API_IMAGE" > dist/security/api-image.digest
docker image inspect --format '{{index .RepoDigests 0}}' "$UI_IMAGE" > dist/security/ui-image.digest
- name: Sign SLSA provenance (main only)
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
env:
CASAN_ATTESTATION_PRIVATE_KEY: ${{ secrets.CASAN_ATTESTATION_PRIVATE_KEY }}
run: |
set -euo pipefail
[ -n "${CASAN_ATTESTATION_PRIVATE_KEY:-}" ] || { echo 'missing CASAN_ATTESTATION_PRIVATE_KEY'; exit 1; }
key="$(mktemp)"; trap 'rm -f "$key"' EXIT
printf '%s\n' "$CASAN_ATTESTATION_PRIVATE_KEY" > "$key"; chmod 600 "$key"
mapfile -t images < <(cat dist/security/api-image.digest dist/security/ui-image.digest)
bash packages/casan-harness/scripts/bash/release-provenance.sh create \
dist/security/provenance.intoto.json "$key" dist/security/npm.cyclonedx.json \
docs/output/casan/evidence/harness-test-report.md "${images[@]}"
openssl pkey -in "$key" -pubout -out dist/security/provenance-public.pem
- name: Upload security evidence and provenance
if: always()
uses: actions/upload-artifact@v4
with:
name: casan-security-${{ github.sha }}
path: dist/security/
retention-days: 90