Case study · Chrome & Edge extension
A cookie manager that asks for as little access as possible
I designed, built, tested and published Bokal on my own: a Manifest V3 extension for viewing, editing and exporting browser cookies, with paid plans, live on the Chrome Web Store and Microsoft Edge Add-ons.
The problem
EditThisCookie, a cookie editor used by millions of people, was removed from the Chrome Web Store in December 2024. A copycat then took its name and was caught stealing logins. A cookie editor can read your session cookies, which is the same as being able to sign in as you, so the tool you replace it with should ask for as little access as possible and let anyone check what it does.
That set the brief: full cookie editing for developers and QA testers, the narrowest permissions Chrome allows, no tracking, and open source code.
Narrow permissions
The extension requests no access to any website at install time and no tabs permission. When you open it on a site, it asks for that one site. The whole permission block is short enough to read in one glance:
// manifest.json (published build) "permissions": [ "cookies", "storage", "sidePanel", "unlimitedStorage", "alarms", "activeTab" ], "optional_host_permissions": ["<all_urls>"], // no "host_permissions", no "tabs" "content_security_policy": { "extension_pages": "script-src 'self'; object-src 'self'" }
No permission warnings. None of the permissions in this manifest triggers one.
- Read your browsing history (the
tabspermission) - Read and change all your data on all websites (site access at install)
Site access is requested later, one site at a time, when the user opens Bokal on that site. Using activeTab in place of tabs means the user clicks the toolbar button before Bokal can see which site is open.
Cookies other tools miss
- HttpOnly cookies, usually the session cookie, are hidden from page scripts. Bokal reads and writes them through Chrome's cookies API.
- Partitioned (CHIPS) cookies, Chrome's newer per-site cookie jars, get their own inspector. Saved profiles capture them too, so a login stored in one restores completely.
- Audit hints flag missing SameSite, unpartitioned cross-site cookies and oversized values in the list.
Built for test automation
Developers can sign in by hand once and move the session straight into a test suite, without scripting the login. Bokal imports and exports:
- JSON
- Netscape cookies.txt
- Cookie header
- Playwright storageState
- Playwright addCookies
- Puppeteer setCookie
It also reads exports from Cookie-Editor and EditThisCookie, so switching over takes one file.
Payments without tracking
Bokal's paid tier saves cookie profiles: named sets of a site's cookies you can switch between, such as separate test accounts. Payments run through Stripe using ExtensionPay, with one-time, yearly and monthly plans and a restore-purchase path for a new computer.
- Free users make no network calls. The payment service is contacted only after someone clicks Unlock Pro or Restore purchase. An end-to-end test asserts this in a real browser.
- The profiles code loads on demand. Encryption and storage code sits in a separate chunk, and a CI check fails the build if it ever leaks into the main bundle.
- Profiles stay on the device, optionally encrypted with AES-GCM and a key derived with PBKDF2 (600,000 iterations).
- From version 1.2, one profile is free and the price is shown before any click.
Testing
Every change runs through GitHub Actions: type-checking, unit tests, a production build, the bundle check, and end-to-end tests against two builds of the extension.
| Layer | Count | What it proves |
|---|---|---|
| Unit tests (Vitest) | 178 | Parsers for every import format, permission logic, encryption, the free-tier limit, billing state |
| End-to-end tests (Playwright) | 7 | The real extension in Chromium on a real local site: create, edit, protect and delete cookies; a full purchase flow against a mocked payment server; a wrong passphrase deleting nothing |
| Privacy assertions | in the 7 | A free user makes no request to the payment service and writes no synced storage; the profiles code isn't loaded until it's needed |
The tests added in 1.2 were mutation-tested: deliberately breaking the on-demand loading makes them fail.
Getting through store review
- Listings on the Chrome Web Store and Microsoft Edge Add-ons, with in-app purchases disclosed
- A hosted privacy policy, data-use disclosures that match the code, and a written justification for each permission
- Checked against the Chrome Web Store policy update enforced from August 2026
- A landing site with guides, search-engine metadata and social preview images
What I can build for you
- New Manifest V3 extensions for Chrome and Edge, from spec to store listing
- Payments and licensing through Stripe
- Store submissions: listing, privacy policy, disclosures, permission review
- End-to-end tests that load your extension in a real browser
The fastest way to reach me is the platform where you found this page.