feat: enforce live supply chain provenance gates
This commit is contained in:
@@ -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
|
||||
Reference in New Issue
Block a user