Privacy

What Sonora touches, and what it does not.

Sonora collects no personal data. There are no analytics, no crash reporting, no accounts, no tracking, no cookies, no advertising identifiers, and no Sonora server anywhere for data to be sent to. Nobody — including me — receives anything about you, your devices, your browsing or your listening.

Sonora is two separate pieces that work together: a Chrome extension, and HeadsetCompanion, a macOS menu-bar app. Either one runs perfectly well on its own. This page covers both.

The Chrome extension

The extension finds every browser tab that is playing audio and lets you control it from one popup. To do that it needs to look at your tabs and at the media elements inside pages. That is the whole job, and everything below exists for it.

What the permissions are for

These are the exact permissions declared in the extension's manifest:

What the in-page script actually reads

On a page, Sonora looks only at the page's own <audio> and <video> elements and the standard media metadata browsers already expose for media controls. Specifically: the page URL and hostname, the page title, the favicon, the og:description/description meta tag (first 200 characters), the track title and artist from the Media Session API, the artwork URL, and playback state — playing or paused, muted, volume, position, duration.

That snapshot goes to the extension's own background worker so the popup can draw a row for the tab. It goes nowhere else. Sonora does not read page text, form fields, passwords, cookies, or anything you type, and it does not modify pages.

What is stored, and where

In chrome.storage.local, which lives in your browser profile on your own machine:

In chrome.storage.session, cleared when you quit the browser: the list of tab ids that reported a media element.

That is the complete list. No history, no URLs, no listening record. None of it is synced, and none of it leaves the device.

The microphone prompt

If you want to pick which audio output a tab plays through, Sonora offers a one-time microphone permission. This is a Chrome rule, not a Sonora one: the browser hides the real names of your output devices ("MacBook Pro Speakers", "WH-1000XM4") until the extension has held a microphone permission once. Sonora asks for the microphone, immediately stops the audio track it gets back, and keeps nothing. No audio is recorded, buffered, or transmitted. The prompt is entirely optional — decline it and everything still works, with outputs listed as "Output 1", "Output 2".

Network requests

The extension makes exactly two kinds of network request, both to your own machine:

If 127.0.0.1 does not answer, the popup tries localhost on the same port. That is the extent of it. There is no other outbound request of any kind — no home-phoning, no version ping, no remote configuration, no remote code. The only external address in the extension at all is a plain link to the GitHub release page on the welcome screen, and nothing is fetched from it unless you click it.

The local bridge

The bridge is the small HTTP server inside HeadsetCompanion, bound to 127.0.0.1 — the loopback interface. Loopback traffic never reaches a network card; it cannot leave your Mac, and no other machine can reach it. It exists so the browser, which has no way to see a classic Bluetooth headset's battery, can get the number from the app that can.

It is optional in both directions. Without the app, the extension works and simply shows no battery. Without the extension, the app shows the battery in your menu bar as usual.

The macOS app

What it reads

HeadsetCompanion reads your headset's battery level from macOS itself, through public system interfaces: CoreBluetooth's standard battery service, IOBluetooth's list of paired devices, and the system_profiler SPBluetoothDataType command. It also reads and sets your audio output device so the menu can replace the Sound menu. What it learns is a device name and a percentage. That stays on your Mac.

The app writes a plain-text log to ~/Library/Logs/headset-companion.log to make problems diagnosable — it can contain your headset's name and battery readings. It is a local file, it is never uploaded, and you can delete it whenever you like.

The update check

This is the one thing in Sonora that talks to the internet, and it is worth being precise about.

Once a day, the app sends an HTTPS GET to https://api.github.com/repos/YamineRL/sonora/releases/latest to see whether a newer version exists. The request carries no identifier of you: no account, no licence key, no device id, no installation id, no usage data. It sends an Accept header and the user-agent string HeadsetCompanion-updater. Your current version number is not sent either — the comparison happens locally after the answer arrives.

What it unavoidably does reveal, as any HTTPS request does, is your IP address to GitHub, along with the fact that a HeadsetCompanion updater asked about this repository. That is GitHub's to handle under their own privacy policy, not mine — I never see it. If a newer version is found, the app then downloads the .dmg from GitHub's release assets, which reveals the same thing again.

You can turn it off. In the app's Settings there is a "Check for updates daily" switch. It is on by default; turn it off and the app makes no network request at all unless you press "Check for Updates" yourself.

Children, and data you never gave

Sonora has no accounts and asks for no personal information, so there is nothing to collect from anyone of any age. There is no data to request, correct, export or delete, because none is held: everything Sonora knows lives on your own machine, and uninstalling removes it.

Check for yourself

You do not have to take my word for any of this. The whole of Sonora — extension and Mac app — is public and readable at github.com/YamineRL/sonora. Every claim on this page corresponds to code you can search: the permission list is in sonora-extension/manifest.json, the only network calls are in popup/bridge.ts, background/service-worker.ts and Sources/HeadsetCompanion/Updater.swift, and the loopback server is in Sources/HeadsetCompanion/BridgeServer.swift.

Changes, and getting in touch

If this policy ever changes, the changed version will be published here with a new date below. Questions, corrections, or something that looks wrong: open an issue at github.com/YamineRL/sonora/issues.

Last updated 23 August 2026.