Open suspicious links in a throwaway browser that lives in your Mac's notch.
Swift
1
1 commits
updated Sep 28, 2026
Open suspicious links in a throwaway browser that lives in your Mac's notch.
Status: 0.1.0, the first release. It works, but it's young. If something breaks, please open an issue.
Some links you'd rather not open. A shortened link in a text from a number you don't know. An "invoice" from a company you've never dealt with. Knotchy opens them somewhere else: a small Linux virtual machine that exists for that one link. The page appears in a panel under the notch, you look at it, and when you're done the whole machine is deleted, along with anything the page did inside it.
The VM can reach the internet. It can't reach your Mac or anything else on your network.
Knotchy-0.1.0.dmg from Releases. It's signed
and notarized, so macOS opens it without warnings.container runtime (version 1.4.1, 118 MB),
checks it against the SHA-256 built into Knotchy, and opens it in Apple's Installer. Click through Installer
and enter your password there. Knotchy never asks for administrator rights itself.If container 1.4 or newer is already installed, Knotchy uses it and goes straight to the build. You can close the
window at any point and setup carries on; Set Up Knotchy… in the menu bar brings it back.
Safari and Mail need nothing extra. Chrome, Edge, Brave and Arc do, because they pass the Services menu a link's text instead of its address. Until the extension is on the Chrome Web Store, install it by hand:
open-in-knotchy-1.0.0.zip from Releases and unzip
it somewhere you'll keep it. (The same files are in extensions/chrome.)chrome://extensions and turn on Developer mode in the top-right corner.The extension has one permission, adding that menu item, and only passes http and https links to the app.
It won't update itself, and deleting the folder removes it from the browser.
Only web links open. Anything else gets a brief "No web link found" in the notch.
The page opens in a panel that drops down from the notch. Scroll, click and type as you would in any browser. The toolbar has back, forward and reload, an address field, and a button that makes the panel bigger.
Click anywhere outside the panel and it folds back into the notch, with a countdown beside it. Hover over the notch to bring the page back. Leave it folded and the VM is destroyed when the countdown runs out, after 5 minutes unless you change it. Destroy in the toolbar, or ⌘W, ends it right away.
Knotchy shows one page at a time. Opening a new link replaces the current VM with a fresh one.
The knot in the menu bar opens a menu with the open page (show it or destroy it), Open Copied Link, the connection picker and Rebuild VM. Settings… has three sections.
General sets how long a folded page lives, whether pages open in the small or large panel, the ⌃⌥⌘L shortcut, and whether Knotchy opens at login.
Network sends pages through an HTTP or SOCKS5 proxy, with a username and password if it needs them, or through a
WireGuard VPN. For a VPN, import the .conf files or the .zip your provider gives you; Mullvad, Proton VPN and IVPN
all offer them. If the proxy or VPN is down, pages don't load. They never fall back to your normal connection.
Proxies on your Mac or your local network are refused, because a page could reach your network through them.
Passwords and VPN keys are kept in your keychain.
VM shows the runtime version and when the image was built, and has Rebuild Now. Rebuilding picks up WebKit security fixes, and Knotchy suggests it once the image is two weeks old.
There are two programs: the Mac app, and a small agent inside each VM.
When a link comes in, the app checks that it's http or https and asks Apple's container tool to start a new VM
from the local/knotchy-vm image. That's Debian with WPE WebKit and GStreamer, given 4 CPU cores and 2 GB of memory.
Each VM gets a random name (knotchy- and 8 hex digits) and is deleted when it stops.
The VM's first process is vm/knotchy-init, a shell script. Before anything else runs, it sets up
an nftables firewall. On a direct connection the firewall allows the public internet and blocks private and
link-local addresses, carrier-grade NAT, IPv6, and the networks your Mac is on. With a proxy, the proxy is the only
thing the VM can reach. With WireGuard, it's the VPN server and the tunnel. If the firewall can't be put in place,
the VM stops instead of starting without it. Init then drops all its capabilities and starts the agent as an
unprivileged user, so nothing the browser runs can change the firewall.
The agent, vm/knotchy-agent.c, loads the page in WPE WebKit at 1024 × 640, encodes what it
draws as H.264 with x264, and writes the frames to a Unix socket. container exposes that socket to the Mac as a
file, so there's no network connection between the two. The app decodes the video with VideoToolbox and draws it
in the panel. Clicks, scrolls, keys and address changes go back over the same socket. The message format is at the
top of the agent's source.
Destroying a page stops and deletes its VM. If Knotchy quits with a VM running, it deletes it on the way out, and any VM left behind by a crash is deleted at the next launch.
The image is built on your Mac from the vm folder that ships inside the app, so what runs in the VM is what's
in this repository. Proxy passwords and VPN keys reach the VM through a shared folder that init reads, deletes and
unmounts before the browser starts. They're never passed as environment variables, which container saves to disk.
| Path | Contents |
|---|---|
Sources/Knotchy | The Mac app: menu bar, notch panel, setup window and Settings |
Sources/KnotchyCore | The session state machine, the VM backend, the stream protocol and decoder, setup logic |
Sources/knotchyctl | A command-line tool that opens a link in a VM and saves a screenshot, for testing without the UI |
Tests | Unit tests for KnotchyCore; none of them need a VM |
vm | The VM image: Containerfile, knotchy-init and knotchy-agent.c |
extensions/chrome | The Open in Knotchy extension |
scripts | Build, release, test and icon scripts |
You need a Mac with Apple silicon, macOS 26 or later, Xcode 26 or later, and Apple's container installed.
git clone https://github.com/aculix/knotchy.git
cd knotchy
scripts/bundle-app.sh
bundle-app.sh builds Knotchy.app and installs it in ~/Applications. It signs with your Developer ID certificate
if you have one and ad hoc if you don't, which is fine for your own Mac. The app builds its VM image the first time
it opens, the same as a downloaded copy.
The other scripts:
swift test runs the unit tests.scripts/build-vm.sh builds the VM image from the command line.scripts/test-egress.sh starts a VM and checks what it can and can't reach. Run it after any change in vm.scripts/test-routes.sh checks the proxy and VPN routes, kill switch included. Build its test server first with
container build --dns 1.1.1.1 -t local/knotchy-route-server scripts/route-server.scripts/release.sh builds a signed, notarized disk image. It needs a Developer ID certificate and notarization
credentials saved with xcrun notarytool store-credentials.scripts/package-extension.sh zips the browser extension.scripts/make-icons.sh redraws every icon from the knot in scripts/icons/knot.py.A VM image you build yourself is exactly as trustworthy as the checkout you built it from.
Quit Knotchy and move it to the Trash. Then remove its VM image in Terminal:
container image rm local/knotchy-vm
If nothing else on your Mac uses Apple's container, you can remove it as well. This deletes all of its data:
/usr/local/bin/uninstall-container.sh -d
To report a security problem, please use GitHub's private reporting. SECURITY.md has the details.
MIT. See LICENSE.
Swift
85.4%
Shell
7.9%
C
5.1%
Open suspicious links in a throwaway browser that lives in your Mac's notch.
Swift
1
1 commits
updated Sep 28, 2026
Open suspicious links in a throwaway browser that lives in your Mac's notch.
Status: 0.1.0, the first release. It works, but it's young. If something breaks, please open an issue.
Some links you'd rather not open. A shortened link in a text from a number you don't know. An "invoice" from a company you've never dealt with. Knotchy opens them somewhere else: a small Linux virtual machine that exists for that one link. The page appears in a panel under the notch, you look at it, and when you're done the whole machine is deleted, along with anything the page did inside it.
The VM can reach the internet. It can't reach your Mac or anything else on your network.
Knotchy-0.1.0.dmg from Releases. It's signed
and notarized, so macOS opens it without warnings.container runtime (version 1.4.1, 118 MB),
checks it against the SHA-256 built into Knotchy, and opens it in Apple's Installer. Click through Installer
and enter your password there. Knotchy never asks for administrator rights itself.If container 1.4 or newer is already installed, Knotchy uses it and goes straight to the build. You can close the
window at any point and setup carries on; Set Up Knotchy… in the menu bar brings it back.
Safari and Mail need nothing extra. Chrome, Edge, Brave and Arc do, because they pass the Services menu a link's text instead of its address. Until the extension is on the Chrome Web Store, install it by hand:
open-in-knotchy-1.0.0.zip from Releases and unzip
it somewhere you'll keep it. (The same files are in extensions/chrome.)chrome://extensions and turn on Developer mode in the top-right corner.The extension has one permission, adding that menu item, and only passes http and https links to the app.
It won't update itself, and deleting the folder removes it from the browser.
Only web links open. Anything else gets a brief "No web link found" in the notch.
The page opens in a panel that drops down from the notch. Scroll, click and type as you would in any browser. The toolbar has back, forward and reload, an address field, and a button that makes the panel bigger.
Click anywhere outside the panel and it folds back into the notch, with a countdown beside it. Hover over the notch to bring the page back. Leave it folded and the VM is destroyed when the countdown runs out, after 5 minutes unless you change it. Destroy in the toolbar, or ⌘W, ends it right away.
Knotchy shows one page at a time. Opening a new link replaces the current VM with a fresh one.
The knot in the menu bar opens a menu with the open page (show it or destroy it), Open Copied Link, the connection picker and Rebuild VM. Settings… has three sections.
General sets how long a folded page lives, whether pages open in the small or large panel, the ⌃⌥⌘L shortcut, and whether Knotchy opens at login.
Network sends pages through an HTTP or SOCKS5 proxy, with a username and password if it needs them, or through a
WireGuard VPN. For a VPN, import the .conf files or the .zip your provider gives you; Mullvad, Proton VPN and IVPN
all offer them. If the proxy or VPN is down, pages don't load. They never fall back to your normal connection.
Proxies on your Mac or your local network are refused, because a page could reach your network through them.
Passwords and VPN keys are kept in your keychain.
VM shows the runtime version and when the image was built, and has Rebuild Now. Rebuilding picks up WebKit security fixes, and Knotchy suggests it once the image is two weeks old.
There are two programs: the Mac app, and a small agent inside each VM.
When a link comes in, the app checks that it's http or https and asks Apple's container tool to start a new VM
from the local/knotchy-vm image. That's Debian with WPE WebKit and GStreamer, given 4 CPU cores and 2 GB of memory.
Each VM gets a random name (knotchy- and 8 hex digits) and is deleted when it stops.
The VM's first process is vm/knotchy-init, a shell script. Before anything else runs, it sets up
an nftables firewall. On a direct connection the firewall allows the public internet and blocks private and
link-local addresses, carrier-grade NAT, IPv6, and the networks your Mac is on. With a proxy, the proxy is the only
thing the VM can reach. With WireGuard, it's the VPN server and the tunnel. If the firewall can't be put in place,
the VM stops instead of starting without it. Init then drops all its capabilities and starts the agent as an
unprivileged user, so nothing the browser runs can change the firewall.
The agent, vm/knotchy-agent.c, loads the page in WPE WebKit at 1024 × 640, encodes what it
draws as H.264 with x264, and writes the frames to a Unix socket. container exposes that socket to the Mac as a
file, so there's no network connection between the two. The app decodes the video with VideoToolbox and draws it
in the panel. Clicks, scrolls, keys and address changes go back over the same socket. The message format is at the
top of the agent's source.
Destroying a page stops and deletes its VM. If Knotchy quits with a VM running, it deletes it on the way out, and any VM left behind by a crash is deleted at the next launch.
The image is built on your Mac from the vm folder that ships inside the app, so what runs in the VM is what's
in this repository. Proxy passwords and VPN keys reach the VM through a shared folder that init reads, deletes and
unmounts before the browser starts. They're never passed as environment variables, which container saves to disk.
| Path | Contents |
|---|---|
Sources/Knotchy | The Mac app: menu bar, notch panel, setup window and Settings |
Sources/KnotchyCore | The session state machine, the VM backend, the stream protocol and decoder, setup logic |
Sources/knotchyctl | A command-line tool that opens a link in a VM and saves a screenshot, for testing without the UI |
Tests | Unit tests for KnotchyCore; none of them need a VM |
vm | The VM image: Containerfile, knotchy-init and knotchy-agent.c |
extensions/chrome | The Open in Knotchy extension |
scripts | Build, release, test and icon scripts |
You need a Mac with Apple silicon, macOS 26 or later, Xcode 26 or later, and Apple's container installed.
git clone https://github.com/aculix/knotchy.git
cd knotchy
scripts/bundle-app.sh
bundle-app.sh builds Knotchy.app and installs it in ~/Applications. It signs with your Developer ID certificate
if you have one and ad hoc if you don't, which is fine for your own Mac. The app builds its VM image the first time
it opens, the same as a downloaded copy.
The other scripts:
swift test runs the unit tests.scripts/build-vm.sh builds the VM image from the command line.scripts/test-egress.sh starts a VM and checks what it can and can't reach. Run it after any change in vm.scripts/test-routes.sh checks the proxy and VPN routes, kill switch included. Build its test server first with
container build --dns 1.1.1.1 -t local/knotchy-route-server scripts/route-server.scripts/release.sh builds a signed, notarized disk image. It needs a Developer ID certificate and notarization
credentials saved with xcrun notarytool store-credentials.scripts/package-extension.sh zips the browser extension.scripts/make-icons.sh redraws every icon from the knot in scripts/icons/knot.py.A VM image you build yourself is exactly as trustworthy as the checkout you built it from.
Quit Knotchy and move it to the Trash. Then remove its VM image in Terminal:
container image rm local/knotchy-vm
If nothing else on your Mac uses Apple's container, you can remove it as well. This deletes all of its data:
/usr/local/bin/uninstall-container.sh -d
To report a security problem, please use GitHub's private reporting. SECURITY.md has the details.
MIT. See LICENSE.
Swift
85.4%
Shell
7.9%
C
5.1%