mirror of
https://github.com/PR0M3TH3AN/bitlogin.git
synced 2026-11-07 22:10:52 +00:00
Second-audit hardening: phrase-gated sudo key, deterministic migration, policy tests
Authored by ChatGPT/Codex in a separate review pass. Reviewed and verified here before committing rather than taken on trust; findings below. The substantive change is that the vault sudo key now lives ONLY in the phrase-gated recovery capsule. A newly written password credential capsule carries just connection_vault_root, so an ordinary login restores connectable-tier records without putting personal-tier material behind a password capsule that is downloadable and therefore offline-guessable forever. Pre-hardening capsules stay readable, password login does not return their sudo key, and the next rotation scrubs it. That closes the gate this project had explicitly set on personal-tier UI. Legacy vault-enable migration now derives roots deterministically from phrase-protected material and account_id, so two concurrent attempts cannot mint divergent roots -- the failure mode the docs previously mitigated with "enable the vault once, from one device". Manual (user-chosen) passwords are REMOVED, not merely discouraged, and a new securityPolicy.test.ts pins that along with several things tests do not usually reach: the deployment CSP (default-src 'none', frame-ancestors 'none') plus six baseline headers, demo pages free of inline scripts and remote fonts, and README documenting same-origin self-hosting only rather than a remote demo embed. llms.txt was updated to match, which I checked because that test only reads README. What I verified, since a passing suite proves less than it appears to: - All 12 fixes from the 2026-07-30 audit survived the rewrite of recover.ts, changePassword.ts, validation.ts, relay.ts, session.ts and element.ts. Checked semantically where grep cannot help: changePassword still checks publish success BEFORE building the tombstone, and vaultSetBinding still unbinds on origin === null rather than silently rebinding to the worker global. - No dependency changes; the package.json diff is scripts only. - Argon2id and KDF parameters unchanged. The NIP-44 diff ADDS a base64 length cap before decoding, a memory-DoS guard. - Validation increased rather than decreased: 44 throws added, 33 removed. - No disabled or skipped tests, no secrets in the diff. typecheck clean, 165/165 tests, build green, and the account manager exercised in a browser: creation correctly refused when relay quorum could not be met, and on retry failed at the recovery capsule with "No login credential was published" -- the §18.1 fail-closed ordering doing its job against a flaky public relay set. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01CMr9Yt8SYmZcfgrg3CV2G1
This commit is contained in:
1 parent
efd994c4de
commit
7d2209d706
56 files changed
+3597
-1318
No files matched your search
@@ -0,0 +1,54 @@
|
||||
name: Security and release integrity
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
verify:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
- run: npm ci --ignore-scripts
|
||||
- name: Run build, typecheck, tests, dependency audit, and registry signature verification
|
||||
run: npm run security:ci
|
||||
- name: Generate checksums and CycloneDX SBOM
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p security-artifacts
|
||||
npm sbom --sbom-format cyclonedx > security-artifacts/sbom.cdx.json
|
||||
find packages/widget/dist packages/demo/dist -type f -print0 | sort -z | xargs -0 sha256sum > security-artifacts/SHA256SUMS
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: bitlogin-security-artifacts
|
||||
path: security-artifacts/
|
||||
if-no-files-found: error
|
||||
|
||||
static-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
- name: Install pinned Semgrep
|
||||
run: pipx install semgrep==1.171.0
|
||||
- name: Scan repository rules without per-rule timeouts
|
||||
run: semgrep scan --config auto --error --timeout 0 packages
|
||||
- name: Scan repository history for secrets
|
||||
uses: gitleaks/gitleaks-action@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
Reference in new issue
Block a user