Skip to content

Add release guardrails: permission lock, secret scan and version gate - #5

Open
EnesYilmazcode wants to merge 13 commits into
mainfrom
rebuild/p0-guardrails
Open

EnesYilmazcode wants to merge 13 commits into
mainfrom
rebuild/p0-guardrails

Conversation

@EnesYilmazcode

@EnesYilmazcode EnesYilmazcode commented Sep 24, 2026 •

Copy link
Copy Markdown
Owner

Stack, merge in order: #5 (this one) > #6 > #7 > #8 > #9.
The proscan-web stack: EnesYilmazcode/proscan-web#1, EnesYilmazcode/proscan-web#2.

First of five stacked PRs from the rebuild audit. This one adds the checks that keep a release from going wrong, before anything else changes.

The source manifest had drifted from what the store ships: 9 host permissions against the live 2 (F-01, F-02). Uploading it would have shown every user a new permission warning and disabled the extension until they re-approved. The live v2.0 manifest is now checked in as tools/live-manifest.json, and a lock script fails if the source or built manifest adds a permission, host, match pattern or access key over it. It also fails on any new top-level manifest key outside a short safe list (version_name, minimum_chrome_version and the like), so a key such as chrome_settings_overrides cannot slip through. Hosts are trimmed back to amazon.com and generativelanguage.googleapis.com.

Also here: the embedded Gemini key is removed and a secret scan runs on every file (F-61, F-62). The version is gated against the live one (F-04). Dev and prod builds are separate, so the emulator flag cannot leak into a store build (F-06, F-08). The zip builder refuses a dev build, a dirty tree or a failed gate (F-05, F-09, F-09b, F-09c); node tools/zip.mjs --allow-dirty builds a -dirty zip for local tries. CI runs all of it (F-83).

Tested: npm test (253 jest, 32 tool tests) and npm run check pass. node tools/zip.mjs passes all gates on a clean prod build, and refuses a dev build and uncommitted changes.

Does not change permissions. It only removes hosts:

[permission-lock] OK manifest.json
[permission-lock] OK dist\manifest.json
[version-gate] OK: 2.1.0 > live 2.0

The old key is still in git history and in the live 2.0 CRX, so it has to be revoked in GCP.

Copied from the 7c2ba1c tree, which matches the published CRX except for
the update_url key the store adds.
Fails on any added permission, optional permission, host, content script
or web_accessible_resources match, or a new externally_connectable key.
Removals pass.
The Firebase Auth, token and Firestore endpoints answer CORS for the
extension origin, so they only need CSP connect-src entries. Gemini is
added to connect-src so the chatbot fetch is not blocked. Dev hosts,
www.googleapis.com, *.firebaseapp.com and wasm-unsafe-eval are dropped.
The key is revoked, so every chat request was failing with it anyway.
With no user key set, the worker now returns a plain error the chat
bubble shows. Bring-your-own-key comes back with the chatbot fix.
Decodes long base64 runs too, which is how the old Gemini key was hidden.
The Firebase web config key is a public identifier and is allowlisted by
exact value.
The prod build writes manifest.json as is and refuses one that mentions a
local host. PROSCAN_ENV=dev adds only the two emulator origins to CSP
connect-src and sets a literal __PROSCAN_EMULATOR__ that esbuild folds, so
the dev build really uses the emulators under demo-proscan and the prod
bundle carries no emulator code. The old process.env check was always
false inside the service worker.
The manifest closure never looked inside popup.html, so a missing popup
script passed the build.
Zips now go to dist-zips/ named with the version and commit, so they can
no longer be mistaken for the live build. Markdown, zips, sourcemaps and
dev builds are refused.
Load unpacked has to point at dist/, and the clone URL was a 404.
The zip builder now exits nonzero on uncommitted changes unless
--allow-dirty is passed. The permission lock fails on any new top-level
manifest key that is not in the live manifest or a short safe list, so
keys like chrome_settings_overrides cannot pass unnoticed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant