Merge pull request 'Add the Calendula and Agendula privacy policies' (#7) from calendula-privacy-policy into main
Reviewed-on: #7
This commit was merged in pull request #7.
This commit is contained in:
@@ -7,7 +7,7 @@ const year = new Date().getFullYear();
|
||||
<footer class="site-footer">
|
||||
<div class="site-footer__inner">
|
||||
<p>
|
||||
© {year} {SITE.author} · <a href="/uses">Uses</a> ·
|
||||
© {year} {SITE.author} · <a href="/uses">Uses</a> ·{' '}
|
||||
<a href="/impressum">Impressum</a> · <a href="/datenschutz">Datenschutz</a>
|
||||
</p>
|
||||
{
|
||||
|
||||
@@ -0,0 +1,328 @@
|
||||
---
|
||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||
import { LEGAL } from '../../consts';
|
||||
|
||||
// App privacy policy for Agendula — required as a public URL by the Google Play
|
||||
// Console (mandatory for every app) and linked from the app's About card.
|
||||
// Deliberately separate from /datenschutz, which covers this website only.
|
||||
//
|
||||
// Kept in English because SITE.lang is 'en' and Play's default store listing is
|
||||
// en-US; /datenschutz and /impressum stay German for legal reasons.
|
||||
//
|
||||
// Source of truth for the facts below: the Agendula repository (docs/PRIVACY.md,
|
||||
// docs/SYNC.md, AndroidManifest.xml, backup_rules.xml). Unlike Calendula,
|
||||
// Agendula *does* hold INTERNET — it has its own CalDAV sync — so the wording
|
||||
// here turns on "only to the server you entered", not on the absence of the
|
||||
// permission. If sync, permissions or data paths change, update this page and
|
||||
// the "Last updated" date.
|
||||
const lastUpdated = '9 September 2026';
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="Agendula — Privacy Policy"
|
||||
description="Privacy policy for the Agendula Android task app. No accounts, no analytics, no tracking — data leaves your device only for the CalDAV server you choose."
|
||||
width="narrow"
|
||||
>
|
||||
<article class="prose">
|
||||
<h1 class="page-title">Privacy Policy — Agendula</h1>
|
||||
|
||||
<p>
|
||||
<strong>Last updated:</strong> {lastUpdated}<br />
|
||||
Applies to the Android app <strong>Agendula</strong>{' '}
|
||||
(package <code>de.jeanlucmakiola.agendula</code>), all versions and all
|
||||
distribution channels.
|
||||
</p>
|
||||
|
||||
<h2>In short</h2>
|
||||
<p>
|
||||
Agendula has no servers, no user accounts and no analytics. Your tasks live
|
||||
on your device. They leave it in exactly one case: if you set up a CalDAV
|
||||
account yourself, they are synchronised with <strong>the server you
|
||||
entered</strong> — and with nothing and no one else. Nothing is ever sent
|
||||
to the developer.
|
||||
</p>
|
||||
|
||||
<h2>1. Controller</h2>
|
||||
<p>
|
||||
{LEGAL.business}<br />
|
||||
{LEGAL.street}<br />
|
||||
{LEGAL.city}<br />
|
||||
Email: <a href={`mailto:${LEGAL.email}`}>{LEGAL.email}</a>
|
||||
</p>
|
||||
|
||||
<h2>2. No data collection by the developer</h2>
|
||||
<p>
|
||||
Agendula contains <strong>no analytics, no tracking, no advertising, no
|
||||
crash-reporting SDK and no third-party service that reports anything
|
||||
anywhere</strong>. No user profile is created, no advertising or device
|
||||
identifier is generated, and no data is shared with or sold to anyone.
|
||||
There is no Agendula account, and the developer operates no server that the
|
||||
app talks to.
|
||||
</p>
|
||||
<p>
|
||||
All of this is verifiable in the{' '}
|
||||
<a href="https://codeberg.org/jlmakiola/agendula" rel="noopener">source code</a>,
|
||||
which is public.
|
||||
</p>
|
||||
|
||||
<h2>3. Where your tasks live — your choice</h2>
|
||||
<p>
|
||||
Agendula offers two storage modes, and you pick one:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>On your device (the default)</strong> — your task lists, tasks and
|
||||
reminders are kept in Agendula's own database inside the app's private
|
||||
storage. Nothing is published to other apps, and uninstalling the app
|
||||
removes it.
|
||||
</li>
|
||||
<li>
|
||||
<strong>In a tasks provider you already use</strong> — OpenTasks or
|
||||
tasks.org. Agendula then reads and writes that app's task database
|
||||
through Android's provider mechanism, after you grant its read/write
|
||||
permission. Whatever already synchronises that provider (DAVx5,
|
||||
SmoothSync, DecSync CC, …) keeps doing so, unchanged; that synchronisation
|
||||
is performed by those apps, not by Agendula, and their privacy policies
|
||||
apply to it.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>4. CalDAV sync — the only case where your tasks leave the device</h2>
|
||||
<p>
|
||||
Sync is optional and off until you add an account. If you add one,
|
||||
everything below happens between your device and <strong>the server you
|
||||
nominated</strong>, and nowhere else.
|
||||
</p>
|
||||
|
||||
<h3>What is stored on your device</h3>
|
||||
<p>
|
||||
The server address, your username, and your password or app password. The
|
||||
password is encrypted with a key held in the Android Keystore, which cannot
|
||||
be exported from the device.
|
||||
</p>
|
||||
|
||||
<h3>What is transmitted, and to whom</h3>
|
||||
<ul>
|
||||
<li>
|
||||
The tasks in the synchronised lists, as standard iCalendar
|
||||
(<code>VTODO</code>) data, and the credentials needed to authenticate.
|
||||
</li>
|
||||
<li>
|
||||
Requests carry the user agent <code>Agendula (Android)</code> — a fixed
|
||||
string, so that you can recognise and revoke the session on your server.
|
||||
No device identifier is sent.
|
||||
</li>
|
||||
<li>
|
||||
Connections are HTTPS. Cleartext HTTP is refused, so credentials are
|
||||
never sent over an unencrypted connection.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Under Google Play's Data Safety definitions this counts as{' '}
|
||||
<strong>collected</strong> — Play defines collection as transmitting data
|
||||
off the device, regardless of who receives it — and <strong>not
|
||||
shared</strong>, because the only recipient is the server you chose. Data is
|
||||
encrypted in transit.
|
||||
</p>
|
||||
|
||||
<h3>Finding your server</h3>
|
||||
<p>
|
||||
When you type a server address or an email domain, Agendula follows the
|
||||
standard discovery procedure (RFC 6764): a DNS lookup for the{' '}
|
||||
<code>_caldavs._tcp</code> service record of that domain, then{' '}
|
||||
<code>/.well-known/caldav</code> on the host. The DNS query goes to whichever
|
||||
resolver your device or network uses, and the requests go to the domain you
|
||||
typed — no directory of servers is consulted and no lookup is sent to the
|
||||
developer.
|
||||
</p>
|
||||
|
||||
<h3>Signing in to a Nextcloud</h3>
|
||||
<p>
|
||||
If the server is a Nextcloud, Agendula uses Nextcloud's Login Flow v2: your
|
||||
browser opens <em>your own server's</em> login page, you authorise there,
|
||||
and the server hands the app a dedicated app password. Agendula never sees
|
||||
your actual account password. The app password appears in your server's
|
||||
“Devices & sessions” list as <code>Agendula (Android)</code>, and you can
|
||||
revoke it there at any time. Removing the account in Agendula revokes it too,
|
||||
where the server supports that.
|
||||
</p>
|
||||
|
||||
<h3>Your server's own policy</h3>
|
||||
<p>
|
||||
Your CalDAV provider has its own privacy policy, and your data on their
|
||||
server is governed by it. Agendula has no relationship with them.
|
||||
</p>
|
||||
<p>
|
||||
A note on certificates: Agendula trusts private certificate authorities that
|
||||
you have installed in your device's user store, because self-hosted servers
|
||||
routinely use them. That is a deliberate trade-off in favour of
|
||||
self-hosters — any CA installed on your device (for example by an employer's
|
||||
management profile) can, in principle, intercept traffic from the app, as it
|
||||
can from other apps that make the same choice.
|
||||
</p>
|
||||
|
||||
<h2>5. Other data Agendula handles on your device</h2>
|
||||
|
||||
<h3>Reminders and notifications</h3>
|
||||
<p>
|
||||
Due-date reminders are scheduled by the app itself and displayed as local
|
||||
notifications. Nothing is sent to a push service — there is no push service.
|
||||
</p>
|
||||
|
||||
<h3>Export files</h3>
|
||||
<p>
|
||||
You can export your tasks as standard iCalendar <code>.ics</code> files.
|
||||
Agendula writes exactly the file you select through Android's system file
|
||||
picker, and has no access to other files.
|
||||
</p>
|
||||
|
||||
<h3>App settings</h3>
|
||||
<p>
|
||||
Your preferences (theme, language, list and reminder defaults and similar)
|
||||
are stored locally on your device and are removed when you uninstall the
|
||||
app.
|
||||
</p>
|
||||
|
||||
<h2>6. Backups</h2>
|
||||
<p>
|
||||
If Android Auto Backup is enabled on your device, your tasks and settings
|
||||
may be backed up to your own Google account, under Google's terms — the
|
||||
developer has no access to it. Two things are deliberately excluded from
|
||||
that backup: your stored CalDAV password, and Agendula's per-device sync
|
||||
bookkeeping. After restoring onto a new device you therefore sign in to your
|
||||
server again.
|
||||
</p>
|
||||
|
||||
<h2>7. Crash reports</h2>
|
||||
<p>
|
||||
If Agendula crashes, it offers to report the problem. Nothing is sent
|
||||
automatically, even though the app has network access. The report is copied
|
||||
to your clipboard and your browser is opened with the project's issue
|
||||
tracker, the text pre-filled. <strong>You see the full content, you decide
|
||||
whether to submit it, and you can edit or discard it.</strong>
|
||||
</p>
|
||||
<p>Such a report contains:</p>
|
||||
<ul>
|
||||
<li>app version,</li>
|
||||
<li>Android version,</li>
|
||||
<li>device manufacturer and model,</li>
|
||||
<li>your device language,</li>
|
||||
<li>the timestamp,</li>
|
||||
<li>and the technical stack trace.</li>
|
||||
</ul>
|
||||
<p>
|
||||
It is built from that fixed list and nothing else: <strong>no</strong> task
|
||||
data, <strong>no</strong> server address or credentials, <strong>no</strong>{' '}
|
||||
account names, <strong>no</strong> log files and <strong>no</strong> personal
|
||||
identifiers.
|
||||
</p>
|
||||
<p>
|
||||
If you choose to submit it, the report becomes a public issue on the
|
||||
project's issue tracker at Codeberg, operated by Codeberg e. V.
|
||||
Their privacy policy then applies to that submission.
|
||||
</p>
|
||||
|
||||
<h2>8. External links</h2>
|
||||
<p>
|
||||
The app links to the source code, the licence, the issue tracker, the
|
||||
translation platform (Weblate) and a voluntary donation page (Ko-fi).
|
||||
Following one of these links opens your browser and leaves the app; the
|
||||
privacy policy of the respective website then applies. Agendula transmits no
|
||||
data of yours in the process — it only opens the address.
|
||||
</p>
|
||||
|
||||
<h2>9. Permissions and why they exist</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<code>INTERNET</code>, <code>ACCESS_NETWORK_STATE</code> — CalDAV sync with
|
||||
the server you configure, and checking whether a connection exists before
|
||||
trying. Without a CalDAV account, no connection is made.
|
||||
</li>
|
||||
<li>
|
||||
<code>READ_SYNC_SETTINGS</code>, <code>WRITE_SYNC_SETTINGS</code> — register
|
||||
the sync account with Android's sync framework so it can be scheduled.
|
||||
</li>
|
||||
<li><code>POST_NOTIFICATIONS</code> — show reminders.</li>
|
||||
<li>
|
||||
<code>USE_EXACT_ALARM</code>, <code>SCHEDULE_EXACT_ALARM</code> — deliver
|
||||
reminders at the exact due time.
|
||||
</li>
|
||||
<li>
|
||||
<code>RECEIVE_BOOT_COMPLETED</code> — re-register pending reminders after a
|
||||
restart.
|
||||
</li>
|
||||
<li>
|
||||
<code>org.dmfs.permission.READ_TASKS</code> /{' '}
|
||||
<code>WRITE_TASKS</code> and <code>org.tasks.permission.READ_TASKS</code> /{' '}
|
||||
<code>WRITE_TASKS</code> — optional, requested only if you choose the
|
||||
external-provider storage mode, and only for the provider you selected
|
||||
(OpenTasks or tasks.org).
|
||||
</li>
|
||||
<li>
|
||||
<code>WAKE_LOCK</code>, <code>FOREGROUND_SERVICE</code> — required by the
|
||||
Android system component used for scheduled background work
|
||||
(WorkManager); on older Android versions it needs them to run an
|
||||
expedited sync.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Agendula publishes no content provider of its own and declares no
|
||||
permissions that other apps could request.
|
||||
</p>
|
||||
|
||||
<h2>10. Distribution channels</h2>
|
||||
<p>
|
||||
Agendula is distributed via F-Droid, Obtainium, a self-hosted repository
|
||||
and, where applicable, the Google Play Store. When you download or update
|
||||
the app, the operator of that channel processes data (such as your IP
|
||||
address) under their own privacy policy. This is outside the developer's
|
||||
control and unrelated to the app's own behaviour.
|
||||
</p>
|
||||
|
||||
<h2>11. Children</h2>
|
||||
<p>
|
||||
Agendula is not directed at children and collects nothing about anyone.
|
||||
</p>
|
||||
|
||||
<h2>12. Deleting your data</h2>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>Remove a CalDAV account</strong> (Settings → Accounts) deletes the
|
||||
stored credential and, where the server supports it, revokes the app
|
||||
password. The task lists become device-only lists rather than being
|
||||
destroyed.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Remove an account and delete its local data</strong> removes those
|
||||
lists and their tasks as well.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Uninstalling the app</strong> removes everything Agendula stored on
|
||||
the device.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Data on your CalDAV server is deleted on that server; data in an external
|
||||
tasks provider is deleted in that app.
|
||||
</p>
|
||||
|
||||
<h2>13. Your rights</h2>
|
||||
<p>
|
||||
The developer stores no personal data of yours — the only data transfer the
|
||||
app performs is between your device and a server you operate or chose. There
|
||||
is therefore no data held by the developer to which rights of access,
|
||||
rectification, erasure, restriction, data portability or objection
|
||||
(Art. 15–21 GDPR) could apply. Your tasks are exportable as standard{' '}
|
||||
<code>.ics</code> files from within the app at any time. You may contact the
|
||||
address above with any question, and you have the right to lodge a complaint
|
||||
with a supervisory authority.
|
||||
</p>
|
||||
|
||||
<h2>14. Changes to this policy</h2>
|
||||
<p>
|
||||
Should the app's functionality change in a way that affects data processing,
|
||||
this policy will be updated and the date at the top adjusted. The version
|
||||
history is publicly traceable in the project's source repository.
|
||||
</p>
|
||||
</article>
|
||||
</BaseLayout>
|
||||
@@ -26,7 +26,7 @@ const lastUpdated = '28 July 2026';
|
||||
|
||||
<p>
|
||||
<strong>Last updated:</strong> {lastUpdated}<br />
|
||||
Applies to the Android app <strong>Calendula</strong>
|
||||
Applies to the Android app <strong>Calendula</strong>{' '}
|
||||
(package <code>de.jeanlucmakiola.calendula</code>), all versions and all
|
||||
distribution channels.
|
||||
</p>
|
||||
@@ -174,7 +174,7 @@ const lastUpdated = '28 July 2026';
|
||||
system dialog for the “Reliable delivery” setting.
|
||||
</li>
|
||||
<li>
|
||||
<code>WAKE_LOCK</code>, <code>FOREGROUND_SERVICE</code>, <code>ACCESS_NETWORK_STATE</code>
|
||||
<code>WAKE_LOCK</code>, <code>FOREGROUND_SERVICE</code>, <code>ACCESS_NETWORK_STATE</code>{' '}
|
||||
— required by the Android system component used for scheduled background
|
||||
work (WorkManager).
|
||||
</li>
|
||||
|
||||
@@ -15,7 +15,7 @@ import { LEGAL } from '../consts';
|
||||
<article class="prose">
|
||||
<h1 class="page-title">Uses</h1>
|
||||
<p>
|
||||
A running colophon of the tools and stack behind this site, the
|
||||
A running colophon of the tools and stack behind this site, the{' '}
|
||||
<a href="/work">Floret apps</a>, and the infrastructure they run on. The
|
||||
throughline: open, self-hostable standards, and as little reliance on
|
||||
third-party services as I can manage.
|
||||
@@ -29,14 +29,14 @@ import { LEGAL } from '../consts';
|
||||
the repo.
|
||||
</li>
|
||||
<li>
|
||||
Typefaces are <a href="https://rsms.me/inter/" rel="noopener">Inter</a>
|
||||
Typefaces are <a href="https://rsms.me/inter/" rel="noopener">Inter</a>{' '}
|
||||
and <a href="https://www.jetbrains.com/lp/mono/" rel="noopener">JetBrains
|
||||
Mono</a>, self-hosted via Fontsource — no Google Fonts CDN, so no
|
||||
third-party request on page load.
|
||||
</li>
|
||||
<li>
|
||||
Analytics is self-hosted <a href="https://umami.is" rel="noopener">Umami</a>:
|
||||
cookieless, no cross-site tracking, no personal profiles. See the
|
||||
cookieless, no cross-site tracking, no personal profiles. See the{' '}
|
||||
<a href="/datenschutz">Datenschutzerklärung</a> for what that means.
|
||||
</li>
|
||||
<li>Icons from <a href="https://iconify.design" rel="noopener">Iconify</a> (Material Design Icons + Simple Icons).</li>
|
||||
@@ -47,7 +47,7 @@ import { LEGAL } from '../consts';
|
||||
<li><strong>Kotlin</strong> and <strong>Jetpack Compose</strong>, designed in <strong>Material 3 Expressive</strong>.</li>
|
||||
<li>
|
||||
No reinvented sync stack — each app is a front-end over a platform
|
||||
provider (<code>CalendarContract</code>, the OpenTasks
|
||||
provider (<code>CalendarContract</code>, the OpenTasks{' '}
|
||||
<code>TaskContract</code>) and open standards like CalDAV, iCalendar, and
|
||||
DecSync.
|
||||
</li>
|
||||
@@ -69,7 +69,7 @@ import { LEGAL } from '../consts';
|
||||
</ul>
|
||||
|
||||
<p class="muted">
|
||||
This list grows as the stack does. Spotted something you'd ask about?
|
||||
This list grows as the stack does. Spotted something you'd ask about?{' '}
|
||||
<a href={`mailto:${LEGAL.email}`}>Get in touch</a>.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
Reference in New Issue
Block a user