Self Lock is a Chrome extension that locks selected websites behind a Self Protocol verification flow.
Before visiting certain sites (social media, NSFW, personal email, etc.), you must prove “you’re you” using the Self app. Once verified, all protected sites are unlocked for a time‑limited session. When the timer expires, those sites blur/lock again automatically, even if the tab is still open.
- Self‑gated browsing – Require a Self verification before visiting chosen sites.
- Time‑boxed sessions – Unlock all protected sites for N minutes, then auto‑relock.
- Overlay blur – Protected pages are blurred with a clean “Self Lock enabled” notice.
- Quick site control – One‑click toggle to protect/unprotect the current domain.
- Privacy‑first – Uses Self proofs; extension only sees verification status and basic summary.
chrome-extension/– the actual Self Lock Chrome extensionsrc/background.ts– Manifest V3 service worker managing session + site lock state.src/contentScript.ts– Injected into pages; adds/removes the blur overlay.src/popup/– React + Tailwind popup UI (shadcn-style layout).public/self-icon.png– Extension icon.vite.config.ts/tsconfig.json/tailwind.config.mjs– build & tooling.
server/– optional Express backend that verifies Self proofs- Uses
SelfBackendVerifierfrom@selfxyz/core. - Configured for staging/mock passports with OFAC enabled.
- Uses
banner.png,README.md,.gitignore,prettier.config.cjs– repo metadata and tooling.
The client demo app has been removed to keep this repo focused on the extension.
- Node.js 18+ (Self SDK recommends Node 22; you may see engine warnings on other versions).
- npm (comes with Node).
- Google Chrome or Chromium-based browser with Manifest V3 support.
- A working Self backend (you can use the provided
server/folder or your own).
Self Lock expects a Self verification endpoint that:
- Accepts a proof from the Self app.
- Validates it using
SelfBackendVerifier. - Exposes a small debug endpoint returning the last verification result.
This repo includes a minimal Express backend at server/ that does exactly that.
cd server
npm installCreate server/.env:
PORT=3001
SELF_SCOPE=demo-scope
SELF_ENDPOINT=https://your-ngrok-id.ngrok-free.app/api/verifyPORT– local port for Express.SELF_SCOPE– Self scope; must match the extension’s scope.SELF_ENDPOINT– public URL for/api/verify(e.g. an ngrok URL pointing to this backend).
cd server
npm run devThe backend exposes:
POST /api/verify– main Self verification endpoint.GET /debug/last-result– returns the last verification result (used by the extension to build a friendly summary).
To use the extension from a real device with the Self app:
ngrok http 3001Take the URL (e.g. https://xxxx.ngrok-free.app/api/verify) and plug it into:
SELF_ENDPOINTinserver/.env.VITE_SELF_ENDPOINTinchrome-extension/.env.
The extension lives entirely in chrome-extension/.
cd chrome-extension
npm installCreate chrome-extension/.env (this file is ignored by git; the values below are examples):
VITE_SELF_APP_NAME=Self Lock
VITE_SELF_SCOPE=demo-scope
VITE_SELF_ENDPOINT=https://your-ngrok-id.ngrok-free.app/api/verify
VITE_SELF_DEBUG_ENDPOINT=http://localhost:3001/debug/last-result
VITE_SESSION_MINUTES=20VITE_SELF_APP_NAME– name shown in Self app.VITE_SELF_SCOPE– must matchSELF_SCOPEfromserver/.env.VITE_SELF_ENDPOINT– must matchSELF_ENDPOINTfromserver/.env.VITE_SELF_DEBUG_ENDPOINT– points to the backend’s debug endpoint.VITE_SESSION_MINUTES– default length for a Self session (in minutes).
cd chrome-extension
npm run buildThis produces a dist/ directory with:
manifest.json– extension manifest (MV3).background.js– built background service worker.contentScript.js– built content script.popup.js+index.html– popup UI bundle.assets/*– CSS and shared chunks.self-icon.png– extension icon.
chrome-extension/dist/ is intentionally not committed; regenerate it via npm run build when needed.
- Open
chrome://extensionsin Chrome. - Enable Developer mode (toggle in the top-right).
- Click Load unpacked.
- Select the
chrome-extension/distfolder.
You should now see Self Lock in your extension list with the Self icon.
At a high level:
- The popup lets you:
- Mark the current domain as “protected”.
- See whether your session is Locked or Unlocked.
- Trigger a Self verification by scanning a QR code.
- Adjust the session length and end the session early.
- The background service worker:
- Tracks:
protectedSites– list of hostnames to guard.session–{ verified, expiresAt, verificationSummary }.
- Observes tab updates:
- Whenever a tab finishes loading, decides whether that host should be locked or unlocked.
- Notifies the content script to lock/unlock pages.
- Tracks:
- The content script:
- Blurs protected pages with a high‑z overlay stating “Self Lock enabled”.
- Listens for lock/unlock/session update messages.
- Locally tracks when the session expires (based on
expiresAt) and re‑applies the overlay without requiring a refresh.
All long‑lived state lives in chrome.storage.local so it persists across browser restarts.
-
Start your backend
Ensure the backend in
server/is running and reachable from the extension (ngrok if needed). -
Protect a site
- Navigate to a site you want to gate (e.g.
https://twitter.com). - Click the Self Lock extension icon to open the popup.
- Inside the Current site card, click the pill so it reads “Protected with Self”.
- The page will blur and show the Self Lock overlay.
- Navigate to a site you want to gate (e.g.
-
Verify with Self
- In the popup, scroll to the combined Session section and find the Verify with Self area.
- Open the Self app on your phone (staging/mock passports).
- Scan the QR code.
- On success, the extension calls the backend’s debug endpoint to summarize your verification and creates a session for
VITE_SESSION_MINUTES. - The overlay disappears and all protected sites are unlocked for the duration of the session.
-
Automatic relock
- When the timer expires, the content script detects it and re‑applies the blur overlay on any open protected pages, without requiring a refresh.
-
Manually end session
- From the popup’s Session card, click End session.
- All protected sites immediately blur again until you re‑verify with Self.
-
Manage multiple sites
- Use the Protected sites card at the bottom of the popup to add/remove domains.
- All protected domains share the same Self session (one verification unlocks them all).
- The popup UI is built with React + Tailwind and styled in a shadcn-like dark theme.
- Chrome integration uses:
- Manifest V3 background service worker (
background.ts). chrome.storage.localfor session + config.chrome.tabs,chrome.runtime.onMessagefor messaging between popup, background, and content script.
- Manifest V3 background service worker (
- Self integration uses:
@selfxyz/qrcodefor the QR rendering.@selfxyz/corefor building the universal link and backend verification.
If you tweak backend URLs or scopes, make sure server/.env and chrome-extension/.env stay in sync.
When you’re ready to share the extension:
-
Run a fresh build:
cd chrome-extension npm run build -
Zip the
dist/folder (contents must includemanifest.jsonat the root of the zip). -
Upload that zip to the Chrome Web Store or distribute it manually.
