A Chrome/Chromium browser extension that handles the KAIST SSO 2FA push authenticator inside the browser, so you don't have to reach for your phone every time you log in.
When you arrive at the KAIST SSO login page, Kaikey fills in your ID and submits the form. When the 2FA challenge page appears, Kaikey reads the displayed two-digit code, asks the auth server for the pending challenge, and approves it automatically when the numbers match. KLMS' SSO redirect page is also clicked through automatically.
You can turn auto-login off and approve manually from the popup instead. The extension keeps a per-device key locally; no data leaves your machine other than what KAIST's normal mobile authenticator would already send.
- One-time setup: open the KAIST registration page from the popup, complete registration, then upload the QR-code screenshot. Kaikey decodes it, runs the registration handshake, and stores the device key in extension-local storage.
- Auto-login (default on): on the SSO login page, fill the ID and click the login button. On the 2FA page, read the displayed code, fetch the pending challenge, and approve it if it matches.
- KLMS support: on
https://klms.kaist.ac.kr/login/ssologin.php, follows the SSO redirect link automatically. - Manual mode: turn auto-login off and use the "Check for login requests" button in the popup to fetch the challenge and pick the matching number yourself. Useful when the request was started from another device.
- Logout removes the registered device from local storage. To stop the device from being recognized server-side, also remove it from the KAIST device list.
There are two ways to install Kaikey. Most people should pick option 1.
Install from the official listing:
https://chromewebstore.google.com/detail/kaikey/pfhelcneioomfmnmnagfpmfggknikbaa
Click "Add to Chrome" and pin Kaikey from the puzzle-piece menu.
The Chrome Web Store build is produced from this exact repository at the
tagged commit, so it is byte-for-byte equivalent to a local pnpm build.
But if you would rather not trust the published artifact, you can build it
yourself:
pnpm install
pnpm buildThen in Chrome:
- Open
chrome://extensions. - Enable Developer mode.
- Click "Load unpacked" and pick
build/chrome-mv3-prod. - Pin Kaikey from the puzzle-piece menu.
Requires Firefox 128+. The extension relies on
chrome.scripting.executeScript({ world: "MAIN" }) to drive the SSO
page's loginProcMfa() call, which Firefox ships in 128 and later.
pnpm install
pnpm build:firefoxThen in Firefox:
- Open
about:debugging#/runtime/this-firefox. - Click "Load Temporary Add-on…" and pick
build/firefox-mv3-prod/manifest.json. - Open
about:addons, find Kaikey, and grant host permissions forsso.kaist.ac.krandklms.kaist.ac.kr— Firefox MV3 does not auto- grant host permissions even when they are listed in the manifest.
Temporary add-ons are removed on Firefox restart. For persistent install
without going through AMO, use Firefox Developer Edition / Nightly / ESR
with xpinstall.signatures.required=false, then package with
pnpm dlx web-ext build --source-dir=build/firefox-mv3-prod and install
the resulting .zip (renamed to .xpi).
- Click the Kaikey icon to open the popup.
- Click "Open registration page" and complete the KAIST 2FA registration
flow (
sso.kaist.ac.kr/auth/twofactor/mfa/regist/...). - The last step shows a QR code. Take a screenshot of it.
- Back in the popup, click "Upload QR screenshot" and pick the image.
- The popup will switch to the registered view once the handshake succeeds.
After that, visit any KAIST page that redirects through SSO. Kaikey logs you in.
pnpm devLoads build/chrome-mv3-dev with hot reload. Chrome 130+ will show a Local
Network Access prompt on KAIST pages because Plasmo's dev runtime opens a
WebSocket to localhost for HMR. Either allow it for the relevant origins, or
just use the prod build for normal testing.
pnpm build produces build/chrome-mv3-prod, which has no HMR runtime and no
loopback connections.
For Firefox, use pnpm dev:firefox / pnpm build:firefox, which emit
build/firefox-mv3-dev and build/firefox-mv3-prod respectively.
src/popup.tsx– setup + registered popup screens (shadcn-ish UI on Tailwind).src/background.ts– central protocol handler. Receives messages from the popup and content scripts, runs the registration / auth-check / approve calls, and dispatcheschrome.scripting.executeScriptinto the page's main world when needed.src/lib/auth/– TypeScript port of the underlying push-authenticator protocol: LEA-128 + RSA-OAEP envelope encryption, ECDSA P-256 P1363 signing, and the verification-number derivation used by the 2FA challenge.src/lib/state.ts– local storage wrapper for the device key + auto-login setting.src/contents/login-page.ts– content script for the SSO login page.src/contents/twofactor-page.ts– content script for the 2FA challenge page.src/contents/klms-sso-redirect.ts– content script for the KLMS SSO redirect page.
- The device's EC private key is stored in
chrome.storage.local. It never leaves the extension. - Network calls to
sso.kaist.ac.krare made from the background service worker so the page's CSP and CORS rules don't apply. - Approval requires the displayed digits on the 2FA page to match the digits the extension derives from the server challenge. Without that match the extension does not call the approve endpoint.
MIT.
