Security

What Breather can see, and what it can't.

How the Breather desktop app works, what it reads from a calendar, how call detection works without listening, and exactly what leaves the device. Written for the IT and security teams who approve it.

Breather for Mac 2.6.1 and later · Updated 23 October 2026

No servers, no accounts

Breather runs entirely on the Mac. There's no sign-in and no Breather server that receives calendar or user data.

Never records or listens

Call detection reads a single on/off signal from macOS: whether any microphone is in use. Breather doesn't even have microphone permission.

Read-only, minimal calendar access

Today's events only, a short list of fields, processed in memory. Descriptions, locations, attachments and attendee identities are never read.

Calendar content stays on the Mac

Meeting titles and details are never stored to disk and never sent anywhere: not to Breather, not to analytics, not in crash reports.

Optional, anonymous telemetry

Usage statistics and crash reports carry no names, emails or calendar data, and one setting switches both off.

Signed and notarized

Signed with an Apple Developer ID and notarized by Apple. Updates are signed the same way and checked by macOS before they install.

How it works

Breather is a menu bar app. It reads today's calendar, notices when calls start and end, keeps a running score of how demanding the day has been, and suggests a two-minute breathing exercise at a moment when there's room for one.

  • Inputs: today's calendar (Google Calendar or the macOS Calendar app) and macOS's "microphone in use" signal.
  • Processing: all on the Mac, in the Breather app. Nothing is sent to a server to be analysed.
  • Outputs: a suggestion window on screen, and a local history of completed sessions for the user's own weekly stats.

There is no Breather account, login or backend database. Breather (the company) cannot see who uses the app, what's in their calendar or when they take a break.

Calendar access

The user chooses one calendar source during setup. Both are read-only, and Breather only ever looks at the current day.

Google Calendar

  • Permission: Google OAuth with the read-only scope calendar.events.readonly, plus the user's email address so Settings can show which account is connected.
  • Scope of reading: the user's primary calendar, today's events only, refreshed every 60 seconds.
  • Tokens: the sign-in happens in the user's own browser and the token exchange goes directly between the Mac and Google. Tokens are stored on the Mac, encrypted with a key held in the macOS Keychain. Breather never receives them.
  • Revoking: "Disconnect" in Settings deletes the tokens from the Mac. Access can also be revoked at any time from the Google account's security settings.

macOS Calendar app (including Outlook and Exchange)

  • Permission: the standard macOS Calendars permission, which the user can revoke in System Settings at any time.
  • Scope of reading: today's events from calendars added to the Calendar app on that Mac. Work Exchange or Microsoft 365 accounts added there are included.
  • A small helper inside the app reads today's events through Apple's EventKit framework and passes on the same short list of fields as for Google. Event notes and links are scanned on the Mac only to find a video-call link; nothing else from them is kept.

Exactly what is read

ReadWhy
Start and end timesTo know when meetings happen and where the gaps are.
TitleKept in memory only, to recognise ad-hoc instant meetings. Never written to disk or sent anywhere.
Free / busy statusEvents marked "free" are ignored.
The user's own responseDeclined meetings are ignored.
Whether the user is the organiserOrganising a meeting counts as slightly more demanding.
Number of other attendeesLarger meetings count as more demanding, and one-person blocks (focus time, lunch) aren't treated as meetings. Only the count is used.
Whether it's a recurring meetingFamiliar recurring meetings count as slightly less demanding.
Video-call linkTo offer a "Join meeting" button after a session if a call is about to start.

Never read or requested: event descriptions or agendas, locations, attachments, attendee names or email addresses (for Google these fields are never requested; for macOS Calendar, attendee names are used only to count attendees and are never stored), other people's calendars, or any day other than today.

Microphone

