macwifi
Wi-Fi scanning and Keychain password access for Go programs on macOS 13+.
The problem
macOS 14.4 removed /usr/libexec/airport, the CLI tool that backed almost every script and library that wanted to enumerate nearby Wi-Fi networks or get the BSSID, RSSI, and channel of the current connection.
Its replacement, wdutil info, requires sudo and returns BSSID : <redacted> for every entry. networksetup and ioreg don’t expose nearby networks at all.
The Apple-recommended path is the CoreWLAN framework, but scanForNetworks only returns real BSSIDs to apps that are signed with a stable Developer ID and have been granted Location Services permission. Apple’s Developer Technical Support team has confirmed on the developer forums that scripts and launchd daemons can’t satisfy these requirements:
I recommend that you try this with native code built in to a native app. TCC, the subsystem within macOS that manages the privileges visible in System Preferences > Security & Privacy > Privacy, doesn’t work well for scripts.
The Go libraries that previously did this — schollz/wifiscan, jarethdisley/wifiscanparser, and several others — parse airport output. None of them work on Sonoma 14.4 or later.
What macwifi does
macwifi is a Go package that embeds a Developer-ID-signed, notarized Swift helper bundle. Your Go binary spawns the helper on first use to trigger the macOS Location Services prompt; subsequent calls reuse the same helper process.
package main
import (
"context"
"fmt"
"github.com/jaisonerick/macwifi"
)
func main() {
nets, err := macwifi.Scan(context.Background())
if err != nil {
panic(err)
}
for _, n := range nets {
fmt.Printf("%-32s %s %d dBm ch %d\n",
n.SSID, n.BSSID, n.RSSI, n.Channel)
}
}
The package returns rich metadata — SSID, BSSID, RSSI, noise floor, channel number, channel band (2.4/5/6 GHz), channel width, security mode, PHY mode, and current/saved flags. There’s also macwifi.Password(ctx, ssid) for reading saved Wi-Fi passwords from the Keychain after the user approves the system prompt.
Install
go get github.com/jaisonerick/macwifi
Requirements: macOS 13 or newer on Apple Silicon, Go 1.26+.
Just want a CLI?
If you don’t need a Go API and just want a working airport -s replacement on the terminal, install macwifi-cli:
brew install jaisonerick/tap/macwifi-cli
macwifi-cli scan
macwifi-cli info
macwifi-cli password "MyHomeWiFi"
What’s next
- Getting started — full setup, Location Services dance, troubleshooting, and a longer worked example.
- How it works — what the embedded helper does, why it exists, and the protocol it speaks back to Go.
Scope
macwifi is a macOS-only Go library. It is not a cross-platform abstraction, a packet capture library, a background daemon, or a workaround for macOS privacy controls. Location Services and Keychain prompts still go through the user, every time.