Markleaf Privacy Policy
Last updated: May 26, 2026 · Applies to Markleaf Android v2.x
Core principle
Markleaf is a local-first Markdown note app. It runs no server of its own and never uploads notes, tags, attachments, or metadata to any external server. The builds distributed through F-Droid and Google Play declare no android.permission.INTERNET permission at all; the sideload build on GitHub Releases declares it for one purpose only, described under Network.
Information Markleaf does not collect
- Name, email, contacts, location
- Account or login information
- Note body, title, tags, attached images, file names, metadata
- Usage statistics, telemetry, analytics events, advertising identifiers
- Crash reports or device identifiers
It also contains no analytics, ads, tracking, remote configuration, Firebase, or closed-source crash-reporting SDKs.
Network
This depends on where you got the app. In both cases, none of your note data is ever sent.
- F-Droid and Google Play — no
android.permission.INTERNET, and no network activity whatsoever. - GitHub Releases (sideload) — declares two permissions: one for the update check, and one so it can install the update you choose to download. Both are off unless you turn the check on.
F-Droid / Google Play INTERNET: none · REQUEST_INSTALL_PACKAGES: none GitHub Releases INTERNET: update check · REQUEST_INSTALL_PACKAGES: install, after SHA-256 verification
The update check in the sideload build
- Off by default. Nothing happens until you switch it on in Settings.
- Once a day it makes a single GET for one static JSON file describing the newest release. A failed check is ignored silently.
- Tapping Download and install in the update dialog makes the app's only other network request: a GET for the update file itself. Like the check, this only happens because you asked for it.
- Once the file is downloaded, the app compares it against the SHA-256 in that JSON file. If it doesn't match, the file is deleted and installation never starts.
- Only a verified file is handed to Android's own
PackageInstaller. The confirmation screen that follows is drawn by Android, not by Markleaf. This step needs theREQUEST_INSTALL_PACKAGESpermission; if it isn't granted yet, the app takes you to Settings first. - If the download or the verification fails, you can try again, or open it in your browser instead — the same handoff this feature used before.
- The request carries that URL and standard HTTP headers. No query string, no cookie, no account.
- No note bodies, titles, tags, attachments, file names, metadata, device identifiers, or usage data are sent. That holds in every build and every one of these requests, without exception.
- The store builds contain neither the permission nor the code for this — not disabled, simply not built in.
Where data is stored
- Note bodies, titles, and the tag index are stored in the app's internal Room database.
- User settings are stored in DataStore.
- Attached images are copied into the app's internal storage, with sensitive EXIF metadata stripped on save.
Android system backup policy
Markleaf sets android:allowBackup="false" to exclude app data from Android Auto Backup and device-to-device transfer. If you need to move to a new device or use multiple devices, you choose Markdown export, share, or a SAF folder mirror yourself.
User-initiated data movement
The following actions happen only when you perform them yourself, going through Android's explicit permission dialog or a UI choice you make.
- Export a single note or all notes as Markdown (
.md) - Share note text or files via the Android system share sheet
- Tap an external link in the body to delegate to the OS / default browser
- Copy to the clipboard
- Mirror Markdown files to a SAF folder you choose
Whether a SAF folder is synced by an external sync client such as Drive, Dropbox, OneDrive, Syncthing, or a NAS mount is the responsibility of that external app. Markleaf does not perform that sync itself.
Permissions
The only runtime-style permission Markleaf declares is android.permission.VIBRATE for haptic feedback. No build declares location, microphone, camera, contacts, notification, external-storage read, or media read permissions. Neither android.permission.INTERNET nor android.permission.REQUEST_INSTALL_PACKAGES is present in the F-Droid and Google Play builds. Both are present only in the sideload build, for the update check and the optional install described under Network.
Contact
For questions or security/privacy reports, please reach out via GitHub Issues.