Skip to content
Open

commit #4794

Show file tree
Hide file tree
Changes from all 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
93 changes: 93 additions & 0 deletions .github/workflows/deploy-stone-technology-fabric.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
name: Deploy Stone technology fabric to fanz-global

on:
push:
branches: [main]
paths:
- ".github/workflows/deploy-stone-technology-fabric.yml"
workflow_dispatch:
inputs:
stone_sha:
description: "Exact FanzCEO/StoneAiOmniRoute SHA"
required: false
default: "10f65fa6b38b00d97961ab38f07e0c4db8a48833"

permissions:
contents: read

concurrency:
group: deploy-stone-technology-fabric
cancel-in-progress: false

jobs:
deploy:
name: Exact-SHA deploy and verify
runs-on: self-hosted
timeout-minutes: 90
env:
STONE_SHA: ${{ inputs.stone_sha || '10f65fa6b38b00d97961ab38f07e0c4db8a48833' }}
STONE_REPO: https://github.com/FanzCEO/StoneAiOmniRoute.git
steps:
- name: Preflight deployment channel
shell: bash
run: |
set -euo pipefail
echo "Runner: $(hostname)"
echo "Stone SHA: $STONE_SHA"
command -v git >/dev/null
command -v curl >/dev/null

if ssh -o BatchMode=yes -o ConnectTimeout=8 fanz-global 'printf reachable' 2>/dev/null | grep -q reachable; then
echo "mode=ssh" >> "$GITHUB_ENV"
echo "Deployment target reachable through ssh alias fanz-global."
elif [ "$(hostname -s)" = "server" ] || [ "$(hostname -s)" = "fanz-global" ]; then
echo "mode=local" >> "$GITHUB_ENV"
echo "Runner appears to be the deployment target."
else
echo "::error::Self-hosted runner cannot reach fanz-global and is not the target host."
exit 70
fi

- name: Deploy exact Stone fork revision
shell: bash
run: |
set -euo pipefail

deploy_cmd='set -euo pipefail
export STONE_OMNIROUTE_REPO_URL="https://github.com/FanzCEO/StoneAiOmniRoute.git"
export STONE_OMNIROUTE_SHA="'"$STONE_SHA"'"
export STONE_DEPLOY_ROOT="$HOME/.stone/omniroute"
tmp="$(mktemp -d)"
trap '\''rm -rf "$tmp"'\'' EXIT
git clone -q --filter=blob:none --no-checkout "$STONE_OMNIROUTE_REPO_URL" "$tmp/repo"
git -C "$tmp/repo" fetch -q --depth 1 origin "$STONE_OMNIROUTE_SHA"
git -C "$tmp/repo" checkout -q --detach FETCH_HEAD
test "$(git -C "$tmp/repo" rev-parse HEAD)" = "$STONE_OMNIROUTE_SHA"
bash "$tmp/repo/scripts/ops/deploy-stone-fork.sh"'

if [ "$mode" = "ssh" ]; then
ssh -o BatchMode=yes fanz-global "bash -lc $(printf '%q' "$deploy_cmd")"
else
bash -lc "$deploy_cmd"
fi

- name: Verify deployed SHA and live fabric
shell: bash
run: |
set -euo pipefail

verify_cmd='set -euo pipefail
test -f "$HOME/.stone/omniroute/DEPLOYED_SHA"
DEPLOYED="$(cat "$HOME/.stone/omniroute/DEPLOYED_SHA")"
test "$DEPLOYED" = "'"$STONE_SHA"'"
curl -fsS http://127.0.0.1:20128/api/health | grep -q '\''"status":"ok"'\''
FABRIC="$(curl -fsS http://127.0.0.1:20128/api/health/technology-fabric)"
printf "%s\n" "$FABRIC"
printf "%s" "$FABRIC" | grep -q '\''"authority":"stone"'\''
echo "DEPLOY_OK $DEPLOYED"'

if [ "$mode" = "ssh" ]; then
ssh -o BatchMode=yes fanz-global "bash -lc $(printf '%q' "$verify_cmd")"
else
bash -lc "$verify_cmd"
fi
118 changes: 118 additions & 0 deletions .github/workflows/supply-chain.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
name: FANZ Supply Chain (SBOM · Sign · License)

