# Privacy modelWhat is stored, what is not, and the sensitive categories the engine never sees.

## Architecture summary

Notification Guard's privacy model rests on three structural
properties:

1. **Local-only data.** Everything is stored in the app-private
   SQLite database. No cloud sync, no server-side state, no
   account.
2. **No network manifest permission.** `android.permission.INTERNET`
   is **not declared** in the AndroidManifest. The app cannot
   make network calls — period. This is verifiable via `aapt
   dump badging`.
3. **Privacy pre-filter.** Sensitive app categories (banking,
   2FA/authenticator, healthcare, public-authority apps) are
   sorted out **before** the rules engine sees their
   notifications. Their content never enters the database.

## What is stored

When a notification is captured for evaluation, the following is
written to the local SQLite database:

- The originating app package name (e.g. `com.whatsapp`).
- A timestamp.
- The category assigned (Social, Games, News, Shopping,
  Streaming, etc.).
- The rule decision: allow, snooze, or block.
- If blocked: the notification's title and body text (so the user
  can review what was suppressed).

For **blocked** notifications, the title and body are also
subject to **TTL cleanup** — by default, 24 hours after capture.
Manual "Clear all" purges everything immediately.

## What is never stored

For notifications from any app in the **sensitive categories**
list:

- The package is recognized at the listener-service boundary.
- The notification is **passed through immediately**, without
  evaluation or storage.
- No title, no body, no metadata about that notification ever
  reaches the database.

The sensitive-category list is hardcoded in the rules engine.
It includes (non-exhaustive):

- Banking apps (DKB, PayPal, savings-bank apps, …)
- 2FA / authenticator apps (Google Authenticator, Authy, …)
- Health-insurance apps (TK, AOK, Barmer, …)
- Public-authority apps (federal services, Elster, …)

This list can be extended via configuration at build time — for
deployments that need to add additional sensitive categories
(e.g. internal corporate apps that should never be filtered).

## Google Play compliance constraints

Notification Guard's architecture is structured around six hard
compliance constraints derived from current Google Play policies:

| ID | Constraint | How the app meets it |
|---|---|---|
| C1 | Prominent disclosure and consent | 4-step onboarding wizard before listener-permission activation. |
| C2 | No `SYSTEM_ALERT_WINDOW` | Re-notifications use `NotificationManager`, no overlay window. |
| C3 | Data retention TTL | Configurable retention (24h default), periodic cleanup task, manual clear. |
| C4 | Contact picker instead of `READ_CONTACTS` | The full `READ_CONTACTS` permission is **not** used. Future contact-aware rules will use the Android Contact Picker. |
| C5 | Privacy filter (sensitive-category blocklist) | Hardcoded pre-filter at the engine entry. |
| C6 | No network layer | `android.permission.INTERNET` not in manifest. No HTTP-client dependencies in any `Cargo.toml`. |

These are not aspirational — they are structural. Removing any
one of them would require an architecture change, not just a
config flip.

## Manifest permissions

Four declared permissions, each tied to a concrete feature:

- **`BIND_NOTIFICATION_LISTENER_SERVICE`** — Core function.
  Without this, the app cannot read or filter notifications.
  User-activated via system settings.
- **`RECEIVE_BOOT_COMPLETED`** — Reconnects the listener after a
  device reboot.
- **`WAKE_LOCK`** — Triggers snooze timers reliably from Doze
  mode (planned for phase 2).
- **`POST_NOTIFICATIONS`** — Surfaces our own re-notifications
  (released or snoozed) without an overlay window (see C2).

No runtime permissions, no restricted special access beyond the
notification listener.

## How to verify

If you are evaluating whether to deploy this in your
organization:

1. **Inspect the APK manifest.**

   ```sh
   aapt dump badging notification-guard.apk | grep -i permission
   ```

   Confirm that `android.permission.INTERNET` does not appear.

2. **Inspect network behaviour.**

   Run the app on a test device with full traffic capture (PCAP,
   a transparent proxy). Confirm no outgoing connections.

3. **Inspect the database.**

   The SQLite file lives in app-private storage. On a rooted
   test device, copy it out and confirm that no notifications
   from sensitive-category apps appear.

If any of those checks comes back with a result you would not
expect, please send details via the [Contact](/contact/) page.
The whole product depends on these guarantees being verifiable.
