The official web browser of the Southbag Global Enterprise Network.
A tabbed web browser built on Electron, styled after Southbag Online Banking and Southbag Terminal. It requires a Southbag account, charges you a cent per page, and is, against all odds, a perfectly usable daily browser. The jokes live in the chrome. Web pages are left exactly as their authors intended.
- Tabs: open, close, drag to reorder, middle-click to close, reopen closed tabs, favicons and loading spinners, ⌘/Ctrl+1–9.
- Omnibox: type a URL or a search. Back, forward, reload/stop and home buttons, all of them far too small.
- Multiple windows, and Incognito* windows on a throwaway session that is wiped when the window closes. (*Kevin can still see you.)
- Mandatory Southbag login: no tab opens until Southbag Identity has verified your account. When you log out, or Identity stops accepting your session, every tab in every window is closed.
- Southbag sites open already logged in (see Single sign-on).
- Bookmarks bar preloaded with every Southbag app: Southbag, Banking, Drive, Office, Git, Social, Code, Support, Lore, Docs, Branch Locator and Identity. These cannot be removed; the option is there, disabled, with a tooltip explaining why you shouldn't want to. Your own bookmarks come and go as you like.
- History, downloads (with progress), find in page, zoom and print ("Print to Branch…", which prints).
southbag://pages:newtab,settings,history,bookmarks,downloads,aboutandterminal.- New tab page in the banking style: your balance from
/api/account, announcements, a dismissible Southbag offer, your Rewards, and Southbag Search, which hands your query to a real search engine of your choosing (DuckDuckGo by default; Google, Bing, Brave, Startpage, Ecosia, Kagi or a custom URL in Settings). - Southbag Secure™ padlock:
*.southbag.ccgets a gold Verified Enterprise badge. Everything else is Not Southbag (Unsafe), and the first visit to each site in a session gets a full-page warning you must click through ("I accept the risk of using the open web"). Real TLS errors get a separate, serious certificate warning. - Ad blocker: requests to a bundled list of ad and tracker domains (
src/main/blocklist.txt) are blocked, with a counter in the status bar. Southbag's own offers appear only on the new tab page and in the status bar, never inside other people's pages. - Kevin: a support sidebar backed by banking's
/api/chat, with a Summarise this page button that is deliberately unhelpful. Page text is sent only when you press it. - Browsing fees: one cent per page load, billed to your Southbag account through the banking economy's
feeaction, with a ticker in the status bar and an off switch in Settings. - Southbag Rewards: one point for every 10 seconds on a Southbag site. Redeemable for nothing.
- Open in Southbag Terminal (menu, context menu and
southbag://terminal) launches Southbag Terminal if it is installed. - Default browser: registers for
http,httpsand HTML files, and asks on launch with a big Yes and a tiny no. "Don't ask again" works. - Privacy button in the address bar, which opens our privacy dialog. It is blank. That is the policy.
- "Kevin is watching" status bar, and a dark mode that works (for the chrome and Southbag's own pages; websites are not restyled).
- App windows:
--app=<url>opens one site in its own chrome-less window — no tab strip, no omnibox, the page fills the window. This is how Southbag OS launches services: every app is a real top-level window, not an iframe. (See App windows.)
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
| Action | macOS | Linux |
|---|---|---|
| New tab | ⌘T | Ctrl+T |
| New window | ⌘N | Ctrl+N |
| New Incognito* window | ⌘⇧N | Ctrl+Shift+N |
| Close tab | ⌘W | Ctrl+W / Ctrl+F4 |
| Close window | ⌘⇧W | Ctrl+Shift+W |
| Reopen closed tab | ⌘⇧T | Ctrl+Shift+T |
| Next / previous tab | ⌘⇧] / ⌘⇧[ (or ⌃Tab / ⌃⇧Tab, ⌘⌥→ / ⌘⌥←) | Ctrl+Tab / Ctrl+Shift+Tab (or Ctrl+PgDn / Ctrl+PgUp) |
| Go to tab 1–8 / last tab | ⌘1–8 / ⌘9 | Ctrl+1–8 / Ctrl+9 |
| Address bar | ⌘L | Ctrl+L / Alt+D / F6 |
| Back / forward | ⌘[ / ⌘] | Alt+← / Alt+→ |
| Home (new tab page) | ⌘⇧H | Alt+Home |
| Reload / force reload | ⌘R / ⌘⇧R | Ctrl+R or F5 / Ctrl+Shift+R |
| Stop loading | Esc | Esc |
| Find / next / previous | ⌘F / ⌘G / ⌘⇧G | Ctrl+F / Ctrl+G or F3 / Ctrl+Shift+G or Shift+F3 |
| Zoom in / out / reset | ⌘= / ⌘- / ⌘0 | Ctrl+= / Ctrl+- / Ctrl+0 |
| Print to branch | ⌘P | Ctrl+P |
| Bookmark this page | ⌘D | Ctrl+D |
| Show bookmarks bar | ⌘⇧B | Ctrl+Shift+B |
| Bookmark manager | ⌥⌘B | Ctrl+Shift+O |
| History | ⌘Y | Ctrl+H |
| Downloads | ⌘⇧J | Ctrl+J |
| Kevin sidebar | ⌘⇧K | Ctrl+Shift+K |
| Settings | ⌘, | Ctrl+, |
| Full screen | ⌃⌘F | F11 |
| Developer tools | ⌥⌘I | Ctrl+Shift+I / F12 |
| Quit | ⌘Q | Ctrl+Q |
Unlike Southbag Terminal, the browser uses the plain Ctrl shortcuts on Linux, as every other Linux browser does: there is no shell underneath that needs them.
Login follows the same pattern as Southbag Terminal (src/main/auth.js is the terminal's, nearly verbatim): OAuth 2.1 with PKCE against identity.southbag.cc, using a public client registered through dynamic client registration and a loopback redirect per RFC 8252.
- The app starts a loopback server on
127.0.0.1(preferring port 47619) and registers a client for that redirect URI the first time it's used. - Identity's authorize page opens in a Southbag Identity window inside Southbag Browser, on the same session your tabs use. You log in (or reuse your existing session) and approve Southbag Browser.
- Identity redirects back to the loopback server. The app exchanges the code for tokens and loads your profile from
/oauth2/userinfo. - Tokens are stored in the app's user-data directory, encrypted with the OS keychain (Electron
safeStorage). They're refreshed automatically and checked again every 5 minutes.
If Identity can't be reached at launch, the browser stays locked: an account that can't be verified gets no web.
The terminal uses the system browser for step 2; Southbag Browser is the system browser, so it does the login itself, in its own browsing session. Identity sets its session cookie on .southbag.cc (Better Auth's cross-subdomain cookies), so after logging in to the browser that cookie is already in the tabs' cookie jar. Any Southbag app that sends you through Identity finds you logged in and comes straight back, without a prompt (Identity skips consent for first-party apps). The Banking bookmark points at banking.southbag.cc/auth/onboard, which does exactly that hop and lands on your dashboard.
Logging out revokes the refresh token, asks Identity to end the web session, and deletes every *.southbag.cc cookie, so single sign-on ends with the browser session. Incognito* windows have their own empty cookie jar and do not share the login with Southbag sites.
The browser talks to Southbag Online Banking the way Southbag Mobile does: from the main process, with the Identity access token as Authorization: Bearer … (see session() in banking's worker.js).
| Endpoint | Used for |
|---|---|
GET /api/account |
Balance and recent transactions on the new tab page |
POST /api/chat |
Kevin. The browser sends its own system prompt plus the conversation; "Summarise this page" adds the visible text of the current page (at most 4,000 characters), only when pressed. If the bank's AI is down, Kevin answers locally. |
POST /api/economy { action: "fee", amount, reason } |
Browsing fees. The economy's generic fee action charges any amount (in dollars) with a reason. Page loads are counted locally and billed in one batch every 20 seconds, so the bank isn't hit on every click; the reason never contains a URL. If the bank can't be reached, fees stay pending locally and are billed later. |
Set SOUTHBAG_BANKING_URL to use a different banking instance.
Copied from Southbag Terminal: the same PostHog project, proxied through palantir.southbag.cc, with the super property southbag_app: "browser", events batched in the main process (src/main/palantir.js) and identified by Identity sub.
What's captured:
- App lifecycle, windows, login, logout, and system events (as in the terminal)
- Tabs: opened, closed, switched, reordered, reopened (counts, sources, lifetimes)
- Page loads: the kind of page (
southbag,web,file,internal), the name of a built-in page, HTTP status class, load time, private or not - The open-web warning shown / accepted / rejected, certificate errors (the error code), downloads (size, duration), find used, zoom level, printing, bookmarks added (whether Southbag or not), searches (that one happened, and where from), Kevin opened and used, fees charged, Rewards redeemed, settings changed, every chrome button and menu action
- Ads blocked, per minute, as a count
What's never sent: URLs, hostnames, page titles, page content, search queries, form data, keystrokes, chat messages, file names or paths. Only names, counts, sizes and durations leave your machine. Events from the renderer and from built-in pages are filtered in the main process: only numbers, booleans and short name-like strings get through. Set SOUTHBAG_PALANTIR_DISABLED=1 to turn analytics off (for development and tests).
- Linux: the
.desktopfile declaresMimeType=x-scheme-handler/http;x-scheme-handler/https;text/html;application/xhtml+xmlandCategories=Network;WebBrowser;. Saying Yes runsapp.setAsDefaultProtocolClientforhttpandhttps,xdg-settings set default-web-browser southbag-browser.desktopandxdg-mime defaultfor HTML. - macOS: electron-builder writes
CFBundleURLTypes(http, https) andCFBundleDocumentTypes(HTML) intoInfo.plist; saying Yes asks LaunchServices, and macOS shows its own confirmation. - Links arrive through
open-url/open-file(macOS), command-line arguments, andsecond-instance(a single-instance lock keeps one browser running). Links that arrive before you've logged in wait behind the login screen and open afterwards.
southbag-browser --app=https://banking.southbag.cc opens that one site in a window with no tab strip, no omnibox and no bookmarks bar — the page fills the window, and the window title follows the page. Login, single sign-on, Southbag Secure™, browsing fees, Rewards and the ad blocker all work exactly as in a normal window. What changes is the shape:
- One window per site: running
--app=for a site that already has an app window focuses it instead of opening a duplicate. The single-instance lock applies, so the OS launcher can call it as often as it likes. - Single-site by design: "new tab" (menu or Ctrl+T) and links that spawn a window open a normal browser window; the right-click menu also offers "Open Link in App Window". A normal window can turn its current page into an app window with File → Open Current Page in App Window.
- While you're logged out, the app window waits behind the same login screen as everything else and opens its site once you're in.
Southbag OS uses this for its launcher: each service is a real top-level window owned by the browser, so sites keep their own cookies, permissions and full-screen behaviour, and nothing is iframed.
Download a build for your platform from Releases.
| Platform | Formats |
|---|---|
| macOS (Apple silicon, Intel) | .dmg, .zip |
| Linux (x64, arm64) | .AppImage, .deb, .rpm, .tar.gz |
| Windows | Not supported. Please visit a branch. |
macOS builds are unsigned. On first launch, right-click the app and choose Open, or run xattr -cr "/Applications/Southbag Browser.app".
Requires Node.js 22.
npm install
npm startnpm run check # syntax-check every source file
npm test # auth, analytics, URLs, Southbag Secure, ad blocker, store, banking and Kevin tests
npm run dist # package for the current platform into dist/To work without a real Southbag account, run the local stand-in for Identity and Banking and point the browser at it:
node scripts/mock-southbag.js
SOUTHBAG_IDENTITY_URL=http://127.0.0.1:47700 SOUTHBAG_BANKING_URL=http://127.0.0.1:47700 \
SOUTHBAG_PALANTIR_DISABLED=1 npm startnpx electron scripts/make-icons.js regenerates the app icon and the small "s" mark from the logo.
src/main/main.js app lifecycle, login gate, sessions, menus, IPC, downloads, default browser
src/main/shell.js one window: the chrome plus a sandboxed WebContentsView per tab
src/main/auth.js Southbag Identity login (OAuth + PKCE, loopback redirect), from Southbag Terminal
src/main/palantir.js PostHog batching and identification, from Southbag Terminal
src/main/banking.js /api/account, /api/chat, /api/economy, and the fee meter
src/main/secure.js Southbag Secure™ open-web warnings and certificate exceptions
src/main/adblock.js the ad blocker (blocklist.txt is the list)
src/main/kevin.js Kevin's prompts and his offline opinions
src/main/urls.js omnibox parsing, Southbag classification, the Southbag bookmarks
src/main/store.js settings, bookmarks, history, rewards and fees on disk
src/main/system.js launching Southbag Terminal, becoming the default browser
src/main/preload.js the chrome's narrow `window.southbag` API
src/main/tab-preload.js the API for southbag:// pages (and nothing at all for websites)
src/renderer/ login screen, tabs, toolbar, bookmarks bar, Kevin, dialogs, status bar
src/internal/ the southbag:// pages
Every tab is a WebContentsView with contextIsolation, sandbox and no Node integration. Websites get no preload API at all; southbag:// pages get a small one, and the main process checks on every call that the sender is one of our tabs currently showing a southbag:// page. Websites cannot navigate to, redirect to or open southbag:// pages. The chrome draws dialogs over the content area by hiding the page and showing a plain screenshot of it underneath; nothing is ever injected into, or drawn over, a live page.
Push a tag like v1.1.0. The release workflow stamps that version, runs the tests, builds Linux x64 and arm64 on native runners and both macOS architectures on a macOS runner, then publishes a GitHub Release with every artifact and a SHA256SUMS.txt. Tags that contain a - (for example v1.1.0-rc.1) are published as prereleases.
Released into the public domain (Unlicense). No warranty is provided.








