diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 6b0f56f..98d1f1e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -7,20 +7,60 @@ on: permissions: contents: read - # Required for npm trusted publishing (OIDC) and provenance attestations - id-token: write - -env: - HYPHEN_PUBLIC_API_KEY: ${{ secrets.HYPHEN_PUBLIC_API_KEY }} - HYPHEN_API_KEY: ${{ secrets.HYPHEN_API_KEY }} - HYPHEN_APPLICATION_ID: ${{ secrets.HYPHEN_APPLICATION_ID }} - HYPHEN_ORGANIZATION_ID: ${{ secrets.HYPHEN_ORGANIZATION_ID }} - HYPHEN_LINK_DOMAIN: ${{ secrets.HYPHEN_LINK_DOMAIN }} jobs: + aikido-gate: + runs-on: ubuntu-latest + # A stalled scan stops after 15 minutes. + timeout-minutes: 15 + permissions: + contents: read + steps: + - name: Install Socket Firewall + uses: SocketDev/action@ba6de6cc0565af1f42295590380973573297e31f # v1.3.2 + with: + mode: firewall-free + firewall-version: "1.15.4" + + - name: Set up Node.js + uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0 + with: + node-version: 22 + package-manager-cache: false + + - name: Install Aikido CI client + # zizmor: ignore[adhoc-packages] pinned Aikido CI client for the release gate + run: sfw npm install --global @aikidosec/ci-api-client@1.0.17 + + - name: Run Aikido release scan + # The scan fails when Aikido reports a new finding at severity LOW or above. + # The API key comes from the Aikido CI settings. + # The key cannot publish a package. + env: + REPO_NAME: ${{ github.event.repository.name }} + AIKIDO_CLIENT_API_KEY: ${{ secrets.AIKIDO_CLIENT_API_KEY }} + run: > + aikido-api-client scan-release + "$REPO_NAME" "$GITHUB_SHA" + --apikey "$AIKIDO_CLIENT_API_KEY" + --fail-on-sast-scan --fail-on-iac-scan --fail-on-secrets-scan + --minimum-severity-level LOW + build: + needs: [aikido-gate] runs-on: ubuntu-latest + permissions: + contents: read + # OIDC lets this job stage the package. + id-token: write + + env: + HYPHEN_PUBLIC_API_KEY: ${{ secrets.HYPHEN_PUBLIC_API_KEY }} + HYPHEN_API_KEY: ${{ secrets.HYPHEN_API_KEY }} + HYPHEN_APPLICATION_ID: ${{ secrets.HYPHEN_APPLICATION_ID }} + HYPHEN_ORGANIZATION_ID: ${{ secrets.HYPHEN_ORGANIZATION_ID }} + HYPHEN_LINK_DOMAIN: ${{ secrets.HYPHEN_LINK_DOMAIN }} steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 diff --git a/DEFENSE_IN_DEPTH.md b/DEFENSE_IN_DEPTH.md index 4ef9de9..5e1d03a 100644 --- a/DEFENSE_IN_DEPTH.md +++ b/DEFENSE_IN_DEPTH.md @@ -38,7 +38,7 @@ Profile: npm library · public ## 5. npm publishing — npm libraries only - [ ] OIDC trusted publishing configured **stage-only** on npmjs.com for the publish workflow — it can stage, never publish live (manual) -- [ ] `.github/workflows/release.yaml` packs then stages with `pnpm stage publish ./packed/*.tgz --no-git-checks` (PR #170 pending) +- [x] `.github/workflows/release.yaml` packs then stages with `pnpm stage publish ./packed/*.tgz --no-git-checks` — PR #170 - [ ] Maintainer promotes staged versions with 2FA (manual) - [ ] Drydock connected — staged releases reviewed before promotion (manual) - [ ] No direct publish rights: package requires 2FA and disallows tokens (manual) @@ -46,7 +46,7 @@ Profile: npm library · public ## 6. Security tooling - [x] Aikido runs on every build — verified 2026-10-08 -- [ ] Aikido release gate: the release workflow's stage-publish job `needs:` a passing `scan-release` +- [ ] Aikido release gate: the release workflow's stage-publish job `needs:` a passing `scan-release` (PR #171 pending) - [ ] Socket reviews every PR that changes dependencies ## 7. Repository lockdown