.Ember
DotEmber icon

DotEmber

.Ember

Last updated 2026-05-26

This Privacy Policy describes how .Ember (DotEmber) handles your information. It supplements — and does not replace — the NilToDev master Privacy Policy, which covers studio-level matters (the website, hosting, contact) common to every app we ship.

Plain-English summary. .Ember runs entirely on your Mac. We do not operate servers, do not collect telemetry, and do not see your journal entries, todos, calendar, or timer sessions unless you opt into one of the third-party integrations described below — and even then your data flows directly between your Mac and that service, never through us.

Overview

.Ember is a local-first productivity desktop app for macOS. We do not run servers and we do not collect, store, or sell your personal data. Your journal entries, todos, calendar blocks, and timer sessions live as Markdown files in a folder you choose on your own Mac. .Ember never sees those files unless you opt in to one of the integrations described below.

This policy describes (1) what stays on your device by default, (2) the optional integrations you can enable, and (3) the third-party services those integrations use.

What stays on your device

By default, .Ember stores everything locally:

  • Vault content — Journal entries, todos, calendar blocks, notebook organization. Stored as Markdown files in a folder you pick during onboarding (default suggestion: ~/Documents/DotEmber).
  • App database — A small SQLite database ({userData}/dotember.sqlite) caches search indexes, timer sessions, and RSS articles (when News is used). This is an accelerator for the local files; the Markdown files are the source of truth.
  • Settings — Theme, accent color, language, week-start day, AI master toggle, and similar UI preferences. Stored in localStorage and {userData}/settings.json.
  • AI keys — API keys you paste in the Settings → AI tab are encrypted via Apple’s safeStorage (Keychain) and stored in {userData}/ai-secrets.enc. They never appear in localStorage, never leave your Mac except in direct calls to the provider you chose, and are never transmitted to us.
  • OAuth tokens — Google refresh tokens are encrypted via safeStorage (Keychain) and stored per-account at {userData}/google-accounts/{accountId}.enc. Same scope as AI keys: never in localStorage, never transmitted to us.

We do not transmit any of this to a .Ember server. There is no .Ember server.

Optional integrations

Each integration is off by default and can be turned off again at any time from Settings. When you enable one, your data flows directly between your Mac and the third-party service — never through .Ember.

iCloud Sync (Apple CloudKit)

When enabled in Settings → Sync, .Ember uses Apple CloudKit to sync your vault between your Macs. Records are stored in your private CloudKit database under container iCloud.com.dotember.app — only your iCloud account can read them. Apple’s standard iCloud privacy applies. Disabling sync does not delete the data already on iCloud — use Settings → iCloud (system) to remove app data from your iCloud account.

Google Calendar + Tasks

