Files
git.stella-ops.org/.gitea/workflows/deploy-keyless-verify.yml
StellaOps Bot 907783f625 Add property-based tests for SBOM/VEX document ordering and Unicode normalization determinism
- Implement `SbomVexOrderingDeterminismProperties` for testing component list and vulnerability metadata hash consistency.
- Create `UnicodeNormalizationDeterminismProperties` to validate NFC normalization and Unicode string handling.
- Add project file for `StellaOps.Testing.Determinism.Properties` with necessary dependencies.
- Introduce CI/CD template validation tests including YAML syntax checks and documentation content verification.
- Create validation script for CI/CD templates ensuring all required files and structures are present.
2025-12-26 15:17:58 +02:00

205 lines
6.1 KiB
YAML

# .gitea/workflows/deploy-keyless-verify.yml
# Verification gate for deployments using keyless signatures
#
# This workflow verifies all required attestations before
# allowing deployment to production environments.
#
# Dogfooding the StellaOps keyless verification feature.
name: Deployment Verification Gate
on:
workflow_dispatch:
inputs:
image:
description: 'Image to deploy (with digest)'
required: true
type: string
environment:
description: 'Target environment'
required: true
type: choice
options:
- staging
- production
require_sbom:
description: 'Require SBOM attestation'
required: false
default: true
type: boolean
require_verdict:
description: 'Require policy verdict attestation'
required: false
default: true
type: boolean
env:
STELLAOPS_URL: "https://api.stella-ops.internal"
jobs:
pre-flight:
runs-on: ubuntu-22.04
outputs:
identity-pattern: ${{ steps.config.outputs.identity-pattern }}
steps:
- name: Configure Identity Constraints
id: config
run: |
ENV="${{ github.event.inputs.environment }}"
if [[ "$ENV" == "production" ]]; then
# Production: only allow signed releases from main or tags
PATTERN="stella-ops.org/git.stella-ops.org:ref:refs/(heads/main|tags/v.*)"
else
# Staging: allow any branch
PATTERN="stella-ops.org/git.stella-ops.org:ref:refs/heads/.*"
fi
echo "identity-pattern=${PATTERN}" >> $GITHUB_OUTPUT
echo "Using identity pattern: ${PATTERN}"
verify-attestations:
needs: pre-flight
runs-on: ubuntu-22.04
permissions:
contents: read
outputs:
verified: ${{ steps.verify.outputs.verified }}
attestation-count: ${{ steps.verify.outputs.count }}
steps:
- name: Install StellaOps CLI
run: |
curl -sL https://get.stella-ops.org/cli | sh
echo "$HOME/.stellaops/bin" >> $GITHUB_PATH
- name: Verify All Attestations
id: verify
run: |
set -euo pipefail
IMAGE="${{ github.event.inputs.image }}"
IDENTITY="${{ needs.pre-flight.outputs.identity-pattern }}"
ISSUER="https://git.stella-ops.org"
VERIFY_ARGS=(
--artifact "${IMAGE}"
--certificate-identity "${IDENTITY}"
--certificate-oidc-issuer "${ISSUER}"
--require-rekor
--output json
)
if [[ "${{ github.event.inputs.require_sbom }}" == "true" ]]; then
VERIFY_ARGS+=(--require-sbom)
fi
if [[ "${{ github.event.inputs.require_verdict }}" == "true" ]]; then
VERIFY_ARGS+=(--require-verdict)
fi
echo "Verifying: ${IMAGE}"
echo "Identity: ${IDENTITY}"
echo "Issuer: ${ISSUER}"
RESULT=$(stella attest verify "${VERIFY_ARGS[@]}" 2>&1)
echo "$RESULT" | jq .
VERIFIED=$(echo "$RESULT" | jq -r '.valid')
COUNT=$(echo "$RESULT" | jq -r '.attestationCount')
echo "verified=${VERIFIED}" >> $GITHUB_OUTPUT
echo "count=${COUNT}" >> $GITHUB_OUTPUT
if [[ "$VERIFIED" != "true" ]]; then
echo "::error::Verification failed"
echo "$RESULT" | jq -r '.issues[]? | "::error::\(.code): \(.message)"'
exit 1
fi
echo "Verification passed with ${COUNT} attestations"
verify-provenance:
needs: pre-flight
runs-on: ubuntu-22.04
permissions:
contents: read
outputs:
valid: ${{ steps.verify.outputs.valid }}
steps:
- name: Install StellaOps CLI
run: |
curl -sL https://get.stella-ops.org/cli | sh
echo "$HOME/.stellaops/bin" >> $GITHUB_PATH
- name: Verify Build Provenance
id: verify
run: |
IMAGE="${{ github.event.inputs.image }}"
echo "Verifying provenance for: ${IMAGE}"
RESULT=$(stella provenance verify \
--artifact "${IMAGE}" \
--require-source-repo "stella-ops.org/git.stella-ops.org" \
--output json)
echo "$RESULT" | jq .
VALID=$(echo "$RESULT" | jq -r '.valid')
echo "valid=${VALID}" >> $GITHUB_OUTPUT
if [[ "$VALID" != "true" ]]; then
echo "::error::Provenance verification failed"
exit 1
fi
create-audit-entry:
needs: [verify-attestations, verify-provenance]
runs-on: ubuntu-22.04
steps:
- name: Install StellaOps CLI
run: |
curl -sL https://get.stella-ops.org/cli | sh
echo "$HOME/.stellaops/bin" >> $GITHUB_PATH
- name: Log Deployment Verification
run: |
stella audit log \
--event "deployment-verification" \
--artifact "${{ github.event.inputs.image }}" \
--environment "${{ github.event.inputs.environment }}" \
--verified true \
--attestations "${{ needs.verify-attestations.outputs.attestation-count }}" \
--provenance-valid "${{ needs.verify-provenance.outputs.valid }}" \
--actor "${{ github.actor }}" \
--workflow "${{ github.workflow }}" \
--run-id "${{ github.run_id }}"
approve-deployment:
needs: [verify-attestations, verify-provenance, create-audit-entry]
runs-on: ubuntu-22.04
environment: ${{ github.event.inputs.environment }}
steps:
- name: Deployment Approved
run: |
cat >> $GITHUB_STEP_SUMMARY << EOF
## Deployment Approved
| Field | Value |
|-------|-------|
| **Image** | \`${{ github.event.inputs.image }}\` |
| **Environment** | ${{ github.event.inputs.environment }} |
| **Attestations** | ${{ needs.verify-attestations.outputs.attestation-count }} |
| **Provenance Valid** | ${{ needs.verify-provenance.outputs.valid }} |
| **Approved By** | @${{ github.actor }} |
Deployment can now proceed.
EOF