- 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.
205 lines
6.1 KiB
YAML
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
|