Skip to content

Keryx Apple privacy, encryption, and SDK compliance

Approved: 25 August 2026

This document is the P1-07 compliance packet for Keryx for SafeCall on iPhone/iPad. It records required privacy manifests, purpose strings, App Privacy nutrition-label draft answers, encryption/export posture, and the in-app privacy link plan.

It does not claim that manifests or purpose strings are fixed in source, that an Xcode privacy report was generated from a signed archive, or that App Store Connect forms are submitted.

Purpose and non-goals

Purpose

  • Approve the Apple compliance answers and checklists that implementation and release evidence must satisfy.
  • Align store privacy answers with data classification and the privacy draft.
  • Assign handoffs for signed reports, live policy URL, and dependency audit.

Non-goals

  • Editing Info.plist, entitlements, or PrivacyInfo.xcprivacy in this item.
  • Building a signed IPA or uploading to App Store Connect.
  • Completing the full dependency/license audit (#102; inventory approved in dependency-ownership.md; machine SBOM/CI remain #112).
  • Setting production aps-environment in source — see ios-signing.md (#110 repo wired; App ID com.sourcectl.keryxapp registered; signed IPA proof pending).

Approved decisions

  • Owner and approver: Thomas Minitsios, 25 August 2026.
  • Encryption / export compliance: HTTPS-only / exempt — Keryx uses TLS (HTTPS) to reach the client ntfy host; launch does not claim custom non-exempt cryptography. App Store Connect should use the standard exemption path for apps that only use HTTPS encryption.
  • In-app privacy access: Settings/About (or equivalent) must open the published privacy URL {public_base}/keryx/privacy after HTTPS deploy per public-web-pages.md (P2-04). Until then, the link target is planned only.
  • Tracking: Keryx does not track users across apps/websites; no ATT; NSPrivacyTracking remains false; no analytics or crash SDK (P0-05).

Current gap baseline

SurfaceCurrent evidencePacket target
App privacy manifestNo app-level PrivacyInfo.xcprivacy under keryx/ios/Add before submission
Vendored ntfy manifestSource lists empty NSPrivacyAccessedAPITypes while NtfyPlugin.swift uses UserDefaultsDeclare UserDefaults required reason CA92.1
Purpose stringsInfo.plist still says lowercase keryx / “notification topics”Approved English strings below
EntitlementsSource development; production via signed IPA (#110)Verify on archive
Privacy policy URLPlanned path only; not liveP2-04 packet then deploy; in-app link
Flutter / plugin manifestsInventories and checklist in dependency-ownership.md (P1-09); source fixes and signed verification remain open#112 / #110 / #125

Evidence sources: keryx/ios/Runner/Info.plist, keryx/ios/Runner/Runner.entitlements, keryx/vendor/ntfy/ios/ntfy/Sources/ntfy/PrivacyInfo.xcprivacy, keryx/vendor/ntfy/ios/ntfy/Sources/ntfy/NtfyPlugin.swift, keryx/pubspec.yaml.

Privacy manifests checklist

App-level manifest

Before App Store submission, the Runner app (or equivalent packaged app target) must ship a privacy manifest that accurately reflects app-level accessed APIs and collected data types, consistent with this packet and the privacy draft.

Vendored ntfy (UserDefaults)

The vendored plugin stores subscription URL, topics, auth, and last-message ids in UserDefaults. The packaged ntfy framework privacy manifest must declare:

API categoryRequired reason codeWhy
User Defaults (NSPrivacyAccessedAPICategoryUserDefaults)CA92.1Access user defaults to read and write information that is only accessible to the app itself (ntfy subscription state for Keryx)

Empty NSPrivacyAccessedAPITypes in the current source manifest is not acceptable for launch. Implementation must update the vendored PrivacyInfo.xcprivacy (and verify the reason survives framework packaging).

Flutter and other plugins

Known privacy-impacting dependencies from keryx/pubspec.yaml (see dependency-ownership.md for the approved inventory; #112 owns machine SBOM completeness):

  • Flutter SDK
  • shared_preferences (UserDefaults / equivalent)
  • mobile_scanner (camera)
  • http
  • flutter_local_notifications
  • app_badge_plus
  • path dependency ntfy

Each must ship a verified privacy manifest or be covered by an approved app-level declaration. Signatures and required-reason coverage are verified on the signed release candidate, not by this document alone.

Purpose strings (approved English targets)

Replace current Info.plist strings before submission. Czech parity is #108.

KeyApproved English string
NSCameraUsageDescriptionKeryx uses the camera so you can scan a SafeCall QR code on your own device to enable administrator alert notifications.
NSUserNotificationUsageDescriptionKeryx shows SafeCall administrator alerts for your building when notifications are enabled.

Do not require ordinary administrators to understand ntfy “topics” in permission copy. Do not use the lowercase launcher-only branding as the sole product name in purpose strings; use Keryx / SafeCall as above.

App Privacy nutrition-label draft

Draft App Store Connect answers derived from data classification and privacy draft. Re-verify against the signed candidate and #102 inventory before submission.

TopicDraft answer
TrackingNo. Not used for tracking. No tracking domains.
Analytics / crash SDKNone at launch (P0-05).
Contact info collected by the appNo (support uses the SafeCall channel outside the app binary).
IdentifiersDevice/account identifiers are not harvested by a Keryx analytics SDK. Alert bodies may contain device names, MACs, or operational identifiers generated by SafeCall; treated as app functionality / notifications data linked to the administrator’s device copy, not sold, not used for tracking.
Product interaction / other dataLocal notification history (title, body, metadata, raw JSON for recovery) stored on device; purpose: app functionality.
DiagnosticsNo third-party crash SDK.
Health / sensitive categoriesNot a Health or Medical app; no health research collection.
Data linked to userLocal history is on the administrator’s device; disclose per Apple’s form categories honestly — do not claim “no data collected” if history and config are stored.
Data used to trackNo.

Final checkbox mapping must be filled in App Store Connect from this draft plus the Xcode privacy report (#110/#125).

Encryption / export compliance

Approved launch answer: Keryx only uses encryption as provided by the operating system / HTTPS (TLS) for network communication with the ntfy host. No proprietary or non-exempt encryption algorithm is introduced by Keryx for launch.

Record this as the App Store Connect export-compliance / encryption answer (standard HTTPS exemption). Reconfirm if a future release adds custom crypto.

In-app privacy access

WhenRequirement
After {public_base}/keryx/privacy is live (deploy)In-app Settings/About (or equivalent) exposes a reachable link to that HTTPS URL
Before live URLDo not invent a host; do not submit store metadata with a dead link
CzechPublic page and in-app label parity via #108

Evidence handoffs

EvidenceOwner
Implement manifests + purpose strings in sourceLater implementation
Complete dependency / SDK / license inventory#102 packet: dependency-ownership.md; machine SBOM/CI #112
Production signing; Xcode privacy report from signed archive#110ios-signing.md
Live privacy URLpublic-web-pages.md (P2-04); HTTPS deploy
ASC nutrition + encryption without unresolved warnings#125
Czech purpose-string / page parity#108
In-app About/Settings link wiringLater app implementation after URL is live

Explicit non-claims

Closing #100 approves this packet. It does not:

  • claim a privacy report was generated from a signed candidate;
  • claim manifests or purpose strings are already fixed in the iOS tree;
  • claim App Store Connect answers are submitted;
  • claim aps-environment is production.

Review record

  • Status: approved as the P1-07 Apple privacy compliance packet.
  • Date: 25 August 2026.
  • Approver: Thomas Minitsios under the P0-05 RACI.
  • Depends on: data-classification.md, legal/privacy.md.
  • Evidence sources: iOS Info.plist, entitlements, vendored ntfy privacy manifest and UserDefaults usage, keryx/pubspec.yaml.