diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..017ce62 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @yuriizee diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 6d0cc71..8c15dd4 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -4,14 +4,16 @@ | Version | Supported | | ------- | --------- | -| 1.x | ✅ | -| < 1.0 | ❌ | +| 2.x | ✅ | +| < 2.0 | ❌ | ## Reporting a vulnerability **Please do not report security vulnerabilities through public GitHub issues.** -Email [yuriyzee@gmail.com](mailto:yuriyzee@gmail.com) with: +Report it privately through +[GitHub Security Advisories](https://github.com/std-out/simple-data-objects/security/advisories/new) +or email [yuriyzee@gmail.com](mailto:yuriyzee@gmail.com) with: - a description of the issue and its impact, - a minimal reproduction if possible, @@ -21,6 +23,15 @@ You'll get an acknowledgement within 48 hours and a status update within 7 days. Once a fix is released, we'll coordinate disclosure with you and credit you in the release notes (unless you prefer to stay anonymous). +## Verifying a release + +Every release carries a source archive, a CycloneDX SBOM and a signed build +provenance attestation: + +```sh +gh attestation verify simple-data-objects-vX.Y.Z.tar.gz --repo std-out/simple-data-objects +``` + ## Security-sensitive areas Two parts of the codebase carry explicit security invariants: diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..fecd44d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + groups: + actions: + patterns: ["*"] diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 5697fe8..ac2d93d 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -20,28 +20,28 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout main - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: ref: main path: main fetch-depth: 0 - name: Checkout v1 - uses: actions/checkout@v7 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 with: ref: v1 path: v1 fetch-depth: 0 - name: Setup Node - uses: actions/setup-node@v6 + uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 with: node-version: 24 cache: npm cache-dependency-path: main/package-lock.json - name: Setup Pages - uses: actions/configure-pages@v6 + uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d - name: Build main docs (v2.0 — current) working-directory: main @@ -63,7 +63,7 @@ jobs: cp -r v1/docs/.vitepress/dist/. site/v1/ - name: Upload artifact - uses: actions/upload-pages-artifact@v5 + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 with: path: site @@ -79,4 +79,4 @@ jobs: steps: - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v5 + uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c0fe4af --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,64 @@ +name: Release artifacts + +on: + release: + types: [published] + workflow_dispatch: + inputs: + tag: + description: Release tag + required: true + +permissions: + contents: write + id-token: write + attestations: write + +jobs: + attest: + name: Provenance and SBOM + runs-on: ubuntu-latest + env: + TAG: ${{ github.event.release.tag_name || inputs.tag }} + GH_TOKEN: ${{ github.token }} + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + with: + ref: ${{ env.TAG }} + persist-credentials: false + + - name: Set up PHP + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 + with: + php-version: "8.4" + coverage: none + + - name: Build source archive + run: git archive --format=tar.gz --prefix="simple-data-objects-$TAG/" -o "simple-data-objects-$TAG.tar.gz" "$TAG" + + - name: Resolve runtime dependencies + run: composer install --no-dev --no-interaction --prefer-dist + + - name: Generate SBOM + uses: anchore/sbom-action@66cbf4bc1f1c0d2edc94016e65bc221b6bb0ad6c + with: + path: . + format: cyclonedx-json + output-file: simple-data-objects-${{ env.TAG }}.cdx.json + upload-artifact: false + upload-release-assets: false + + - name: Attest build provenance + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 + with: + subject-path: simple-data-objects-${{ env.TAG }}.tar.gz + + - name: Attest SBOM + uses: actions/attest-sbom@c604332985a26aa8cf1bdc465b92731239ec6b9e + with: + subject-path: simple-data-objects-${{ env.TAG }}.tar.gz + sbom-path: simple-data-objects-${{ env.TAG }}.cdx.json + + - name: Upload release assets + run: gh release upload "$TAG" "simple-data-objects-$TAG.tar.gz" "simple-data-objects-$TAG.cdx.json" --clobber --repo "$GITHUB_REPOSITORY" diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 4836ff7..9a7ad46 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -3,19 +3,24 @@ name: Security on: push: branches: [main, v2] + pull_request: + branches: [main, v2] schedule: - cron: "0 8 * * *" +permissions: + contents: read + jobs: audit: name: Composer Audit runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Set up PHP - uses: shivammathur/setup-php@v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 with: php-version: "8.4" coverage: none diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8cda913..31023e1 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [main, v2] +permissions: + contents: read + jobs: test: name: PHP ${{ matrix.php }} / Laravel ${{ matrix.laravel }} @@ -29,10 +32,10 @@ jobs: phpunit: "^11.5.50" steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Set up PHP ${{ matrix.php }} - uses: shivammathur/setup-php@v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 with: php-version: ${{ matrix.php }} coverage: none @@ -60,10 +63,10 @@ jobs: needs: test steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Set up PHP 8.4 with pcov - uses: shivammathur/setup-php@v2 + uses: shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962 with: php-version: "8.4" coverage: pcov diff --git a/CHANGELOG.md b/CHANGELOG.md index e12989f..2f16a53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0. ## [Unreleased] +### Changed +- Releases ship with a source archive, a CycloneDX SBOM and a build + provenance attestation (`gh attestation verify`). Security reports go + through GitHub private vulnerability reporting; 2.x is the supported line. + ## [2.2.1] — 2026-10-16 ### Security