diff --git a/.github/workflows/rotate-wallet-publisher.yml b/.github/workflows/rotate-wallet-publisher.yml new file mode 100644 index 0000000..91b1978 --- /dev/null +++ b/.github/workflows/rotate-wallet-publisher.yml @@ -0,0 +1,32 @@ +name: rotate-wallet-publisher + +# One-off, admin-approved rotation of io.pilot.wallet's publisher pin +# (2026-10-08). The key the catalogue pinned (ed25519:VF8fdEP…) is held by +# no workflow, so wallet 0.4.0 could not be signed with it. This re-points +# the pin to the new wallet key and opens the catalogue PR, re-signed with +# CATALOG_SIGN_KEY (publish.RotatePublisher, as /admin/rotate-key does). +# The app id and the key are fixed here so the workflow cannot re-pin +# anything else; delete this file once the rotation has merged. + +on: + workflow_dispatch: + +permissions: + contents: read + +jobs: + rotate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + - name: Rotate io.pilot.wallet's publisher pin + env: + CATALOG_PUBLISH_TOKEN: ${{ secrets.CATALOG_PUBLISH_TOKEN }} + CATALOG_SIGN_KEY: ${{ secrets.CATALOG_SIGN_KEY }} + run: | + go run ./cmd/rotate-publisher \ + -id io.pilot.wallet \ + -publisher 'ed25519:xAD0ai5GYWo8v0cmdhytZYRjSbi2edgEthWkBnO+1ik=' diff --git a/cmd/rotate-publisher/main.go b/cmd/rotate-publisher/main.go new file mode 100644 index 0000000..e785c39 --- /dev/null +++ b/cmd/rotate-publisher/main.go @@ -0,0 +1,31 @@ +// rotate-publisher re-points an app's publisher pin in the catalogue and opens +// the re-signed catalogue PR: the same admin-gated rotation the publish-server's +// /admin/rotate-key does (publish.RotatePublisher), for use from a workflow that +// holds CATALOG_PUBLISH_TOKEN and CATALOG_SIGN_KEY. +// +// rotate-publisher -id io.pilot.wallet -publisher ed25519: +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/pilot-protocol/app-template/internal/publish" +) + +func main() { + id := flag.String("id", "", "app id whose publisher pin to re-point") + pub := flag.String("publisher", "", "new publisher pin, ed25519:") + flag.Parse() + if *id == "" || *pub == "" { + fmt.Fprintln(os.Stderr, "usage: rotate-publisher -id -publisher ed25519:") + os.Exit(2) + } + url, err := publish.RotatePublisher(*id, *pub, os.Getenv("CATALOG_PUBLISH_TOKEN"), os.Getenv("CATALOG_SIGN_KEY")) + if err != nil { + fmt.Fprintln(os.Stderr, "rotate:", err) + os.Exit(1) + } + fmt.Println(url) +}