# .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