Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# release flow:
# 1. tag v* on main triggers this workflow
# 2. build job produces zopa.wasm (--release=small) + sha256 and exposes
# base64 subjects for the slsa-github-generator
# 3. provenance job generates SLSA v1.0 attestation via the reusable workflow
# (runs in an isolated builder, uploads the intoto.jsonl to the release)
# 4. sign job runs cosign sign-blob keylessly and attaches the sigstore bundle
# 5. release job attaches the wasm + sha256 to the GitHub Release
#
# secrets used: none. credentials are minted via OIDC per run.

name: release

on:
push:
tags: ["v*"]
workflow_dispatch:

permissions: {}

jobs:
build:
name: build wasm + checksum
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
outputs:
wasm-name: ${{ steps.pack.outputs.wasm-name }}
wasm-sha256: ${{ steps.pack.outputs.wasm-sha256 }}
subjects-base64: ${{ steps.pack.outputs.subjects-base64 }}
steps:
- name: harden runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2
with:
egress-policy: audit

- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1
with:
version: 0.16.0

- name: build (release-small)
run: zig build --release=small

- name: pack
id: pack
run: |
set -euo pipefail
src="zig-out/bin/zopa.wasm"
name="zopa-${GITHUB_REF_NAME}.wasm"
cp "$src" "$name"
sha=$(shasum -a 256 "$name" | awk '{print $1}')
printf '%s %s\n' "$sha" "$name" > "$name.sha256"
subjects=$(printf '%s %s\n' "$sha" "$name" | base64 -w0)
echo "wasm-name=$name" >>"$GITHUB_OUTPUT"
echo "wasm-sha256=$sha" >>"$GITHUB_OUTPUT"
echo "subjects-base64=$subjects" >>"$GITHUB_OUTPUT"
ls -l "$name" "$name.sha256"
wc -c "$name"

- name: upload wasm
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: wasm
path: |
${{ steps.pack.outputs.wasm-name }}
${{ steps.pack.outputs.wasm-name }}.sha256
if-no-files-found: error
retention-days: 7

provenance:
name: slsa v1.0 provenance
needs: [build]
permissions:
actions: read
contents: write
id-token: write
# exception: slsa-github-generator reusable workflows MUST be referenced by tag,
# not sha. internally this ref is parsed as `refs/tags/vX.Y.Z` to fetch the
# pre-built builder binary from the matching release. sha pinning makes the
# binary download fail with "Invalid ref ... Expected ref of the form
# refs/tags/vX.Y.Z". see https://github.com/slsa-framework/slsa-github-generator
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
with:
base64-subjects: ${{ needs.build.outputs.subjects-base64 }}
provenance-name: ${{ needs.build.outputs.wasm-name }}.intoto.jsonl
upload-assets: true

sign:
name: cosign sign-blob (keyless)
needs: [build, provenance]
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
steps:
- name: harden runner
uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2
with:
egress-policy: audit

- uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1

- name: download wasm
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8
with:
name: wasm

- name: sign
# cosign v4 emits a single sigstore bundle (.sigstore.json) by default;
# --output-signature / --output-certificate are deprecated and ignored.
run: |
cosign sign-blob --yes \
--bundle "${{ needs.build.outputs.wasm-name }}.sigstore.json" \
"${{ needs.build.outputs.wasm-name }}"

- name: attach to release
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3
with:
files: |
${{ needs.build.outputs.wasm-name }}
${{ needs.build.outputs.wasm-name }}.sha256
${{ needs.build.outputs.wasm-name }}.sigstore.json
fail_on_unmatched_files: true
generate_release_notes: true
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ once the first stable tag ships.
proxy-wasm host buffer ownership conventions.
- Integration tests in Node, wasmtime, and a real Envoy
(`zig build test`, `test-wasmtime`, `test-envoy`).
- Automated releases on `v*` tags with SLSA v1.0 build provenance and
cosign keyless signatures. Each release attaches `zopa-<tag>.wasm`,
`.sha256`, `.intoto.jsonl`, and `.sigstore.json`.

### Fixed

- README badges (CI, OpenSSF Scorecard) now resolve. They were left
pointing at `kanywst/zopa` after the repo moved to `0-draft/zopa`.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ Tiny, zero-allocation authorization engine for proxy-wasm and the edge.
~50 KB. No GC. No deps.

[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
[![CI](https://github.com/kanywst/zopa/actions/workflows/ci.yml/badge.svg)](https://github.com/kanywst/zopa/actions/workflows/ci.yml)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/kanywst/zopa/badge)](https://securityscorecards.dev/viewer/?uri=github.com/kanywst/zopa)
[![CI](https://github.com/0-draft/zopa/actions/workflows/ci.yml/badge.svg)](https://github.com/0-draft/zopa/actions/workflows/ci.yml)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/0-draft/zopa/badge)](https://securityscorecards.dev/viewer/?uri=github.com/0-draft/zopa)
[![Zig](https://img.shields.io/badge/zig-0.16.0-orange.svg)](https://ziglang.org)

zopa runs as a `wasm32-freestanding` module. Hosts hand it a request
Expand Down
Loading