Skip to content

chore(main): release 2.3.1 - #253

Merged
chrischall merged 1 commit into
mainfrom
release-please--branches--main--components--fetchproxy
Aug 31, 2026
Merged

chrischall merged 1 commit into
mainfrom
release-please--branches--main--components--fetchproxy

Conversation

@chrischall

Copy link
Copy Markdown
Owner

🤖 I have created a release beep boop

2.3.1 (2026-08-31)

Bug Fixes

  • extension: re-inject content scripts after an update, not on next reload (#251) (57ff992)

This PR was generated with Release Please. See documentation.

@chrischall chrischall added the release-ready Starts auto-review on a release PR label Aug 31, 2026
@github-actions github-actions Bot added the auto-review Auto-review pipeline is handling this PR label Aug 31, 2026
@claude

claude Bot commented Aug 31, 2026

Copy link
Copy Markdown

No issues found. Standard release-please version-bump PR (2.3.0 → 2.3.1) — mechanical, lockstep changes across all workspace package.json files, .release-please-manifest.json, CHANGELOG.md, and the generic-updater-managed packages/cli/src/version.ts. No hand-authored logic changed.

Verdict: pass

@github-actions

Copy link
Copy Markdown
Contributor

✅ Auto-review verdict: pass — Standard release-please version-bump PR (2.3.0 → 2.3.1); mechanical, lockstep, no hand-authored logic changes. No issues found.

@chrischall chrischall added the ready-to-merge Arms auto-merge — added by the pipeline on a pass/warn verdict, never by hand label Aug 31, 2026
@chrischall
chrischall enabled auto-merge (squash) August 31, 2026 22:13
@chrischall
chrischall merged commit 8ac3ec3 into main Aug 31, 2026
19 checks passed
@chrischall
chrischall deleted the release-please--branches--main--components--fetchproxy branch August 31, 2026 22:14
@chrischall

Copy link
Copy Markdown
Owner Author

🤖 Created releases:

🌻

chrischall added a commit that referenced this pull request Sep 23, 2026
…t-writable storage (#395)

## What was wrong

The extension kept two kinds of security-critical state in
`chrome.storage.local`. Content scripts can read and write that area, so
a compromised renderer could reach it.

- **#253: identity private keys.** The extension's X25519/Ed25519
identity private keys were stored in `chrome.storage.local`, so any
content script could read them.
- **#252: MCP trust records.** Trust records, remote bridges and
dismissed scope hashes also lived in `chrome.storage.local`. A
compromised renderer could plant a trust record to forge a pairing, or
delete one to revoke it.

## What changed

- **Identity keys.** The keys now live in an extension-origin IndexedDB
vault as non-extractable WebCrypto `CryptoKey`s. Content scripts cannot
open that vault, and even the extension cannot export the raw key bytes.
- **Trust, bridges and dismissals.** These are now read only from the
vault. `TrustStore.load`, the remote-bridge dial list
(`loadRemoteLinks`) and the dismissed-scope lookup in `onServerHello`
ignore anything a page plants in `storage.local`.
- **Migrating existing data.** Legacy `storage.local` identity, trust,
bridges and dismissals are imported once, and only when an `onInstalled`
update event arrives while the vault still holds no identity.
`noteInstalled` records that permission in `chrome.storage.session`,
which content scripts cannot reach. The legacy keys are purged after the
import. If the vault is lost at any other time, the extension mints a
fresh identity and does not import from `storage.local`, so a page
cannot plant an identity for it to adopt.
- **Release ordering.** Pairings survive the upgrade whichever of this
PR and release PR #394 (3.2.1) ships first. The import is triggered by
any `onInstalled` update onto a still-empty vault, not by a hardcoded
last-legacy version.
- **Docs.** `docs/SECURITY.md` (Defense 4, Migration, T-fake-extension),
`docs/PRIVACY.md` and `docs/PROTOCOL.md` are updated to match.

## Behaviour changes

- On the first update to this build, existing pairings are carried over
into the vault and the legacy `storage.local` copies are removed.
- An extension update onto a vault that already has an identity writes
no migration flag to `chrome.storage.session`.
- Exported API change in `@fetchproxy/extension-core` vault-migration:
`LAST_LEGACY_VERSION` and `isLegacyUpgrade` are removed and
`isExtensionUpdate` is added. Both are internal migration helpers.
- Fails safe: pairings can still be lost in a few edge cases. For
example, the worker dies before `noteInstalled` writes the session flag,
or the popup is opened between the update and `onInstalled`. In those
cases a fresh identity is minted and the user has to re-pair. The
extension never falls back to trusting `storage.local`.

## What the owner needs to do

- **Before release, test the upgrade by hand in real Chrome.** Install
3.2.0 or 3.2.1, pair, then update to this build. `fake-indexeddb` cannot
show that Chrome saves non-extractable Ed25519/X25519 `CryptoKey`s to
IndexedDB and reads them back as `CryptoKey` with `extractable=false`.
If that round trip fails, the extension cannot load its identity on any
later wake.

## Verification

- Root `npm run build`: exit 0.
- `npm run typecheck` (`tsc -b` across
protocol/server/bootstrap/cli/extension-core/test-helpers): exit 0.
- `npm test`: 174 files, 2158 tests passed. `packages/extension-core`
alone: 46 files, 589 tests.
- TDD: the new tests failed before the implementation.
- Mutation checks each broke tests:
  - removing the vault-identity guard in `noteInstalled`
  - merging `storage.local` trust in `TrustStore.load` (2 failures)
  - importing on any empty vault (7)
  - generating an extractable Ed25519 key (9)
- Not run locally: the manual Chrome upgrade test above. CI runs no
prettier/lint step. The docs and `boot.ts` files this PR touches were
already failing prettier on `main`, and every file new on this branch is
prettier-clean.

## Follow-ups (non-blocking)

- Add worker-level tests for the #252 call sites. They should plant rows
in `storage.local`, then assert that `loadRemoteLinks` dials nothing and
that `onServerHello` still queues the scope update. The code is correct
today, but only the vault-record helpers are tested directly.
- Fix the Chrome version floor. `minimum_chrome_version` is 102, but
WebCrypto Ed25519/X25519 needs a newer Chrome, so the docs' "Chrome <
102" fail-closed note understates the real floor. This predates this
branch.

Reviewed by an independent reviewer agent before opening.

Closes chrischall/fleet-audit#253
Closes chrischall/fleet-audit#252

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01AAur3ToRuUEBQMSCyYffhX

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auto-review Auto-review pipeline is handling this PR autorelease: tagged ready-to-merge Arms auto-merge — added by the pipeline on a pass/warn verdict, never by hand release-ready Starts auto-review on a release PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant