Skip to content

Implement M44: Auditability and documentation hardening #65

Implement M44: Auditability and documentation hardening

Implement M44: Auditability and documentation hardening #65

Workflow file for this run

name: CI
on:
push:
branches: [main]
paths-ignore:
- "**.md"
pull_request:
paths-ignore:
- "**.md"
workflow_dispatch:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
# Minimal permissions by default
permissions:
contents: read
jobs:
go-build-and-test:
name: Go Build & Test
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
matrix:
service: [airlock, registry, tool-firewall, gpu-integrity-watch, mcp-firewall, policy-engine, runtime-attestor, integrity-monitor, incident-recorder]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: "1.23"
cache-dependency-path: services/${{ matrix.service }}/go.sum
- name: Build
working-directory: services/${{ matrix.service }}
run: CGO_ENABLED=0 go build -ldflags="-s -w" -o /dev/null .
- name: Test
working-directory: services/${{ matrix.service }}
run: go test -v -race -count=1 ./...
- name: Vet
working-directory: services/${{ matrix.service }}
run: go vet ./...
python-test:
name: Python Test & Lint
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
- name: Install dependencies
run: pip install pyyaml flask requests pytest
- name: Lint (syntax check)
run: |
python -m py_compile services/ui/ui/app.py
python -m py_compile services/diffusion-worker/app.py
python -m py_compile services/common/audit_chain.py
python -m py_compile services/common/auth.py
python -m py_compile services/common/mlock_helper.py
python -m py_compile services/agent/agent/app.py
python -m py_compile services/agent/agent/models.py
python -m py_compile services/agent/agent/policy.py
python -m py_compile services/agent/agent/planner.py
python -m py_compile services/agent/agent/executor.py
python -m py_compile services/agent/agent/storage.py
python -m py_compile services/agent/agent/capabilities.py
python -m py_compile services/agent/agent/sandbox.py
- name: Test
env:
PYTHONPATH: services
run: python -m pytest tests/ -v
shellcheck:
name: Shell Script Lint
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Lint shell scripts
run: |
shellcheck -s bash \
files/system/usr/libexec/secure-ai/*.sh \
files/scripts/build-services.sh \
files/scripts/generate-mok.sh
policy-validate:
name: Validate YAML configs
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
- name: Install pyyaml
run: pip install pyyaml
- name: Validate YAML files
run: |
python -c "
import yaml, sys, glob
errors = 0
for pattern in ['files/system/etc/secure-ai/**/*.yaml', 'recipes/*.yml']:
for f in glob.glob(pattern, recursive=True):
try:
with open(f) as fh:
yaml.safe_load(fh)
print(f'OK: {f}')
except Exception as e:
print(f'FAIL: {f}: {e}')
errors += 1
sys.exit(errors)
"
check-pins:
name: Verify action pins
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- run: bash .github/scripts/check-action-pins.sh
supply-chain-verify:
name: Supply Chain & SBOM Verification
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: "1.23"
- name: Install Syft (SBOM generator)
run: curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
- name: Install cosign (signing & attestation)
run: |
COSIGN_VERSION="v2.4.3"
curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64" \
-o /usr/local/bin/cosign
chmod +x /usr/local/bin/cosign
- name: Verify SBOM generation (Go services)
run: |
echo "=== SBOM generation verification ==="
for svc in airlock registry tool-firewall gpu-integrity-watch mcp-firewall \
policy-engine runtime-attestor integrity-monitor incident-recorder; do
echo "--- ${svc} ---"
syft dir:services/${svc} -o cyclonedx-json=/dev/null
echo "OK: ${svc} SBOM generated"
done
- name: Verify SBOM generation (Python services)
run: |
for svc in agent ui quarantine common diffusion-worker search-mediator; do
if [ -d "services/${svc}" ]; then
syft dir:services/${svc} -o cyclonedx-json=/dev/null
echo "OK: ${svc} SBOM generated"
fi
done
- name: Verify cosign is functional
run: |
cosign version
echo "OK: cosign available for signing and attestation"
- name: Verify release workflow has provenance steps
run: |
echo "=== Checking release.yml provenance pipeline ==="
# Verify release workflow exists and contains required supply-chain steps
test -f .github/workflows/release.yml || { echo "FAIL: release.yml missing"; exit 1; }
for keyword in "sbom-action" "attest-build-provenance" "cosign" "cyclonedx" "SHA256SUMS"; do
grep -q "${keyword}" .github/workflows/release.yml || \
{ echo "FAIL: release.yml missing '${keyword}'"; exit 1; }
echo "OK: release.yml contains '${keyword}'"
done
# Verify build workflow has SBOM attestation
test -f .github/workflows/build.yml || { echo "FAIL: build.yml missing"; exit 1; }
for keyword in "sbom-action" "cosign attest" "cyclonedx"; do
grep -q "${keyword}" .github/workflows/build.yml || \
{ echo "FAIL: build.yml missing '${keyword}'"; exit 1; }
echo "OK: build.yml contains '${keyword}'"
done
echo "=== Supply chain verification passed ==="
security-regression:
name: Security Regression Tests
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: "1.23"
- name: Install Python dependencies
run: pip install pyyaml flask requests pytest
- name: Run adversarial Python tests
run: python -m pytest tests/test_adversarial.py -v --tb=short
- name: Run MCP firewall adversarial tests
working-directory: services/mcp-firewall
run: go test -v -race -run TestAdversarial ./...
- name: Run policy-engine adversarial tests
working-directory: services/policy-engine
run: go test -v -race -run TestAdversarial ./...
- name: Run incident-recorder recovery tests
working-directory: services/incident-recorder
run: go test -v -race -run "TestRecovery|TestEscalation|TestForensic|TestLatched" ./...
test-count-check:
name: Test Count Drift Check
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0
with:
go-version: "1.23"
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: "3.12"
- name: Install Python dependencies
run: pip install pyyaml flask requests pytest
- name: Check test counts for drift
run: bash .github/scripts/check-test-counts.sh