diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..249bb2f --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,128 @@ +name: Release + +on: + push: + tags: + - 'v*.*.*' + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,prefix={{branch}}- + labels: | + org.opencontainers.image.title=Barycenter + org.opencontainers.image.description=OpenID Connect Identity Provider with federation and auto-registration + org.opencontainers.image.vendor=${{ github.repository_owner }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + VERSION=${{ github.ref_name }} + REVISION=${{ github.sha }} + + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 + with: + subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + subject-digest: ${{ steps.build.outputs.digest }} + push-to-registry: true + + create-github-release: + runs-on: ubuntu-latest + needs: build-and-push + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate changelog + id: changelog + run: | + # Get previous tag + PREVIOUS_TAG=$(git describe --abbrev=0 --tags $(git rev-list --tags --skip=1 --max-count=1) 2>/dev/null || echo "") + + # Generate changelog + if [ -z "$PREVIOUS_TAG" ]; then + CHANGELOG=$(git log --pretty=format:"- %s (%h)" --no-merges) + else + CHANGELOG=$(git log ${PREVIOUS_TAG}..HEAD --pretty=format:"- %s (%h)" --no-merges) + fi + + # Save to file for multiline output + echo "$CHANGELOG" > /tmp/changelog.txt + + # Set output + echo "changelog<> $GITHUB_OUTPUT + cat /tmp/changelog.txt >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: softprops/action-gh-release@v1 + with: + body: | + ## What's Changed + + ${{ steps.changelog.outputs.changelog }} + + ## Docker Images + + Pull the Docker image: + ```bash + docker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }} + ``` + + Available platforms: + - linux/amd64 + - linux/arm64 + + ## Installation + + See [DEPLOYMENT.md](https://github.com/${{ github.repository }}/blob/${{ github.ref_name }}/DEPLOYMENT.md) for installation instructions. + draft: false + prerelease: ${{ contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') || contains(github.ref_name, 'rc') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0f772f2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,40 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added +- Initial release of Barycenter OpenID Connect Identity Provider +- OAuth 2.0 Authorization Code flow with PKCE (S256) +- Dynamic client registration +- ID Token signing (RS256) with at_hash and nonce support +- UserInfo endpoint with Bearer token authentication +- OpenID Discovery and JWKS publication +- User registration and authentication with session management +- Property storage API for arbitrary user properties +- Comprehensive deployment configurations: + - Docker and Docker Compose + - Kubernetes Helm chart with Ingress support + - Kubernetes Gateway API support + - systemd service for Linux + - FreeBSD rc.d script + - illumos/Solaris SMF manifest +- Security headers and Cache-Control for token endpoint +- Rate limiting for authentication endpoints +- Integration tests with openidconnect-rs and oauth2-rs libraries + +### Security +- Password hashing with Argon2 +- PKCE S256 enforcement +- CSRF protection with state parameter +- Security headers (X-Frame-Options, CSP, etc.) +- Non-root user execution in containers +- Extensive systemd security hardening + +## [0.1.0] - 2025-11-29 + +Initial development version. diff --git a/Cargo.toml b/Cargo.toml index 88b5223..deefb11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,3 +51,21 @@ urlencoding = "2" [profile.release] debug = 1 + +# cargo-release configuration +[package.metadata.release] +# Ensure version is updated in Cargo.toml +pre-release-commit-message = "chore: release {{version}}" +# Create a git tag +tag-message = "chore: release {{version}}" +tag-name = "v{{version}}" +# Push changes and tags +push = true +# Require branch to be main +allow-branch = ["main"] +# Run tests before releasing +pre-release-replacements = [ + { file = "CHANGELOG.md", search = "## \\[Unreleased\\]", replace = "## [Unreleased]\n\n## [{{version}}] - {{date}}", exactly = 1 }, + { file = "deploy/helm/barycenter/Chart.yaml", search = "version: .*", replace = "version: {{version}}" }, + { file = "deploy/helm/barycenter/Chart.yaml", search = "appVersion: .*", replace = "appVersion: \"{{version}}\"" }, +] diff --git a/README.md b/README.md index a92594b..289d7b1 100644 --- a/README.md +++ b/README.md @@ -150,6 +150,43 @@ This is an early-stage implementation. See `docs/next-iteration-plan.md` for pla - Token revocation and introspection - OpenID Federation support +## Deployment + +Barycenter supports multiple deployment platforms: + +- **Docker**: Pre-built images available at `ghcr.io/[owner]/barycenter` +- **Kubernetes**: Helm chart with Ingress and Gateway API support +- **Linux**: systemd service with security hardening +- **FreeBSD**: rc.d init script +- **illumos/Solaris**: SMF manifest + +See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed installation instructions for each platform. + +### Quick Start with Docker + +```bash +docker pull ghcr.io/[owner]/barycenter:latest +docker run -p 8080:8080 -v barycenter-data:/app/data ghcr.io/[owner]/barycenter:latest +``` + +### Quick Start with Helm + +```bash +helm install barycenter ./deploy/helm/barycenter \ + --namespace barycenter \ + --create-namespace +``` + +## Releases + +For maintainers: see [RELEASE.md](RELEASE.md) for the release process. + +To create a new release: +```bash +cargo install cargo-release +cargo release minor --execute # Bumps version and creates release +``` + ## Contributing Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, development workflow, and the process for submitting pull requests. diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..ba1ea77 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,248 @@ +# Release Process + +This document describes how to create a new release of Barycenter. + +## Prerequisites + +1. **Install cargo-release:** + ```bash + cargo install cargo-release + ``` + +2. **Ensure you're on the main branch with a clean working tree:** + ```bash + git checkout main + git pull origin main + git status # Should show clean working tree + ``` + +3. **Verify all tests pass:** + ```bash + cargo nextest run + cargo clippy -- -D warnings + cargo fmt -- --check + ``` + +## Release Steps + +### 1. Update CHANGELOG.md + +Before releasing, update the `CHANGELOG.md`: + +1. Move all changes from `[Unreleased]` to a new version section +2. Add the release date +3. Ensure all changes are categorized (Added, Changed, Deprecated, Removed, Fixed, Security) + +Example: +```markdown +## [Unreleased] + +## [0.2.0] - 2025-12-01 + +### Added +- New feature X +- New feature Y + +### Fixed +- Bug fix Z +``` + +### 2. Run cargo-release + +cargo-release will: +- Bump the version in `Cargo.toml` +- Update the Helm chart versions +- Create a git commit +- Create a git tag +- Push to GitHub + +**Dry run first (recommended):** +```bash +# Patch version bump (0.1.0 -> 0.1.1) +cargo release patch --dry-run + +# Minor version bump (0.1.0 -> 0.2.0) +cargo release minor --dry-run + +# Major version bump (0.1.0 -> 1.0.0) +cargo release major --dry-run + +# Specific version +cargo release 1.0.0 --dry-run +``` + +**Execute the release:** +```bash +# Patch release +cargo release patch --execute + +# Minor release +cargo release minor --execute + +# Major release +cargo release major --execute + +# Specific version +cargo release 1.0.0 --execute +``` + +### 3. Automated Release Process + +Once the tag is pushed, GitHub Actions will automatically: + +1. **Build Docker images** for multiple platforms: + - linux/amd64 + - linux/arm64 + +2. **Push images to GitHub Container Registry** with tags: + - `ghcr.io/[owner]/barycenter:v1.0.0` (full version) + - `ghcr.io/[owner]/barycenter:1.0` (major.minor) + - `ghcr.io/[owner]/barycenter:1` (major) + - `ghcr.io/[owner]/barycenter:main-` (commit SHA) + +3. **Create a GitHub Release** with: + - Auto-generated changelog + - Docker pull instructions + - Links to documentation + +4. **Generate attestations** for supply chain security + +### 4. Verify the Release + +After the release workflow completes: + +1. **Check GitHub Releases:** + - Visit https://github.com/[owner]/barycenter/releases + - Verify the release notes are correct + - Check that all assets are present + +2. **Test the Docker image:** + ```bash + docker pull ghcr.io/[owner]/barycenter:v1.0.0 + docker run --rm ghcr.io/[owner]/barycenter:v1.0.0 --version + ``` + +3. **Test the Helm chart:** + ```bash + helm install barycenter ./deploy/helm/barycenter \ + --dry-run \ + --namespace barycenter-test + ``` + +## Versioning Strategy + +We follow [Semantic Versioning](https://semver.org/): + +- **MAJOR** version (1.0.0 → 2.0.0): Incompatible API changes +- **MINOR** version (1.0.0 → 1.1.0): Backwards-compatible new features +- **PATCH** version (1.0.0 → 1.0.1): Backwards-compatible bug fixes + +### Pre-releases + +For alpha, beta, or release candidates: + +```bash +cargo release 1.0.0-alpha.1 --execute +cargo release 1.0.0-beta.1 --execute +cargo release 1.0.0-rc.1 --execute +``` + +Pre-release images are automatically marked as "pre-release" in GitHub. + +## Hotfix Releases + +For urgent fixes: + +1. Create a hotfix branch from the release tag: + ```bash + git checkout -b hotfix/v1.0.1 v1.0.0 + ``` + +2. Make the fix and commit: + ```bash + git add . + git commit -m "fix: critical security issue" + ``` + +3. Run cargo-release: + ```bash + cargo release patch --execute + ``` + +4. Merge back to main: + ```bash + git checkout main + git merge hotfix/v1.0.1 + git push + ``` + +## Rollback + +If you need to rollback a release: + +1. **Delete the tag locally and remotely:** + ```bash + git tag -d v1.0.0 + git push origin :refs/tags/v1.0.0 + ``` + +2. **Delete the GitHub Release:** + - Go to Releases page + - Click Edit on the release + - Click Delete + +3. **Delete the container images:** + - Go to Packages page + - Select the version + - Delete the package version + +4. **Revert the version bump commit:** + ```bash + git revert HEAD + git push + ``` + +## Troubleshooting + +### cargo-release fails with dirty working tree + +Ensure all changes are committed: +```bash +git status +git add . +git commit -m "chore: prepare for release" +``` + +### GitHub Actions workflow fails + +Check the workflow logs: +1. Go to Actions tab +2. Click on the failing workflow +3. Review the error messages +4. Fix the issue and re-run the workflow + +### Docker image build fails + +Common issues: +- Platform-specific build errors: Check Dockerfile for platform compatibility +- Cache issues: Clear GitHub Actions cache and retry +- Dependency issues: Ensure Cargo.lock is up to date + +## Post-Release Tasks + +After a successful release: + +1. **Announce the release:** + - Update project documentation + - Post to social media/forums + - Notify users of breaking changes + +2. **Monitor for issues:** + - Watch GitHub Issues + - Check container pull metrics + - Monitor error reports + +3. **Plan next release:** + - Create milestone for next version + - Triage issues and features + - Update roadmap