AARKYNATE·LABS
TOOLS 2 LIVEUPTIME 10ySCAN 0%STATUS ● ONLINE
▶ Open Comms
§ PingOps · Privacy Policy

Local mode collects nothing. Cloud mode is opt-in and encrypted.

Effective June 1, 2026

1. Summary

PingOps runs in two modes — Local and Cloud — which have very different privacy implications. • In Local mode, PingOps does not transmit your data to any server we operate. Everything stays on your device. No account, no telemetry. • In Cloud mode (Cloud Free, Cloud Pro, Cloud Archon, Cloud Patron), PingOps transmits the endpoints you flip into Cloud mode to the PingOps Cloud backend so server-side checks can run while your phone sleeps. Cloud mode is strictly opt-in per endpoint. Authentication on iOS is Sign in with Apple — no password, no email harvesting. This policy describes both modes. Section 2 covers Local. Sections 3 through 11 cover Cloud. Section 12 onward applies to both.

2. Local mode — what stays on your device

When you use PingOps without enabling Cloud mode for an endpoint, the following data is stored exclusively in the on-device SwiftData container: • Endpoint configurations (URL, HTTP method, headers, request body, validation rules) • Check results (outcome, HTTP status code, latency, optional response body snippet for failed checks) • Group memberships, favorites, mute and snooze state, SLO settings • User preferences (auto-refresh interval, retention window, notification toggles) This data is private to your device. No PingOps server ever sees it. The app does not include analytics SDKs, advertising SDKs, or crash-reporting SDKs. The only outbound network traffic in Local mode is PingOps making the HTTP/HTTPS request (GET, POST, PUT, DELETE, HEAD) to the URLs you explicitly configured.

3. Cloud mode — what is transmitted and stored server-side

If you sign in to Cloud and toggle an endpoint into Cloud mode, the following per-endpoint data is transmitted from your device to the PingOps Cloud backend and stored in our Cloudflare D1 database: Stored as plaintext (queryable by our scheduler): • The endpoint's URL, friendly name, and HTTP method • Validation rules — expected status code, response keyword to match, JSON field to assert • Per-endpoint settings (group membership, check interval, mute/snooze state, SLO target, alert preferences) • Server-generated check results — outcome, HTTP status code, latency, optional failure-reason string Stored encrypted at rest, per-user, with AES-256-GCM (described in Section 5): • Any custom request headers you've defined • Any request body you've defined We chose this split deliberately: the URL and validation rules must be readable by the scheduler so it can dispatch checks, but custom headers and bodies frequently contain auth tokens (Authorization: Bearer …, X-API-Key, Cookie, signed payloads) and are encrypted so even an operator with raw database access cannot read them. PingOps Cloud is hosted on Cloudflare Workers + Cloudflare D1; the backend is described in our public source repository's SECURITY.md document.

4. Cloud mode — retention by tier

Server-side cloud check results are retained as follows, then deleted by a daily maintenance job at 03:00 UTC: • Cloud Free — 7 days • Cloud Patron (lifetime tier) — 7 days • Cloud Pro — 30 days • Cloud Archon — 90 days After your tier's retention window passes, older check results are deleted from the server. The endpoint configuration itself remains as long as you keep the endpoint in Cloud mode; toggling an endpoint back to Local removes it from the server on the next sync. Audit-log events (sign-in attempts, endpoint mutations, abuse flags) are retained for 90 days.

5. How the per-user encryption works

Custom request headers and request bodies are encrypted before they are written to D1. The key for each user is derived deterministically with HKDF-SHA-256: derived_key = HKDF(WORKER_AES_KEY, salt=apple_sub, info="pingops-cloud-endpoint-v1") WORKER_AES_KEY is a single high-entropy secret stored in Cloudflare Workers' secret manager — only the running Worker process can read it. The salt is your stable Sign in with Apple subject identifier. Without your apple_sub, even the WORKER_AES_KEY cannot decrypt your data. The ciphertext format is a 12-byte nonce followed by the AES-GCM ciphertext + authentication tag, stored as a single BLOB in the D1 row. A database leak that exposed only D1 rows would not expose your request headers or bodies, because the per-user salt is needed to derive each user's key. (The WORKER_AES_KEY itself is a separate secret, not in the database.)

6. Authentication — Sign in with Apple

