# .github/workflows/examples/example-container-sign.yml # Example: Sign container image with keyless signing # # This example shows how to: # 1. Build a container image # 2. Push to registry # 3. Sign using StellaOps keyless signing # 4. Attach attestation to image # # Adapt to your repository by: # - Updating the registry URL # - Adjusting Dockerfile path # - Adding your specific build args name: Build and Sign Container on: push: branches: [main] tags: ['v*'] pull_request: branches: [main] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build: runs-on: ubuntu-latest permissions: contents: read packages: write outputs: digest: ${{ steps.build.outputs.digest }} image: ${{ steps.build.outputs.image }} steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Container Registry if: github.event_name != 'pull_request' uses: docker/login-action@v3 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract Metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha - name: Build and Push id: build uses: docker/build-push-action@v5 with: context: . push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max provenance: true sbom: true - name: Output Image Digest if: github.event_name != 'pull_request' run: | echo "digest=${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT echo "image=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT sign: needs: build if: github.event_name != 'pull_request' uses: ./.github/workflows/examples/stellaops-sign.yml with: artifact-digest: ${{ needs.build.outputs.digest }} artifact-type: image push-attestation: true permissions: id-token: write contents: read packages: write verify: needs: [build, sign] if: github.event_name != 'pull_request' uses: ./.github/workflows/examples/stellaops-verify.yml with: artifact-digest: ${{ needs.build.outputs.digest }} certificate-identity: 'repo:${{ github.repository }}:ref:${{ github.ref }}' certificate-oidc-issuer: 'https://token.actions.githubusercontent.com' require-rekor: true strict: true permissions: contents: read packages: read summary: needs: [build, sign, verify] if: github.event_name != 'pull_request' runs-on: ubuntu-latest steps: - name: Generate Release Summary run: | cat >> $GITHUB_STEP_SUMMARY << EOF ## Container Image Published **Image:** \`${{ needs.build.outputs.image }}\` ### Pull Command \`\`\`bash docker pull ${{ needs.build.outputs.image }} \`\`\` ### Verify Signature \`\`\`bash stella attest verify \\ --artifact "${{ needs.build.outputs.digest }}" \\ --certificate-identity "repo:${{ github.repository }}:ref:${{ github.ref }}" \\ --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \`\`\` ### Attestations | Type | Digest | |------|--------| | Signature | \`${{ needs.sign.outputs.attestation-digest }}\` | | Rekor | \`${{ needs.sign.outputs.rekor-uuid }}\` | EOF