# FANZ software-supply-chain compliance workflow. Drop into each repo as
# .github/workflows/supply-chain.yml. Produces a CycloneDX + SPDX SBOM per build,
# submits it to the GitHub dependency graph, scans it for vulns (Grype), enforces a
# license policy, and cryptographically attests the SBOM (cosign keyless / SLSA-style).
# Standards: SPDX 2.3, CycloneDX 1.5, NIST SSDF (SP 800-218), EO 14028, DORA Art.28.

on:
push:
branches: [ main, master ]
release:
types: [ published ]
workflow_dispatch:

permissions:
contents: read
id-token: write # cosign keyless (OIDC)
security-events: write # dependency graph submission

jobs:
sbom:
name: Generate · scan · license · attest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

# ---- 1. Generate SBOMs (both standard formats) --------------------------
- name: Generate CycloneDX SBOM (Syft)
uses: anchore/sbom-action@v0
with:
format: cyclonedx-json
output-file: sbom.cdx.json
upload-artifact: false

- name: Generate SPDX SBOM (Syft)
uses: anchore/sbom-action@v0
with:
format: spdx-json
output-file: sbom.spdx.json
upload-artifact: false

# ---- 2. Feed the GitHub dependency graph (continuous inventory) ---------
- name: Submit SBOM to GitHub dependency graph
uses: advanced-security/spdx-dependency-submission-action@v0.1.1
continue-on-error: true
with:
filePath: sbom.spdx.json

# ---- 3. Vulnerability scan of the SBOM (Grype) -------------------------
- name: Scan SBOM for known vulnerabilities
uses: anchore/scan-action@v4
id: grype
with:
sbom: sbom.cdx.json
fail-build: false # report-only until backlog is triaged (ch.145 SLA governs)
severity-cutoff: high
output-format: sarif
- name: Upload vuln findings to code scanning
if: always()
uses: github/codeql-action/upload-sarif@v3
continue-on-error: true
with:
sarif_file: ${{ steps.grype.outputs.sarif }}

# ---- 4. License policy gate (FANZ banned/copyleft) --------------------
- name: Enforce license policy
run: |
echo "Checking component licenses against FANZ policy..."
BANNED='AGPL-3.0|AGPL-1.0|GPL-3.0|SSPL|Commons-Clause|BUSL'
# extract declared licenses from the CycloneDX SBOM
hits=$(node -e '
const b=require("./sbom.cdx.json");
const banned=/AGPL|SSPL|Commons-Clause|BUSL|GPL-3/i;
const bad=(b.components||[]).flatMap(c=>(c.licenses||[]).map(l=>({name:c.name,lic:(l.license&&(l.license.id||l.license.name))||l.expression||""})))
.filter(x=>banned.test(x.lic));
bad.forEach(x=>console.log(" BANNED-LICENSE: "+x.name+" -> "+x.lic));
console.log("count="+bad.length);
' 2>/dev/null | tail -20)
echo "$hits"
n=$(echo "$hits" | grep -oE 'count=[0-9]+' | cut -d= -f2)
if [ "${n:-0}" -gt 0 ]; then
echo "::warning::${n} components carry banned/copyleft licenses (see log). Fix or add a License-Waiver."
# switch to 'exit 1' to hard-block once the baseline is clean
fi

# ---- 5. Cryptographic attestation (provenance / integrity) ------------
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Attest SBOM (keyless, OIDC — SLSA-style)
run: |
cosign attest-blob --yes \
--predicate sbom.cdx.json \
--type cyclonedx \
--output-signature sbom.cdx.json.sig \
--output-certificate sbom.cdx.json.pem \
sbom.cdx.json || echo "::warning::cosign attestation skipped (non-release build)"

# ---- 6. Publish the SBOMs as durable artifacts ------------------------
- name: Upload SBOMs + attestation
uses: actions/upload-artifact@v4
with:
name: sbom-${{ github.sha }}
path: |
sbom.cdx.json
sbom.spdx.json
sbom.cdx.json.sig
sbom.cdx.json.pem
retention-days: 90

- name: Attach SBOMs to GitHub Release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: |
sbom.cdx.json
sbom.spdx.json
sbom.cdx.json.sig
Loading