This document describes the release process for DuckPond and addresses software supply chain security considerations.
All builds are performed via GitHub Actions (see .github/workflows/rust-ci.yml):
- On Pull Requests: Run tests, clippy, and format checks only
- On Main Branch: Run tests + build and publish container image + create .deb package
- On Version Tags (
v*): Same as main, with version-tagged artifacts
For each successful build on main or version tags:
-
Container Image:
ghcr.io/jmacd/duckpond:latest(or version tag)- Built with Podman on GitHub's Ubuntu runners
- Based on Debian Bookworm (glibc 2.36)
- Includes pond binary at
/usr/bin/pond
-
Debian Package:
pond_<version>_amd64.deb- Available as GitHub Actions artifact (90 day retention)
- Dependencies: libssl3, ca-certificates
- Installs to
/usr/bin/pond
-
Update version in
Cargo.tomlworkspace section:[workspace.package] version = "0.16.0"
-
Commit and tag:
git commit -am "Release v0.16.0" git tag v0.16.0 git push origin main --tags -
Wait for CI: GitHub Actions will automatically build and publish
-
Download artifacts: Go to Actions tab → select the workflow run → download artifacts
-
Create GitHub Release:
- Go to Releases → Draft a new release
- Select the tag
- Attach the .deb package (download from artifacts first)
- Document changes
✅ Build Isolation: All builds run in ephemeral GitHub-hosted runners
✅ Dependency Pinning: Cargo.lock is committed to the repository
✅ Audit Trail: All builds are associated with specific commits and workflow runs
✅ Container Registry: Uses GitHub Container Registry with authentication
❌ No artifact signing: Binaries and packages are not cryptographically signed
❌ No SBOM generation: No Software Bill of Materials
❌ No provenance attestation: No SLSA provenance
❌ Limited reproducibility: Builds may not be bit-for-bit reproducible
Install GPG key in GitHub Actions:
- name: Import GPG key
uses: crazy-max/ghaction-import-gpg@v6
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.GPG_PASSPHRASE }}
- name: Sign .deb package
run: |
dpkg-sig --sign builder artifacts/*.debAdd to workflow:
- name: Generate SBOM
run: |
cargo install cargo-sbom
cargo sbom > artifacts/pond-sbom.jsonUse the SLSA GitHub Generator:
- uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0
with:
provenance-name: pond-provenance.intoto.jsonl- name: Sign container image
run: |
cosign sign --key env://COSIGN_KEY ${{ steps.meta.outputs.image_id }}:${{ steps.meta.outputs.version }}
env:
COSIGN_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}Create .github/dependabot.yml:
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"Trust model: Trust GitHub Actions + repository access control
Verification steps:
- Verify the artifact came from the official repository
- Check the commit hash matches the release tag
- Review the workflow run logs for any anomalies
Users will be able to verify signatures:
# Verify .deb signature
dpkg-sig --verify pond_0.16.0_amd64.deb
# Verify container image
cosign verify ghcr.io/jmacd/duckpond:v0.16.0
# Verify SLSA provenance
slsa-verifier verify-artifact pond \
--provenance-path pond-provenance.intoto.jsonl \
--source-uri github.com/jmacd/duckpond- Platform: Debian 12 (Bookworm)
- Architecture: x86_64 (amd64)
- Minimum RAM: 1GB (monitor memory usage)
- Dependencies: libssl3, ca-certificates
# Download from GitHub Release
wget https://github.com/jmacd/duckpond/releases/download/v0.16.0/pond_0.16.0_amd64.deb
# Install
sudo dpkg -i pond_0.16.0_amd64.deb
sudo apt-get install -f # Install any missing dependencies
# Verify
pond --version
# Uninstall
sudo dpkg -r pondCreate systemd service /etc/systemd/system/pond.service:
[Unit]
Description=DuckPond Service
After=network.target
[Service]
Type=simple
User=pond
Group=pond
ExecStart=/usr/bin/pond <your-arguments>
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.targetEnable and start:
sudo useradd -r -s /bin/false pond
sudo systemctl daemon-reload
sudo systemctl enable pond
sudo systemctl start pond
sudo journalctl -u pond -f- Run as non-root user (demonstrated in systemd service above)
- Use minimal container images (Debian bookworm-slim)
- Keep dependencies up to date (use Dependabot)
- Monitor for CVEs in dependencies
- Container registry requires authentication for writes
- GitHub Actions uses OIDC tokens (no long-lived credentials)
- Release artifacts require repo admin access to create
All releases are traceable:
- Git commit hash
- GitHub Actions workflow run ID
- Build logs (retained for 90 days)
- Container image layers and manifest
- Reproducible builds: Investigate cargo-careful or similar tools
- Multi-architecture builds: Add ARM64 support
- Automated security scanning: Integrate trivy or grype
- FIPS compliance: If required for regulated environments
- Release automation: Auto-create GitHub releases from tags
For release-related questions, open an issue in the repository with the release label.