When connected in Settings → Calendar, .Ember reads upcoming events from calendars you select via Google’s Calendar REST API and task lists you select via Google’s Tasks REST API. Scopes requested (all in the Sensitive tier — .Ember never requests Restricted scopes such as https://www.googleapis.com/auth/calendar):

  • https://www.googleapis.com/auth/calendar.events — read and write events on calendars the user has selected.
  • https://www.googleapis.com/auth/calendar.readonly — enumerate the calendar list and derive the connected account’s primary email for display in the Settings → Calendar account row.
  • https://www.googleapis.com/auth/tasks — read and write tasks on task lists the user has selected.

Multiple Google accounts are supported; each account’s refresh token is stored encrypted on your Mac at {userData}/google-accounts/{accountId}.enc. Events and task lists are cached in the local SQLite. .Ember writes to your Google Calendar or Google Tasks only when you create, edit, complete, or delete an event or task from inside .Ember — every write originates from a deliberate user action; there is no background sync that pushes local changes you didn’t make. Disconnecting an account (Settings → Calendar → Remove on the account row) revokes the local token, deletes the encrypted file, and removes that account’s cached events and tasks.

Apple Calendar (EventKit)

When connected in Settings → Calendar, .Ember reads from and writes to your local Apple Calendar via macOS’s EventKit framework. macOS prompts you for full Calendar access (TCC permission personal-information.calendars); you can revoke it at any time in System Settings → Privacy & Security → Calendars. All Apple Calendar data stays on your device — EventKit is process-local; nothing is transmitted off your Mac via this integration. .Ember writes to your Apple Calendar only when you create, edit, or delete an event from inside .Ember. Events are cached in the local SQLite for the same selectable-calendar UX as the Google integration. Removing the Apple account row in Settings clears the cached events; revoking system-level Calendar access additionally blocks future reads/writes.

RSS / News feeds

Feeds you add in /news are fetched directly by your Mac from each publisher’s URL on a 30-minute schedule. .Ember does not proxy or log these requests. Article content is cached locally for the reader view.

BYOK AI (Claude / Gemini / OpenAI)

When AI is enabled (Settings → AI → master switch) and a provider key is configured, AI features (Auto-arrange Inbox, Daily Brief, palette commands) call the provider’s API directly from your Mac. The relevant data sent depends on the feature:

  • Auto-arrange Inbox — Inbox todo titles, your block names, and the last 14 days of completed/scheduled todo titles + block + start time.
  • Daily Brief — RSS article titles + sources + publication dates from your subscribed feeds, plus the titles of articles you have saved to your journal in the last 30 days.
  • Palette commands — Whatever text you type into the command palette as an AI command.

Each provider has its own data-handling policy:

Disabling AI (master toggle off) immediately stops all outbound AI calls and hides every AI surface in the app.

Google API Services User Data Policy compliance

.Ember’s use and transfer of raw or derived user data received from Google Workspace APIs will adhere to the Google API Services User Data Policy, including the Limited Use requirements (and the equivalent Workspace API user data developer policy).

Specifically, for the Google Calendar (calendar.events, calendar.readonly) and Google Tasks (tasks) scopes that .Ember requests:

  • Limited use. Data received from Google APIs is used only to provide or improve the user-facing features that the user requested — rendering events and tasks on the Todo Calendar grid; creating, editing, completing, and deleting events and tasks the user authored inside .Ember; surfacing per-calendar visibility and color in Settings → Calendar; resolving conflicts when the same event was edited on both sides between syncs.
  • No transfer. .Ember does not transfer Google user data to third parties, except as necessary to provide or improve the user-facing features (which currently is no such transfer at all — every API request originates from the user’s Mac and hits Google’s endpoints directly), or for security purposes (e.g., investigating abuse), or to comply with applicable laws.
  • No advertising. .Ember does not use Google user data — including any inferences derived from it — to serve advertisements, including retargeted, personalized, or interest-based advertising.
  • No human reading. .Ember does not allow humans to read Google user data, except (a) with the user’s explicit consent for specific data, (b) as necessary for security purposes such as investigating abuse, (c) to comply with applicable laws, or (d) for internal operations on data that is aggregated and anonymized, and only in compliance with the Google API Services User Data Policy. As of the Last updated date above, .Ember operates no servers, employs no support staff with access to user accounts, and performs no aggregated or anonymized processing on Google user data — so no Google user data is read by any human on the .Ember side.
  • No AI/ML training, no transfer for training purposes. .Ember does not use Google user data — raw, aggregated, anonymized, or derived — to develop, train, or improve any generalized or foundational machine-learning or artificial-intelligence model, and does not transfer Google user data to any third party for such training purposes. .Ember’s BYOK AI features (Auto-arrange Inbox, Daily Brief, command palette actions) are described in the “BYOK AI” subsection above; in version 1.0.0 those features operate on local app data (Inbox todo titles, block names, RSS article titles + saved-article titles, and text the user types into the palette) and do not include Google Calendar events or Google Tasks data in the AI request body. Should a future release route Google user data into an AI feature, it would do so only as a user-facing feature for that individual user under Limited Use — never for training a generalized model and never via any provider that re-trains on API-tier inputs.

We will continue to adhere to these restrictions as the product evolves; any future change that would alter the Limited Use posture (e.g., introducing a server-side feature that handles Google data, or routing Google user data through an AI feature) will trigger a privacy policy update and a fresh Google OAuth verification before shipping.

Data protection mechanisms

Sensitive data that .Ember handles locally — Google OAuth refresh tokens, BYOK AI API keys, and StoreKit purchase receipts — is protected by the following mechanisms:

  • Encryption at rest. Google refresh tokens and AI API keys are encrypted using Apple’s safeStorage API, which routes through the macOS Keychain Services framework. The encrypted blobs at {userData}/google-accounts/{accountId}.enc and {userData}/ai-secrets.enc cannot be decrypted by any process outside .Ember’s signed app binary running under the same macOS user account. The encryption key is managed by macOS and never leaves the device.
  • Encryption in transit. All network requests .Ember makes to Google APIs (https://oauth2.googleapis.com, https://www.googleapis.com, https://tasks.googleapis.com) use HTTPS with TLS 1.2 or newer enforced by the macOS networking stack (URLSession). Plaintext fallback is impossible — NSAppTransportSecurity in .Ember’s Info.plist blocks any cleartext HTTP connection by default and .Ember declares no exceptions.
  • Access control. Encrypted credential blobs are sandbox-scoped to the .Ember app bundle (App Sandbox entitlement com.apple.security.app-sandbox = true) — no other application on the user’s Mac can read them. The sandbox is enforced by the macOS kernel; circumvention would require user-level privilege escalation, which is outside .Ember’s threat model and is itself a violation of Apple’s platform policies.
  • No copies. .Ember does not maintain unencrypted copies of these credentials anywhere — not in localStorage, not in UserDefaults, not in log files, not in crash reports. Refresh tokens are decrypted into memory only for the duration of a single token-refresh REST call and are released immediately after the call completes.
  • Token revocation paths. Disconnecting a Google account (Settings → Calendar → Remove on the account row) deletes the encrypted token file and removes the account’s cached events and tasks from the local database. Users can additionally revoke the OAuth grant directly with Google at myaccount.google.com/permissions; .Ember treats subsequent 401 responses as a revoked grant and re-runs the consent flow.
  • No transmission to NilToDev. None of these credentials, tokens, or any data fetched using them is ever transmitted to a NilToDev server — there is no NilToDev server. The encrypted blobs leave the user’s Mac only via the user’s own iCloud Drive backup of Application Support data if the user has enabled that backup, in which case Apple’s standard iCloud encryption applies (see Apple’s iCloud security overview).

Analytics, tracking, advertising

None. .Ember does not include analytics SDKs, crash-reporting services that link to user identity, advertising trackers, or any other phone-home telemetry. The app makes zero outbound network requests on a clean install with no integrations enabled.

Purchases (Apple App Store)

.Ember 1.0.0 ships with a Free Trial followed by a one-time in-app purchase to continue use beyond the trial period. Purchase processing is handled by Apple — NilToDev does not receive your credit-card number, billing address, or any other payment instrument data; the App Store EULA governs that relationship.

What .Ember handles locally for license validation:

  • StoreKit 2 transaction record. When you purchase, Apple’s StoreKit framework returns a verified transaction object containing an anonymous transaction ID, the product ID, the purchase date, and the current transaction status (purchased / refunded / revoked). .Ember stores this verified record locally so the app knows whether to show paid features.
  • Trial start date. When the Free Trial begins, .Ember writes the start timestamp to local app storage (localStorage and/or {userData}/license.json) so the trial countdown can run without contacting an external server.

What .Ember does not handle:

  • Your Apple ID email, name, or any other personal Apple-account detail (StoreKit’s verified transaction does not expose these).
  • Any payment instrument (card number, last 4 digits, billing zip, etc.).
  • Any per-user purchase history beyond your own most recent transaction record.

Refund handling is described in the .Ember Terms of Use §9 — refunds are processed by Apple at reportaproblem.apple.com; NilToDev cannot directly issue refunds.

Sale and sharing of personal information

We do not sell or share your personal information in any sense — including the senses contemplated by the California Consumer Privacy Act / California Privacy Rights Act (CCPA/CPRA), the Colorado Privacy Act, or any comparable framework. We do not engage in cross-context behavioral advertising. We do not have a Data Use Choices opt-out mechanism because there is nothing to opt out of.

Accounts, GDPR, CCPA

.Ember has no user account system — no signup, no login, no .Ember-issued user ID. Because we do not collect, store, or process any personal data on our side (with the narrow exceptions documented in “Purchases” above and “Contact” below), data-subject rights under GDPR / UK GDPR / CCPA / Korean PIPA generally have no NilToDev-side data to act upon. Where rights apply to data held by third-party services you opt into (Apple iCloud, Google, Anthropic, OpenAI), exercise them directly with that third party under their own privacy policies.

For completeness, the framework-by-framework rights summary:

FrameworkRightsHow to exercise against NilToDev
GDPR / UK GDPR (Art. 15-22)Access, rectification, erasure, restriction of processing, portability, objection, withdrawal of consent, lodging a complaint with a supervisory authorityEmail [email protected]. We respond within 30 days. Most rights have no NilToDev-side data to act on (we hold none); we’ll confirm that in writing.
CCPA / CPRAKnow, delete, correct, opt out of sale/sharing, limit use of sensitive personal info, non-discriminationEmail [email protected]. We do not sell or share, so the opt-out is moot. Most other rights have no NilToDev-side data to act on.
Korean PIPA (Art. 35-37)Access, rectification, deletion, suspension of processingSee the dedicated KR PIPA section in the Korean version of this addendum for the full disclosures and procedure.

For the studio-level position on these regimes (Cloudflare Analytics, hosting, contact handling), see the NilToDev master Privacy Policy.

Children

.Ember is not directed at children under 16 (GDPR threshold) or under 13 (COPPA threshold) and we do not knowingly collect data from such children. Age rating: 4+ (App Store).

Data deletion

.Ember writes user data only to (a) your vault folder, (b) the macOS Application Support directory, and (c) — if iCloud Sync is enabled — your private CloudKit database. There is no .Ember-side database to issue an erasure request against.

Inside the vault, deletes are deferred — not immediate. When you delete a journal entry, todo, notebook, block, or when sync removes a file that has disappeared upstream, the file is moved to {vault}/_trash/ and kept there for 30 days before being hard-removed by the next cleanup pass. This is a local recovery window — _trash/ lives only in your vault folder, is never synced to iCloud or any other sync target, and is never read by any feature except the trash recovery UI in Settings → Trash. To empty it on demand, use Settings → Trash → Empty trash.

To remove every trace of .Ember from your Mac:

  1. Quit the app.
  2. Delete the vault folder (default ~/Documents/DotEmber, or wherever you pointed it). This includes _trash/ since it lives inside the vault.
  3. Delete ~/Library/Application Support/DotEmber/ (contains the SQLite cache, AI keychain blob, OAuth token blobs under google-accounts/, settings).
  4. Delete the app from /Applications/.

To remove iCloud-synced data, also visit System Settings → Apple ID → iCloud → Manage → .Ember → Delete.

To revoke OAuth access to your Google account, visit myaccount.google.com/permissions.

Changes to this policy

Material changes will be noted in the in-app changelog and in the Last updated line at the top of this document. The version-controlled source of this addendum lives at docs/privacy/privacy-policy.en.md in the .Ember repository; the canonical published copy is this page on niltodev.com.

Contact

Questions: [email protected]


This addendum reflects .Ember 1.0.0 and supersedes any prior version. For studio-level matters not covered here, refer to the NilToDev master Privacy Policy.