{"id":49375853,"url":"https://github.com/jaisonerick/macwifi","last_synced_at":"2026-05-02T19:00:58.865Z","repository":{"id":352890409,"uuid":"1216184679","full_name":"jaisonerick/macwifi","owner":"jaisonerick","description":"Real macOS WiFi data for Go: scan unredacted SSIDs/BSSIDs and read saved WiFi passwords with user-approved macOS prompts.","archived":false,"fork":false,"pushed_at":"2026-04-21T16:36:05.000Z","size":161,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-21T16:37:08.435Z","etag":null,"topics":["apple-silicon","cli","corewlan","go","golang","keychain","location-services","macos","network-diagnostics","networking","tui","wifi"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaisonerick.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":"SUPPORT.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-20T16:48:33.000Z","updated_at":"2026-04-21T16:36:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jaisonerick/macwifi","commit_stats":null,"previous_names":["jaisonerick/macwifi"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jaisonerick/macwifi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaisonerick%2Fmacwifi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaisonerick%2Fmacwifi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaisonerick%2Fmacwifi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaisonerick%2Fmacwifi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaisonerick","download_url":"https://codeload.github.com/jaisonerick/macwifi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaisonerick%2Fmacwifi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32545870,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T12:25:33.646Z","status":"ssl_error","status_checked_at":"2026-05-02T12:24:51.733Z","response_time":132,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apple-silicon","cli","corewlan","go","golang","keychain","location-services","macos","network-diagnostics","networking","tui","wifi"],"created_at":"2026-04-28T02:00:34.651Z","updated_at":"2026-05-02T19:00:58.843Z","avatar_url":"https://github.com/jaisonerick.png","language":"Go","funding_links":[],"categories":["Networking"],"sub_categories":["Transliteration"],"readme":"# macwifi\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/jaisonerick/macwifi.svg)](https://pkg.go.dev/github.com/jaisonerick/macwifi)\n[![CI](https://github.com/jaisonerick/macwifi/actions/workflows/ci.yml/badge.svg)](https://github.com/jaisonerick/macwifi/actions/workflows/ci.yml)\n\nWi-Fi scanning and Keychain password access for Go programs on macOS 13+.\n\nmacOS 14.4 removed the `airport` CLI tool. `wdutil info` returns\n`BSSID : \u003credacted\u003e` even with `sudo`, and CoreWLAN's `scanForNetworks`\nonly returns real BSSIDs to apps signed with a stable Developer ID that\nhave Location Services permission — which scripts and most CLI tools\ncan't get ([Apple DTS forum thread][apple-dts]).\n\n`macwifi` closes that gap by embedding a Developer-ID-signed and\nnotarized Swift helper bundle inside the Go package. Your Go binary\nspawns the helper on first use to trigger the macOS Location Services\nprompt; subsequent calls reuse it.\n\nLooking for a ready-to-run command instead of a library? See\n[`macwifi-cli`](https://github.com/jaisonerick/macwifi-cli) — a\ndrop-in `airport`-replacement built on this package:\n\n```sh\nbrew install jaisonerick/tap/macwifi-cli\n```\n\n[apple-dts]: https://developer.apple.com/forums/thread/718331\n\n## What you can build with it\n\n- Network diagnostics CLIs and TUIs.\n- IT, inventory, and support utilities that need local Wi-Fi context.\n- Security and audit tools that need BSSID, channel, band, and security\n  mode.\n- Migration or recovery tools that need user-approved access to saved\n  Wi-Fi passwords.\n- Desktop agents that need a Go API while still respecting macOS\n  privacy prompts.\n\nOut of scope: cross-platform Wi-Fi abstraction, packet capture,\nbackground daemons that bypass Location Services, or privacy-control\nworkarounds. Location Services and Keychain access stay under user\ncontrol.\n\n## What You Get\n\nWiFi data for saved SSIDs and reachable networks through a simple interface:\n\n```go\n// Asks for Location Services permission on first request.\nnetworks, err := macwifi.Scan(context.Background())\n// networks: []macwifi.Network{\n// \t{\n// \t\tSSID:         \"Office WiFi\",\n// \t\tBSSID:        \"aa:bb:cc:dd:ee:ff\",\n// \t\tRSSI:         -52,\n// \t\tChannel:      149,\n// \t\tChannelBand:  macwifi.Band5GHz,\n// \t\tChannelWidth: 80,\n// \t\tSecurity:     macwifi.SecurityWPA2Personal,\n// \t\tCurrent:      true,\n// \t\tSaved:        true,\n// \t},\n// }\n\n// Asks for Keychain password access.\npassword, err := macwifi.Password(context.Background(), \"MyHomeWiFi\")\n// password: '\u003cmy-password\u003e'\n```\n\nAvailable data:\n\n| Field | Description |\n| --- | --- |\n| `SSID` | WiFi network name. |\n| `BSSID` | Access point MAC address, available after Location Services approval. |\n| `RSSI` | Signal strength in dBm. Closer to zero is stronger. |\n| `Noise` | Noise floor in dBm, when macOS reports it. |\n| `Channel` | WiFi channel number. |\n| `ChannelBand` | `2.4GHz`, `5GHz`, `6GHz`, or `unknown`. |\n| `ChannelWidth` | Channel bandwidth in MHz. |\n| `Security` | Open, WEP, WPA, WPA2, WPA3, enterprise, OWE, or unknown. |\n| `PHYMode` | 802.11 mode when available. |\n| `Current` | Whether the Mac is connected to this network now. |\n| `Saved` | Whether the SSID is in the Mac's preferred networks list. |\n| `Password` | Always empty from `Scan`; use `Password(ctx, ssid)` when needed. |\n\nSaved networks that are not currently visible may be included with signal and\nchannel fields set to zero.\n\n## Usage\n\n### Install\n\n```sh\ngo get github.com/jaisonerick/macwifi\n```\n\nRequirements:\n\n- macOS 13 or newer on Apple Silicon.\n- Go 1.26 or newer.\n\nPermissions requested:\n\n- Location Services for WiFi discovery.\n- macOS Keychain for password retrieval.\n\n### Versioning\n\n`macwifi` follows [Semantic Versioning](https://semver.org/). The exported\nGo API of the `macwifi` package — types, functions, and option helpers —\nis stable across the v1.x line: no breaking changes will land without a\nmajor-version bump. The wire protocol between the Go client and the\nembedded helper is an internal implementation detail and is not covered\nby this commitment.\n\nVersions before v1.0.0 are retracted in `go.mod` when they cannot meet\nthe macOS support floor; `go get` and tooling like Dependabot will steer\nyou to the latest non-retracted release.\n\n### Reuse One Helper Session\n\nWhen scanning for networks and then fetching a password in one run, create a\nclient and reuse it:\n\n```go\nctx := context.Background()\n\nc, err := macwifi.New(ctx)\nif err != nil {\n\tpanic(err)\n}\ndefer c.Close()\n\nnetworks, err := c.Scan(ctx)\nif err != nil {\n\tpanic(err)\n}\n\npassword, err := c.Password(ctx, \"MyHomeWiFi\",\n\tmacwifi.OnKeychainAccess(func(ssid string) {\n\t\tfmt.Printf(\"Approve the macOS Keychain prompt to read %q\\n\", ssid)\n\t}))\nif err != nil {\n\tpanic(err)\n}\n\nfmt.Println(len(networks), password)\n```\n\n### Keychain Passwords\n\nThe legacy **Always Allow** path is no longer available in the macOS Keychain\naccess permission dialog, so users will see the prompt every time\n`macwifi.Password()` runs for an SSID.\n\nUse `OnKeychainAccess` to prepare users before macOS shows its dialog:\n\n```go\npassword, err := macwifi.Password(ctx, ssid,\n\tmacwifi.OnKeychainAccess(func(ssid string) {\n\t\tfmt.Printf(\"Approve the macOS Keychain prompt to read %q\\n\", ssid)\n\t}))\n```\n\n## Development\n\nRun the example scanner:\n\n```sh\ngo run ./examples/scan\ngo run ./examples/scan --password MyHomeWiFi\n```\n\nRun tests:\n\n```sh\nmake ci-go\n```\n\nBuild and use a local helper while editing Swift code:\n\n```sh\nmake scanner\nMACWIFI_APP=$PWD/WifiScanner.app go run ./examples/scan\n```\n\n`MACWIFI_APP` tells the Go package to use a local helper bundle instead of the\nembedded one.\n\n## Releases\n\nReleases are fully automated. Day-to-day:\n\n1. Land changes on `main` using [Conventional Commits](https://www.conventionalcommits.org/).\n2. [Release Please](https://github.com/googleapis/release-please) keeps a\n   rolling Release PR open with the next `CHANGELOG.md` entry, the\n   `go.mod`-aware version bump, and the `embeddedVersion` constant in\n   `embed.go`.\n3. Merging the Release PR tags the version, publishes a GitHub Release,\n   primes `proxy.golang.org`, and attaches the signed `WifiScanner.app`\n   zip to the release.\n\nThe signed companion workflow handles the helper bundle. Pull requests\nthat touch `scanner/Sources/`, `scanner/Info.plist`,\n`scanner/entitlements.plist`, or the helper build scripts trigger a\nmacOS runner that builds, codesigns with Developer ID, notarizes,\nstaples, and commits the regenerated `embedded/WifiScanner.app` back to\nthe PR branch before merge. The workflow expects the environment\nsecrets documented in\n[`.github/SIGNING_SECRETS.md`](.github/SIGNING_SECRETS.md).\n\n### Local helper rebuild (development only)\n\nWhen iterating on Swift code, you don't need notarization — just an\nad-hoc signed bundle pointed at via `MACWIFI_APP`:\n\n```sh\nmake scanner\nMACWIFI_APP=$PWD/WifiScanner.app go run ./examples/scan\n```\n\nA full Developer ID + notarized release build can be produced locally\nwith `make release`, but it is not required to ship — CI handles that\nend-to-end.\n\n## Contributing\n\nIssues and pull requests are welcome, especially for:\n\n- Compatibility reports across macOS releases and hardware.\n- Better metadata mapping from CoreWLAN into the Go API.\n- Documentation improvements for real-world diagnostics, support, and security\n  use cases.\n\nFor code changes, run `make ci-macos` before opening a pull request. If your\nchange touches the Swift helper, also test with `make scanner` and\n`MACWIFI_APP=$PWD/WifiScanner.app go run ./examples/scan`.\n\nChanges to the helper app must pass the signed companion workflow because\nsigning and notarization are automated before merge.\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for the full contribution workflow,\n[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for community expectations,\n[SECURITY.md](SECURITY.md) for vulnerability reporting, and\n[SUPPORT.md](SUPPORT.md) for support expectations.\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaisonerick%2Fmacwifi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaisonerick%2Fmacwifi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaisonerick%2Fmacwifi/lists"}