mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 21:56:43 +00:00
chore(release): signed releases for binaries and docker (#35)
* chore(release): signed releases for binaries and docker * undo unneeded changes
This commit is contained in:
parent
6a308e75b8
commit
688d070666
3 changed files with 204 additions and 9 deletions
140
.github/workflows/RELEASE_SIGNING.md
vendored
Normal file
140
.github/workflows/RELEASE_SIGNING.md
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
# Release Signing Setup
|
||||||
|
|
||||||
|
This document explains how release signing is implemented for bera-geth, including PGP signing for binaries and Cosign signing for Docker images.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The bera-geth release process includes cryptographic signing for all release artifacts:
|
||||||
|
- **Binary releases**: Signed with PGP/GPG
|
||||||
|
- **Docker images**: Signed with Cosign (keyless signing via OIDC)
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Prerequisites for Release Managers
|
||||||
|
|
||||||
|
#### PGP Signing Setup
|
||||||
|
|
||||||
|
1. **Create the `LINUX_SIGNING_KEY` secret in GitHub**:
|
||||||
|
```bash
|
||||||
|
# Export your PGP private key
|
||||||
|
gpg --export-secret-keys --armor YOUR_KEY_ID > private.key
|
||||||
|
|
||||||
|
# Base64 encode it
|
||||||
|
cat private.key | base64 -w 0
|
||||||
|
|
||||||
|
# Copy the output and add it as the LINUX_SIGNING_KEY secret in GitHub repository settings
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Ensure the public key matches**: The public key at `.github/workflows/release.asc` should correspond to the private key used for signing.
|
||||||
|
|
||||||
|
#### Cosign Setup
|
||||||
|
|
||||||
|
Cosign uses keyless signing (no secret required). The workflow uses GitHub's OIDC provider to sign images, which means:
|
||||||
|
- No private keys to manage
|
||||||
|
- Signatures are tied to the GitHub Actions workflow identity
|
||||||
|
- Full transparency via Rekor transparency log
|
||||||
|
|
||||||
|
## Release Process
|
||||||
|
|
||||||
|
### Triggering a Release
|
||||||
|
|
||||||
|
Releases are triggered by:
|
||||||
|
- Pushing a tag matching `v1.*` (e.g., `v1.0.0`, `v1.0.0-rc1`)
|
||||||
|
- The workflow will automatically create a draft release with all signed artifacts
|
||||||
|
|
||||||
|
### What Gets Signed
|
||||||
|
|
||||||
|
1. **Binary Archives**:
|
||||||
|
- `bera-geth-linux-amd64-*.tar.gz` → `bera-geth-linux-amd64-*.tar.gz.asc`
|
||||||
|
- `bera-geth-linux-arm64-*.tar.gz` → `bera-geth-linux-arm64-*.tar.gz.asc`
|
||||||
|
- `bera-geth-alltools-linux-amd64-*.tar.gz` → `bera-geth-alltools-linux-amd64-*.tar.gz.asc`
|
||||||
|
- `bera-geth-alltools-linux-arm64-*.tar.gz` → `bera-geth-alltools-linux-arm64-*.tar.gz.asc`
|
||||||
|
|
||||||
|
2. **Docker Images**:
|
||||||
|
- Multi-arch images at `ghcr.io/berachain/bera-geth:VERSION`
|
||||||
|
- Signed with Cosign using keyless signing
|
||||||
|
|
||||||
|
## Verification Instructions
|
||||||
|
|
||||||
|
### Verifying Binary Signatures
|
||||||
|
|
||||||
|
Users can verify the PGP signatures of release binaries:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Download and import the public key
|
||||||
|
curl -sSL https://raw.githubusercontent.com/berachain/bera-geth/main/.github/workflows/release.asc | gpg --import
|
||||||
|
|
||||||
|
# Download a release archive and its signature
|
||||||
|
wget https://github.com/berachain/bera-geth/releases/download/v1.0.0/bera-geth-linux-amd64-v1.0.0.tar.gz
|
||||||
|
wget https://github.com/berachain/bera-geth/releases/download/v1.0.0/bera-geth-linux-amd64-v1.0.0.tar.gz.asc
|
||||||
|
|
||||||
|
# Verify the signature
|
||||||
|
gpg --verify bera-geth-linux-amd64-v1.0.0.tar.gz.asc bera-geth-linux-amd64-v1.0.0.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected output:
|
||||||
|
```
|
||||||
|
gpg: Signature made [date] using RSA key ID [key-id]
|
||||||
|
gpg: Good signature from "bera-geth-linux-signing-key"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verifying Docker Images
|
||||||
|
|
||||||
|
Docker images are signed with Cosign and can be verified:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install cosign if not already installed
|
||||||
|
brew install cosign # macOS
|
||||||
|
# or see https://docs.sigstore.dev/cosign/installation/
|
||||||
|
|
||||||
|
# Verify a specific version
|
||||||
|
cosign verify ghcr.io/berachain/bera-geth:v1.0.0
|
||||||
|
|
||||||
|
# Verify the latest image
|
||||||
|
cosign verify ghcr.io/berachain/bera-geth:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
The verification will show:
|
||||||
|
- The GitHub Actions workflow that created the image
|
||||||
|
- The commit SHA
|
||||||
|
- The OIDC issuer (GitHub)
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **PGP Key Security**:
|
||||||
|
- The PGP private key should be kept secure and only accessible to authorized release managers
|
||||||
|
- Regularly rotate keys and update the public key in the repository
|
||||||
|
- Use a strong passphrase for the private key
|
||||||
|
|
||||||
|
2. **Cosign Keyless Signing**:
|
||||||
|
- Signatures are tied to the GitHub Actions workflow identity
|
||||||
|
- Verification includes checking the workflow that signed the image
|
||||||
|
- All signatures are recorded in the Rekor transparency log
|
||||||
|
|
||||||
|
3. **Best Practices**:
|
||||||
|
- Always verify signatures before using release artifacts in production
|
||||||
|
- Check that the signing workflow matches the official repository
|
||||||
|
- Monitor the repository for any changes to signing keys or workflows
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### PGP Signing Issues
|
||||||
|
|
||||||
|
If PGP signing fails:
|
||||||
|
1. Check that the `LINUX_SIGNING_KEY` secret is properly set
|
||||||
|
2. Verify the key hasn't expired: `gpg --list-secret-keys`
|
||||||
|
3. Ensure the base64 encoding was done correctly
|
||||||
|
|
||||||
|
### Cosign Signing Issues
|
||||||
|
|
||||||
|
If Cosign signing fails:
|
||||||
|
1. Ensure the workflow has `id-token: write` permission
|
||||||
|
2. Check that the Docker image was successfully pushed before signing
|
||||||
|
3. Verify the image tag/digest is correct
|
||||||
|
|
||||||
|
### Release Draft Issues
|
||||||
|
|
||||||
|
If the release draft fails:
|
||||||
|
1. Ensure all artifacts were successfully uploaded
|
||||||
|
2. Check that the tag follows the correct format (`v1.*`)
|
||||||
|
3. Verify the workflow has `contents: write` permission
|
||||||
30
.github/workflows/docker.yml
vendored
30
.github/workflows/docker.yml
vendored
|
|
@ -38,6 +38,36 @@ jobs:
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Install Cosign
|
||||||
|
uses: sigstore/cosign-installer@v3
|
||||||
|
|
||||||
- name: Build and push multi-arch images to GHCR
|
- name: Build and push multi-arch images to GHCR
|
||||||
run: |
|
run: |
|
||||||
go run build/ci.go dockerx -platform linux/amd64,linux/arm64 -hub ghcr.io/berachain/bera-geth -upload
|
go run build/ci.go dockerx -platform linux/amd64,linux/arm64 -hub ghcr.io/berachain/bera-geth -upload
|
||||||
|
|
||||||
|
- name: Get image digest and version
|
||||||
|
id: image_info
|
||||||
|
run: |
|
||||||
|
# Extract version information
|
||||||
|
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
||||||
|
VERSION="${{ github.ref_name }}"
|
||||||
|
elif [[ "${{ github.ref }}" == refs/heads/main ]]; then
|
||||||
|
VERSION="latest"
|
||||||
|
else
|
||||||
|
VERSION="branch-${GITHUB_REF##*/}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the digest of the pushed image
|
||||||
|
DIGEST=$(docker buildx imagetools inspect ghcr.io/berachain/bera-geth:${VERSION} --format "{{.Manifest.Digest}}")
|
||||||
|
echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
|
||||||
|
echo "version=${VERSION}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Sign Docker images with Cosign
|
||||||
|
env:
|
||||||
|
COSIGN_EXPERIMENTAL: true
|
||||||
|
run: |
|
||||||
|
# Sign the multi-arch manifest by digest
|
||||||
|
cosign sign --yes ghcr.io/berachain/bera-geth@${{ steps.image_info.outputs.digest }}
|
||||||
|
|
||||||
|
# Also sign the tagged version
|
||||||
|
cosign sign --yes ghcr.io/berachain/bera-geth:${{ steps.image_info.outputs.version }}
|
||||||
|
|
|
||||||
43
.github/workflows/release.yml
vendored
43
.github/workflows/release.yml
vendored
|
|
@ -39,14 +39,18 @@ jobs:
|
||||||
|
|
||||||
- name: Create archive (amd64)
|
- name: Create archive (amd64)
|
||||||
run: |
|
run: |
|
||||||
go run build/ci.go archive -arch amd64 -type tar
|
go run build/ci.go archive -arch amd64 -type tar -signer LINUX_SIGNING_KEY
|
||||||
|
env:
|
||||||
|
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
|
||||||
- name: Upload artifacts (amd64)
|
- name: Upload artifacts (amd64)
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: bera-geth-linux-amd64-archives
|
name: bera-geth-linux-amd64-archives
|
||||||
path: |
|
path: |
|
||||||
bera-geth-linux-amd64-*.tar.gz
|
bera-geth-linux-amd64-*.tar.gz
|
||||||
|
bera-geth-linux-amd64-*.tar.gz.asc
|
||||||
bera-geth-alltools-linux-amd64-*.tar.gz
|
bera-geth-alltools-linux-amd64-*.tar.gz
|
||||||
|
bera-geth-alltools-linux-amd64-*.tar.gz.asc
|
||||||
- name: Cleanup bin
|
- name: Cleanup bin
|
||||||
run: rm -f build/bin/*
|
run: rm -f build/bin/*
|
||||||
|
|
||||||
|
|
@ -74,19 +78,23 @@ jobs:
|
||||||
|
|
||||||
- name: Create archive (arm64)
|
- name: Create archive (arm64)
|
||||||
run: |
|
run: |
|
||||||
go run build/ci.go archive -arch arm64 -type tar
|
go run build/ci.go archive -arch arm64 -type tar -signer LINUX_SIGNING_KEY
|
||||||
|
env:
|
||||||
|
LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }}
|
||||||
- name: Upload artifacts (arm64)
|
- name: Upload artifacts (arm64)
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: bera-geth-linux-arm64-archives
|
name: bera-geth-linux-arm64-archives
|
||||||
path: |
|
path: |
|
||||||
bera-geth-linux-arm64-*.tar.gz
|
bera-geth-linux-arm64-*.tar.gz
|
||||||
|
bera-geth-linux-arm64-*.tar.gz.asc
|
||||||
bera-geth-alltools-linux-arm64-*.tar.gz
|
bera-geth-alltools-linux-arm64-*.tar.gz
|
||||||
|
bera-geth-alltools-linux-arm64-*.tar.gz.asc
|
||||||
- name: Cleanup bin
|
- name: Cleanup bin
|
||||||
run: rm -fr build/bin/*
|
run: rm -fr build/bin/*
|
||||||
|
|
||||||
draft-release:
|
draft-release:
|
||||||
name: Draft Release
|
name: Draft Release
|
||||||
needs: [extract-version, linux-intel, linux-arm]
|
needs: [extract-version, linux-intel, linux-arm]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
|
|
@ -176,15 +184,32 @@ jobs:
|
||||||
|
|
||||||
## Binaries
|
## Binaries
|
||||||
|
|
||||||
| System | Architecture | Binary | Notes |
|
| System | Architecture | Binary | PGP Signature | Notes |
|
||||||
|:---:|:---:|:---:|:---|
|
|:---:|:---:|:---:|:---:|:---|
|
||||||
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | amd64 | [GETH_AMD64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_AMD64_PLACEHOLDER) | Most Linux systems |
|
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | amd64 | [GETH_AMD64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_AMD64_PLACEHOLDER) | [Signature](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_AMD64_PLACEHOLDER.asc) | Most Linux systems |
|
||||||
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | arm64 | [GETH_ARM64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ARM64_PLACEHOLDER) | 64-bit ARM systems |
|
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | arm64 | [GETH_ARM64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ARM64_PLACEHOLDER) | [Signature](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ARM64_PLACEHOLDER.asc) | 64-bit ARM systems |
|
||||||
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | amd64 | [GETH_ALLTOOLS_AMD64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ALLTOOLS_AMD64_PLACEHOLDER) | All tools bundle (amd64) |
|
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | amd64 | [GETH_ALLTOOLS_AMD64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ALLTOOLS_AMD64_PLACEHOLDER) | [Signature](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ALLTOOLS_AMD64_PLACEHOLDER.asc) | All tools bundle (amd64) |
|
||||||
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | arm64 | [GETH_ALLTOOLS_ARM64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ALLTOOLS_ARM64_PLACEHOLDER) | All tools bundle (arm64) |
|
| <img src="https://simpleicons.org/icons/linux.svg" style="width: 32px;"/> | arm64 | [GETH_ALLTOOLS_ARM64_PLACEHOLDER](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ALLTOOLS_ARM64_PLACEHOLDER) | [Signature](https://github.com/${{ github.repository }}/releases/download/RELEASE_TAG_PLACEHOLDER/GETH_ALLTOOLS_ARM64_PLACEHOLDER.asc) | All tools bundle (arm64) |
|
||||||
| **System** | **Option** | - | **Resource** |
|
| **System** | **Option** | - | **Resource** |
|
||||||
| <img src="https://simpleicons.org/icons/docker.svg" style="width: 32px;"/> | Docker | | [ghcr.io/berachain/bera-geth](https://ghcr.io/berachain/bera-geth) |
|
| <img src="https://simpleicons.org/icons/docker.svg" style="width: 32px;"/> | Docker | | [ghcr.io/berachain/bera-geth](https://ghcr.io/berachain/bera-geth) |
|
||||||
|
|
||||||
|
### Verifying Binary Signatures
|
||||||
|
|
||||||
|
All release binaries are signed with PGP. To verify:
|
||||||
|
|
||||||
|
1. Download the [public key](https://raw.githubusercontent.com/${{ github.repository }}/master/.github/workflows/release.asc)
|
||||||
|
2. Import the key: `gpg --import release.asc`
|
||||||
|
3. Verify the signature: `gpg --verify <filename>.asc <filename>`
|
||||||
|
|
||||||
|
### Docker Images
|
||||||
|
|
||||||
|
Docker images are available at `ghcr.io/berachain/bera-geth` and are signed with [Cosign](https://github.com/sigstore/cosign).
|
||||||
|
|
||||||
|
To verify Docker images:
|
||||||
|
```bash
|
||||||
|
cosign verify ghcr.io/berachain/bera-geth:RELEASE_TAG_PLACEHOLDER
|
||||||
|
```
|
||||||
|
|
||||||
### Installation
|
### Installation
|
||||||
|
|
||||||
The archives contain the geth binary and license file. Extract and run:
|
The archives contain the geth binary and license file. Extract and run:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue