From 212984f376d8efbd9ac4b33cba4d14e28da143b2 Mon Sep 17 00:00:00 2001 From: Yusuf GUNDOGDU Date: Tue, 27 Oct 2026 20:39:24 +0300 Subject: [PATCH] feat(legal): a privacy policy page for the Android app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Google Play requires a policy that applies specifically to the app and discloses what the app itself collects. The existing /privacy-policy is the website's: cookies, analytics and the YouTube embed. It says nothing about the access token the app sends, the statements it sends to Studio, the crash reports, or how to delete any of it, so entering it in the Play Console risks a review rejection. This is the wording the app ships with, in libredb/libredb-mobile `docs/privacy-policy.md`; the two are updated together. The page reuses the existing policy's layout and styles, and the vendor details come from `data/company` rather than being typed out again. The route is registered in site.config.json, which is also what puts it in the accessibility audit, and described in llms.txt — the three guards that caught it missing. --- site.config.json | 1 + src/pages/llms.txt.ts | 1 + src/pages/mobile-privacy-policy.astro | 341 ++++++++++++++++++++++++++ 3 files changed, 343 insertions(+) create mode 100644 src/pages/mobile-privacy-policy.astro diff --git a/site.config.json b/site.config.json index 9728310..16a544a 100644 --- a/site.config.json +++ b/site.config.json @@ -47,6 +47,7 @@ "/playground", "/faq", "/privacy-policy", + "/mobile-privacy-policy", "/blog", "/rss.xml", "/404" diff --git a/src/pages/llms.txt.ts b/src/pages/llms.txt.ts index 55628d6..1b881d2 100644 --- a/src/pages/llms.txt.ts +++ b/src/pages/llms.txt.ts @@ -45,6 +45,7 @@ const DESCRIPTIONS: Record = { '/faq': 'The questions asked before adopting it.', '/blog': 'Release notes and engineering writing.', '/privacy-policy': 'What is collected, by whom, and on what legal basis.', + '/mobile-privacy-policy': 'What the LibreDB Mobile Android app sends, keeps on the device, and how to delete it.', }; /** Routes that are not pages a reader should be pointed at. */ diff --git a/src/pages/mobile-privacy-policy.astro b/src/pages/mobile-privacy-policy.astro new file mode 100644 index 0000000..ee285c7 --- /dev/null +++ b/src/pages/mobile-privacy-policy.astro @@ -0,0 +1,341 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import { VENDOR, VENDOR_ADDRESS_FULL, vendorOrganizationSchema } from '../data/company'; +import { site } from '../lib/site'; + +// The policy for the Android app, kept apart from /privacy-policy, which is the website's. Google Play requires a +// policy that applies specifically to the app and discloses what the app itself collects; the website's cookie and +// analytics policy does not do that. The wording here is the one the app ships with, in +// libredb/libredb-mobile `docs/privacy-policy.md`, and the two are updated together. +const UPDATED = '2026-10-27'; +const updatedLabel = new Date(UPDATED).toLocaleDateString('en-GB', { + day: 'numeric', + month: 'long', + year: 'numeric', +}); + +const registrationRows = [ + { label: 'Registered company name', value: VENDOR.legalName }, + { label: 'Trade name', value: VENDOR.tradeName }, + { label: 'Registered office', value: VENDOR_ADDRESS_FULL }, + { label: 'Tax office', value: VENDOR.taxOffice }, + { label: 'Tax ID (VKN)', value: VENDOR.taxId }, + { label: 'MERSIS No', value: VENDOR.mersisNo }, + { label: 'Trade Registry No', value: VENDOR.tradeRegistryNo }, +]; + +const schema = [ + vendorOrganizationSchema, + { + '@type': 'WebPage', + name: 'LibreDB Mobile Privacy Policy', + url: `${site.url}/mobile-privacy-policy`, + dateModified: UPDATED, + publisher: { '@id': VENDOR.schemaId }, + }, +]; +--- + + +
+ +
+

Legal

+

+ LibreDB Mobile Privacy Policy +

+

+ Last updated +

+ +
+

+ This policy describes what LibreDB Mobile for Android does with your data. LibreDB Mobile is a client of + LibreDB Studio: it signs you in through Keycloak and shows the databases that Studio offers you. Questions + about this policy go to info@libredb.org. +

+

+ This policy covers the app. The policy for the website is a separate one, at + libredb.org/privacy-policy. +

+ +

Who publishes the app

+

+ LibreDB Mobile is published on Google Play by {VENDOR.tradeName}, the trade name of {VENDOR.legalName}, a + limited liability company registered in Turkiye and the data controller responsible for the processing + described in this policy. The details below are matters of public record and can be verified independently. +

+
+ { + registrationRows.map((row) => ( +
+
{row.label}
+
{row.value}
+
+ )) + } +
+

+ Full company information is published at {VENDOR.url} ↗. +

+ +

The servers the app talks to

+

The app talks to four kinds of servers, and to no others on its own:

+
    +
  • + Keycloak, the sign-in server of the LibreDB deployment the app was built for. You sign in + on Keycloak's own page, in the device's browser, so the app never sees your password. Keycloak gives the app + tokens that identify you. +
  • +
  • + LibreDB Studio of the same deployment. The app sends Studio your Keycloak access token with its + requests, so Studio knows who you are and what you may use. The access token carries what Keycloak puts into it, + such as your username, your e-mail address and your name. The app also sends Studio what you ask it to do: the + connection you open, the objects you look at and the statements you run. +
  • +
  • + LibreDB Platform of the same deployment, but only in a build that includes Platform mode, and + only after you pick the Platform entry on the sign-in page or switch to Platform in the profile. The app sends + Platform your Keycloak access token with its requests and receives your Platform identity: your Platform user + id, e-mail address, name and organisation. The app holds that identity in memory while you are signed in and never + stores it on the device. Platform's first answer to your account creates your Platform user record and takes one + of the license's admin seats. In Platform mode the app shows who holds access to a connection: their usernames + and e-mail addresses, and the name or e-mail address of the admin who granted it. It holds them in memory while + the page is open and never stores them on the device, and it sends Platform the removals of access you ask for. + When you search the directory to give someone access, the search text goes to Platform, which searches Keycloak, + and the app shows the usernames, names, e-mail addresses, enabled state and Studio role of the users found. It + keeps them in memory only while the screen is open, keeps no search history and stores none of it, and it sends + Platform the access you give or change: the user, the level and the expiry. In Platform mode the app also sends + Platform the enabling or disabling of a connection that you ask for, and nothing else about that connection. In + Platform mode the app shows the audit log of the governed queries: the users who ran them (their usernames and + Keycloak ids), the connections, the statement text, which can carry data from the databases, the database error + messages and the times. It holds them in memory while the audit page is open and never stores them on the device, + and it sends Platform the filters you set, the statement search text included. +
  • +
  • + Sentry, a crash reporting service, but only when the build was made with a Sentry project + key. See Crash reports below. +
  • +
+

+ The organisation that runs the deployment operates Keycloak, Studio and Platform, and decides what they + record. For example, Studio can keep an audit log of sign-ins and sign-outs and, depending on its settings, a + record of the statements you run. That organisation's own privacy terms cover what those servers keep. +

+

The app reaches Keycloak, Studio, Platform and Sentry over HTTPS, which encrypts the traffic.

+ +

What the app does not do

+
    +
  • + The app holds no database password or other database credential: Studio keeps them and opens every database + connection. +
  • +
  • + The app shows no advertising, contains no advertising, third-party analytics or tracking SDK, and sends + nothing about how you use it beyond the crash reports, session records and timing information described + below. +
  • +
  • The app does not read your contacts, location, photos, files or other apps' data.
  • +
  • The app does not sell your data or share it with anyone for advertising.
  • +
+ +

What the app keeps on the device

+
    +
  • + Your session tokens, in Android's secure storage, encrypted with a key held by the Android + Keystore. Signing out deletes them. +
  • +
  • + Your drafts and statement history: the editor's draft for each connection and the + statements you ran, encrypted on the device with a key for your account alone. They stay after you sign out, + so you find them again when you sign in with the same account, and another account on the device cannot read + them. +
  • +
  • + Your connection choices: the connections you starred or opened recently, the connection you + had open last and the database you last used on it, and the sections of the connection list you collapsed. +
  • +
  • + Device preferences: the language, the theme and whether results show as cards or as a + table. +
  • +
+

+ The app keeps no rows of query results after it closes. While it runs, it keeps the lists, counts and + descriptions of a connection's objects in memory for up to 10 minutes, so going back does not ask Studio + again. What you type into the object search goes only to Studio, and the app keeps no search history. + Android's cloud backup is turned off for the app, and its preferences, drafts and history are left out of + device-to-device transfers. +

+ +

Sharing and copying

+

+ The app passes data to another app only when you ask it to. When you copy a value of a result, the app copies + what the screen shows, so a masked value is copied as its mask. When you share an object's source, such as a + view's definition, the system's share sheet sends it to the app you choose. A source longer than 100,000 + characters is shared as a file, and that file can stay in the app's temporary storage until Android clears it + or you uninstall the app. +

+ +

Crash reports

+

+ A build made with a Sentry project key sends a report to Sentry when the app runs into an error. A report + holds the error and where in the app it happened, the app's version, technical details of the device such as + its model, Android version, language, free memory and battery level, a random identifier of the installation, + and a trail of the events before the error, such as the screens you opened and the app going to the + background. A build with a Sentry project key also sends a session record each time you use the app: when the + session started and ended, how long it lasted, whether it ended in a crash, and the installation identifier. + It also sends timing information for about one in five app starts and screen changes, to show where the app is + slow. +

+

+ Before a report leaves the device, the app removes e-mail addresses, tokens, passwords and other credentials + from it. A report carries no screenshot, no layout of the screen, no request body and no screen recording of + the session. Sentry receives your device's IP address with each report, as with any connection to a server, + and derives an approximate location, such as a city and a country, from that address, unless the Sentry + project is set not to store IP addresses. A build made without a Sentry project key sends no reports. +

+ +

Protections on the device

+
    +
  • + The screens that show query results, a row's detail, a key's value, an object's source, the audit log list + or an audit event's statement and error message are kept out of screenshots, screen recordings and the + recent apps view. +
  • +
  • Columns whose names look sensitive, such as e-mail, password or card number, are masked on screen.
  • +
  • The app signs you out after 15 minutes without input.
  • +
+ +

Deleting your data

+
    +
  • + Remove my data, in the Privacy section of Settings, deletes what the app keeps for the + signed-in account (the drafts, the history and the connection choices) and then signs you out. It keeps the + language, the theme and the result view preference, which belong to the device. +
  • +
  • Uninstalling the app deletes everything it keeps on the device.
  • +
  • + Crash reports already sent stay in Sentry until they expire; write to + info@libredb.org to have them deleted sooner. +
  • +
  • + Data that Keycloak or Studio keep about you is held by the organisation that runs them; ask that + organisation to delete it. +
  • +
+ +

Children

+

The app is a tool for people who work with databases and is not directed at children.

+ +

Changes to this policy

+

+ When the app starts handling data in a new way, this policy is updated before that version is released, and + the date at the top changes. +

+
+
+
+
+ +