Breather needs to know when a call ends, so it can suggest a break at that moment and never interrupt a meeting in progress. It does this without listening.

  • Every few seconds, a small helper asks macOS one yes/no question: is any microphone on this Mac currently running? This is the same system state behind the orange microphone indicator in the menu bar.
  • Breather never opens an audio input, never receives audio samples, and cannot tell which app is using the microphone, who is speaking, or what is said. Nothing about microphone state is stored or sent.
  • Reading this signal doesn't need microphone permission, so Breather never asks for it. The app is also signed without the entitlement macOS requires before any app can capture from a microphone, so macOS would block it from recording even if its code tried. You can confirm this with codesign -d --entitlements - /Applications/Breather.app.
  • Because it never captures audio, Breather never appears in the macOS microphone indicator, in Control Centre, or in the Microphone list in Privacy & Security settings.

What leaves the Mac

This is the complete list of outbound connections the app makes. Breather accepts no inbound connections.

DestinationWhenWhat's sentCan be switched off
Google
accounts.google.com
oauth2.googleapis.com
www.googleapis.com
Only if the user connects Google CalendarThe user's own OAuth token, to read their calendar as described aboveYes: use the macOS Calendar option, or disconnect
Breather updates
updates.breather.work
(Cloudflare)
At launch and every 4 hoursA request for the latest version number; downloads of signed updatesNo: needed to receive security fixes
Usage statistics
eu.i.posthog.com
(PostHog, EU)
While the app is in useA random install ID, app version, platform and chip type, and events such as "suggestion shown", "suggestion accepted", "session completed" and "setting changed", some with a numeric day-intensity score. No names, emails, calendar data or location.Yes: Settings → Share usage data
Crash reports
*.ingest.de.sentry.io
(Sentry, Germany)
Only when the app hits an errorThe error's stack trace, app and macOS version. No console output, no user identifier, no calendar data.Yes: the same "Share usage data" setting

During Google sign-in only, the app briefly listens on a random local port on 127.0.0.1 to receive Google's redirect, then closes it.

Never sent anywhere: meeting titles or details, attendee information, audio or microphone activity, session history, or anything that identifies the user.

What's stored on the Mac

Everything lives in the user's own Library folder at ~/Library/Application Support/Breather/, readable only by that macOS user.

DataContentsKept for
SettingsWorking hours, sound, suggestion frequency and similar preferencesUntil changed
Session historyTime, length and breathing pattern of each completed session1 year
Suggestion historyWhen each suggestion appeared and the response, with the length and attendee count of the meeting before it (no titles or names)30 days
Today's stateThe day-intensity score and calendar event IDs already counted, so a restart doesn't double countReset daily
Google tokensEncrypted with a key held in the macOS KeychainUntil disconnected

App security

  • Code signing: signed with an Apple Developer ID, notarized by Apple, with the hardened runtime enabled. Verify any copy with codesign -dv --verbose=2 /Applications/Breather.app and spctl -a -vv /Applications/Breather.app.
  • Updates: delivered over HTTPS. Before installing, the macOS updater checks that the update is signed by the same Apple developer team. Users choose when to install.
  • Built on Electron: every screen is bundled inside the signed app; no web content is loaded from the internet. Screens run sandboxed, with context isolation and no direct access to the system.
  • Footprint: no admin rights needed to run, no background services, kernel or system extensions, browser extensions or system-wide changes. An optional login item starts the app when the user logs in.

macOS permissions

PermissionUsed forRequired
CalendarsReading today's events, only if the user picks the macOS Calendar optionNo
Login itemStarting at login (a setting the user can switch off)No

Breather does not request Microphone, Camera, Screen Recording, Accessibility, Full Disk Access, Contacts or Location.

Deployment and removal

  • Requirements: a Mac with Apple silicon (M1 or later) running macOS 12 Monterey or later.
  • Install: a signed disk image containing Breather.app, which can be deployed with standard Mac management tools.
  • Network allowlist: updates.breather.work, plus eu.i.posthog.com and *.ingest.de.sentry.io if usage data is left on, plus the three Google domains above if Google Calendar is used.
  • Removal: quit Breather, delete Breather.app and the folder ~/Library/Application Support/Breather/. Optionally remove the "Breather Safe Storage" item from the Keychain and revoke Google access from the Google account.

Questions

We're happy to go through any of this with your security team, or to answer a questionnaire. Email hello@breather.work, which is also the address for reporting a security issue.

This page covers the Breather desktop app. Team Breathers live sessions are covered in our privacy policy.