Add release guardrails: permission lock, secret scan and version gate - #5
Open
EnesYilmazcode wants to merge 13 commits into
Open
EnesYilmazcode wants to merge 13 commits into
EnesYilmazcode wants to merge 13 commits into
Conversation
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.
This was referenced Sep 24, 2026
Open
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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-dirtybuilds 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:
The old key is still in git history and in the live 2.0 CRX, so it has to be revoked in GCP.