Files
SeedPass/.github/workflows/release-integrity.yml
T
thePR0M3TH3ANandClaude Fable 5 a1df3cfde0 security: keep secrets off argv, fix packaging, add JS supply-chain CI
Secret input:
- Values that are secrets can now be read from stdin: `entry add key-value
  --stdin`, `entry add totp --secret-stdin`, `entry add document --stdin`,
  and `entry modify --value-stdin`. Arguments are visible in shell history
  and process listings, so the positional forms now warn (without echoing
  the secret they are warning about) rather than silently accepting.

Packaging (the published package was broken):
- `exports` pointed at src/index.ts while `files` shipped only dist/, so an
  installed package had no entry point; exports now points at the bundle.
- A `workspace:*` runtime dependency would have failed any real install. The
  bundle inlines everything, so the package now declares no runtime
  dependencies at all. Verified by packing the tarball, installing it into a
  clean project and running the binary -- and CI now does the same on every
  change, because this class of mistake is invisible to build and test.
- The workspace globs cover apps/* so a future extension cannot sit outside
  CI.
- @types/node aligned with the advertised Node 22 runtime.

Release and supply chain:
- release-integrity now builds the CLI bundle into dist/ before checksums
  are generated and signed, so the executable TypeScript artifact is covered
  by the same manifest and cosign signature as the Python ones.
- A new javascript-supply-chain job runs `pnpm audit` and produces a
  CycloneDX SBOM; the JS tree previously had neither.

Also documents two findings that are protocol-level and shared with Python,
where changing the port alone would break convergence: tombstone retention
allowing deletion replay after the 2048-entry cap, and SSH/PGP sharing a
derivation domain (same index yields the same Ed25519 key). Both need a
versioned change in both implementations and are recorded in the
compatibility matrix rather than silently patched here.

193 core + 70 CLI tests green; pnpm audit clean.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-14 23:13:21 -04:00

90 lines
2.6 KiB
YAML

name: Release Integrity
on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: write
id-token: write
jobs:
verify-and-sign:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Validate lockfile and install dependencies
run: |
python -m pip install --upgrade pip
pip install pip-tools pip-audit build
python scripts/release_integrity.py check-lockfile --lockfile requirements.lock
pip-compile --generate-hashes --output-file=requirements.lock src/requirements.txt
git diff --exit-code requirements.lock
pip install --require-hashes -r requirements.lock
- name: Run CVE audit
run: pip-audit -r requirements.lock --ignore-vuln GHSA-wj6h-64fc-37mp --ignore-vuln CVE-2025-62727
- name: Build release artifacts
run: python -m build
# The TypeScript CLI is an executable release artifact and must be
# covered by the same checksum manifest and signature as the Python
# ones; building it only as a CI artifact left it outside the signed
# release path entirely.
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Build the TypeScript CLI bundle
run: |
corepack enable
cd js
pnpm install --frozen-lockfile
pnpm --filter @seedpass/cli build
cp packages/cli/dist/seedpass-js.mjs ../dist/
- name: Generate and verify checksums
run: |
python scripts/release_integrity.py generate --artifact dist --base-dir . --output SHA256SUMS
python scripts/release_integrity.py verify --checksum-file SHA256SUMS --base-dir .
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Sign checksum manifest (keyless)
env:
COSIGN_EXPERIMENTAL: "1"
run: |
cosign sign-blob --yes \
--output-signature SHA256SUMS.sig \
--output-certificate SHA256SUMS.pem \
SHA256SUMS
- name: Upload release assets
if: github.event_name == 'release'
uses: softprops/action-gh-release@v2
with:
files: |
dist/*
SHA256SUMS
SHA256SUMS.sig
SHA256SUMS.pem
- name: Upload integrity artifacts (manual runs)
if: github.event_name != 'release'
uses: actions/upload-artifact@v4
with:
name: release-integrity
path: |
dist/*
SHA256SUMS
SHA256SUMS.sig
SHA256SUMS.pem