Cloud mode on iOS uses Sign in with Apple exclusively. We do not collect a password. We do not collect an email address you didn't choose to share — if you use Apple's "Hide My Email" relay, the relay address is all we receive. What we store on the user record: • apple_sub — the stable identifier Apple provides • email_hash — a SHA-256 hash of the email (if you chose to share one). The raw email is never persisted. • Your tier, subscription product ID, and subscription expiry timestamp (so the server knows what you're paying for) • A list of your most recent APNs device tokens (capped at 5 — older tokens get rotated out) Session JWTs are issued for 30 days at sign-in and carry a tier claim. You can sign out at any time from the app's Cloud Settings; the device-side token is discarded immediately.

7. Notifications — what they contain

When you grant PingOps permission to send notifications, the app generates them locally on your device using the on-device data described in Section 2 plus (for Cloud-enabled endpoints) the most recent server check result. By default, failure notifications are aggregate: the title is "PingOps" and the body is a count ("3 endpoints failing"). They never contain endpoint names, URLs, or response data. This is the same notification surface whether you're on Free or a paid tier. If you opt into per-endpoint notifications (a Cloud Pro / Cloud Archon / Cloud Patron feature), the notification body includes the friendly name you set for the endpoint plus the failure category. Endpoint URLs and response bodies are never included in any notification. Push delivery uses Apple's APNs in the standard way. We do not operate a separate push relay.

8. Public status pages (Cloud Pro and above)

Cloud Pro, Cloud Patron, and Cloud Archon users may publish a public status page. When you opt in, PingOps generates a random UUID token at https://arkynate.com/pingops/status/<token>; anyone with that URL can view a read-only page. The public page intentionally never displays endpoint URLs, request bodies, or custom headers. Only the friendly name you set, current up/down/degraded status, uptime over 24h / 7d / 30d, a sparkline of recent latencies, and the timestamp of the last incident. You can revoke the public status page from inside the app at any time; the URL stops resolving immediately on revocation. Republishing later generates a fresh token; the old URL stays dead.

9. Subscriptions and payments

Cloud Pro and Cloud Archon are sold as auto-renewing subscriptions via the App Store. Cloud Patron is a one-time non-consumable purchase that grants the Cloud Patron tier for the life of the Apple ID. All payment, billing details, and subscription management are handled by Apple — PingOps does not see your payment method, card number, or billing address. The server receives, from iOS, the App Store receipt and parsed transaction state. We persist three fields on your user record so the scheduler knows what to gate on: • subscription_product_id — the App Store product ID you purchased (e.g. com.arkynate.pingops.pro.annual) • subscription_expires_at — Unix-epoch expiry for auto-renewable subs; NULL for Patron (lifetime) • subscription_updated_at — last time we ingested a receipt from iOS When an auto-renewable subscription expires, the daily maintenance job (and an inline check on the next authenticated request) downgrades the user to Cloud Free. Patron users (NULL expiry) are never auto-downgraded. Subscriptions auto-renew until you cancel them in iOS Settings → Apple ID → Subscriptions.

10. Live Activities, widgets, and deep links

PingOps uses ActivityKit to display active-incident Live Activities on the lock screen and Dynamic Island. These run on-device using the data described above; no separate transmission occurs for this feature. The app supports sharing an endpoint configuration as a cURL string, JSON document, or pingops:// deep link via iOS's standard share sheet. Sensitive header values (Authorization, X-API-Key, Cookie, and similar) are redacted by default before export so accidentally shared links don't leak credentials. When PingOps opens a pingops://import link, it parses the link locally on your device and inserts the endpoint into your store — no PingOps server is involved in this flow.

11. Third parties

The PingOps service has only two third-party data processors: • Apple — for Sign in with Apple (identity-token verification against Apple's JWKS), App Store subscription receipt validation, and APNs notification delivery. Governed by Apple's privacy policy. • Cloudflare — Cloudflare Workers + Cloudflare D1 are our backend hosting and database. Cloudflare may process traffic in any region of its global network; data residency is global. Cloudflare's logs sink ingests our application's structured log events (with tokens redacted and IPs SHA-256-hashed before persistence — see Section 13). There is no analytics SDK, no advertising SDK, no crash-reporting SDK, no third-party tracker in the app or on the backend.

12. Data deletion

You can delete your data at any time: Local data — uninstall the app, or use each endpoint's "Clear history" and "Delete endpoint" actions in the Danger Zone of the edit screen. Cloud data — open Cloud Settings → Delete Cloud account. This calls DELETE /v1/account on the backend, which immediately removes your user row and cascades through foreign keys to delete all endpoints, all check results, and all notification state. A single audit_log row recording the deletion is retained for 90 days, then auto-pruned. If the in-app flow fails for any reason, email jabitojavier@gmail.com from the email tied to your Sign in with Apple identity and we will action the deletion manually.

13. Logging and operator safeguards

PingOps Cloud's logging is designed so an operator can debug issues without seeing user data: • Authentication tokens are never written to logs. On a failed sign-in we log only the JOSE error name (e.g. "JWTExpired"). • IP addresses are SHA-256-hashed before persistence to the audit_log table. • Email addresses are SHA-256-hashed before persistence to the users.email_hash column. • Endpoint custom headers and request bodies are AES-256-GCM-encrypted at rest as described in Section 5. • Application logs go to Cloudflare's observability sink with the same redaction rules. Defences in place against abuse: • Server-side checks reject private-network targets (RFC1918, link-local, loopback, multicast, *.local, *.internal, IPv6 link-local) and re-evaluate this on every check fetch (DNS-rebinding defence). • /v1/auth/apple has a 15-requests-per-minute IP rate limit. • Server-side check interval is floored at 60 seconds (paid) or 5 minutes (Free) so we never amplify traffic toward a target.

14. Children's privacy

PingOps is rated 4+ and is not directed to children under 13. PingOps does not knowingly collect personal information from children under 13.

15. International data transfers

Because the PingOps Cloud backend runs on Cloudflare Workers and Cloudflare D1, requests and stored data may be processed in any region of Cloudflare's global network. By enabling Cloud mode for an endpoint, you consent to that processing.

16. Changes to this policy

If a future version of PingOps introduces a feature that materially changes what data is collected, transmitted, or shared, this policy will be updated and the App Store privacy declaration will be updated to match before that version ships. This page's effective date will reflect the change.

17. Contact

Privacy questions or deletion requests: jabitojavier@gmail.com. Abuse reports or security issues: abuse@arkynate.com (triage within 24 hours, response within 72).
← Back to PingOpsSupport →