Last reviewed: October 12, 2026
This policy defines the security practices Jointly follows to protect consumer financial data, maintain system integrity, and comply with applicable data privacy laws. It applies to all systems, services, and personnel involved in developing and operating the Jointly application.
This policy covers:
| Classification | Description | Examples |
|---|---|---|
| Restricted | Financial credentials and tokens | Plaid access tokens, API secrets (Note: FinanceKit uses no access tokens — authorization is OS-managed) |
| Confidential | User financial data | Transactions (including FinanceKit-sourced), account numbers, split details, receipt images |
| Internal | Operational data | User profiles, profile photos, partnership records, app configuration, subscription status |
| Internal | Analytics and behavioral metrics | Feature usage counts, user properties, custom category counts (never the names), survey responses (no PII) |
| Public | Publicly accessible content | Privacy policy, landing page, App Store listing |
Production Systems: Access to the Firebase and Google Cloud consoles, the Plaid Dashboard, GitHub, App Store Connect, the Apple Developer account and the domain registrar is limited to authorized personnel. Every one of those accounts requires multi-factor authentication (MFA). Least privilege applies to services as well as people: the runtime identity for Cloud Functions holds only the specific roles it needs (for example database, storage, authentication and messaging access), not broad project-editor rights.
Access Reviews: Access is reviewed every quarter, and whenever a person or service provider gains or loses access. Each review covers cloud IAM principals and roles, service-account keys, app-integrity debug tokens, admin allowlists, and the member lists and MFA status of every account above. Reviews are logged with their date and results, and anything found is fixed or tracked to resolution.
Firestore Security Rules: Client-side access is governed by Firestore Security Rules, reviewed and deployed via version control. Collections containing sensitive data (e.g., access tokens) have rules preventing any client-side read access, restricting access to server-side Cloud Functions only. Users can only read and write their own data; partnership data is scoped to matched partners. Premium/subscription fields are server-written only — client writes are denied, and entitlements are set exclusively by Cloud Functions after StoreKit receipt verification against Apple's certificate chain.
Cloud Storage Security Rules: Receipt files (images and PDFs) and profile photos in Cloud Storage are governed by version-controlled Storage Security Rules. Receipt reads are scoped to the owning transaction's owner (private receipts) or either partner on the associated split (shared receipts); profile-photo access is scoped to the owner. Writes require authentication and enforce content-type (images, plus PDFs for receipts) and size limits, and a server-side check deletes any upload whose contents don't match its declared type. Files are rendered via tokenized download URLs, and the rules close raw-path access.
API Keys and Secrets: API credentials are stored in Google Secret Manager and bound to individual Cloud Functions at deploy time, never in source code or client-side bundles. A pre-deploy check fails the deployment if a function that reads a secret is missing its binding. No downloadable service-account keys exist. Cloud Functions authenticate with Google-managed credentials that rotate automatically, and operational scripts run under the operator's own MFA-protected sign-in. An organization policy blocks anyone from creating or uploading service-account keys, and an alert notifies the operator if anyone attempts it. Secret files are excluded from version control via .gitignore, a pre-commit hook blocks accidental commits of credentials, and an automated secret scan runs against the full repository history on every build. Apple FinanceKit requires no API keys or access tokens — authorization is managed entirely by the iOS operating system at the device level.
Administrative Access: Administrative access to production features is restricted to designated operator accounts, verified via a Cloud Function that checks against an allowlist of authorized email addresses. Admin capabilities are used exclusively for testing and debugging purposes.
In Transit: All client-server communication uses TLS 1.2 or higher. Firebase Cloud Functions enforce HTTPS for all callable endpoints. iOS App Transport Security (ATS) enforces TLS for all outbound network requests. Cloud Storage uploads and downloads occur over TLS. All third-party API communication uses TLS. FinanceKit transaction data is transmitted from the iOS app to Firebase Cloud Functions over TLS. FinanceKit itself operates entirely on-device and does not involve network communication with Apple.
At Rest: All data stored in Cloud Firestore is encrypted at rest using Google-managed encryption keys (AES-256). Cloud Storage objects (receipt images, profile photos) are encrypted at rest using Google-managed keys (AES-256). Access tokens stored in Firestore are additionally protected by security rules preventing any client-side read access.
Users authenticate via Firebase Auth using email/password, Google Sign-In, or Apple Sign-In. Google Sign-In provides Google's built-in MFA capabilities. Apple Sign-In supports Apple's two-factor authentication and private relay email addresses. Password requirements are enforced by Firebase Auth. Multi-factor authentication before bank linking: Before Plaid Link opens, every session must have passed a second factor. Sign in with Apple sessions already did, through Apple's mandatory two-factor authentication. Sessions signed in with email/password or Google must also confirm with Face ID, Touch ID or the device passcode. This check is based on how the current session signed in, not on which sign-in methods are linked to the account. Bank account authentication is handled entirely by Plaid — Jointly never receives, stores, or has access to bank login credentials. Apple FinanceKit authorization is handled by the iOS operating system. Users grant access via a system-level prompt and can revoke it in iOS Settings. Jointly never receives Apple Wallet credentials.
Biometric Authentication: Users may optionally enable Face ID or Touch ID to unlock the app. When enabled, sign-in credentials are stored in the iOS Keychain with biometric access control (kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly with .biometryAny). No biometric data is collected, stored, or transmitted by Jointly — all biometric processing is handled locally by Apple's LocalAuthentication framework.
App Integrity: Firebase App Check with Apple App Attest verifies that requests to backend Cloud Functions originate from the authentic Jointly app, preventing unauthorized API access from spoofed or tampered clients.
All backend infrastructure runs on Google Cloud Platform (Firebase), which maintains SOC 1, SOC 2, SOC 3, and ISO 27001 certifications. Cloud Functions execute in isolated, ephemeral containers managed by Google. No self-managed servers, VMs, or databases are used. Firebase project access is restricted to authorized Google accounts with MFA enabled.
Firebase Analytics: Pseudonymous usage data (screen views, basic interaction events, and aggregate counts) is collected to understand app usage patterns and improve the user experience. Events are associated with a random account identifier. Analytics events do not carry names, email addresses, merchant names, transaction amounts or account numbers.
Firebase Crashlytics: Pseudonymous crash reports (stack traces, device state, OS version) are collected automatically when the app encounters an error. Crash data is used exclusively for identifying and fixing bugs. We do not intentionally include names, email addresses, merchant names or transaction amounts in crash reports, but reports do carry a device installation identifier and may include internal database paths that contain the account identifier.
Push Notifications: Push notifications are processed via a scheduled Cloud Function that batches and delivers pending notifications. Notification content is transient and deleted after delivery. Device tokens are stored in an owner-only area of the user's account data and removed upon account deletion.
All application code is stored in a private GitHub repository with MFA-enabled access. Secrets and credentials are excluded from version control. GitHub Dependabot alerts are enabled to detect known vulnerabilities in dependencies. npm audit runs automatically both in continuous integration and as a pre-deployment check for Cloud Functions — builds and deployments are blocked if high or critical severity vulnerabilities are detected. The gate distinguishes a genuine advisory from an unreachable package registry, so that a registry outage cannot silently pass a vulnerable build nor block an urgent security fix from shipping. An automated secret scan covering the full repository history runs on every build. Firebase and third-party SDKs are kept on supported, maintained versions.
GitHub Dependabot monitors repository dependencies for known CVEs and alerts on vulnerabilities. npm audit runs automatically before every Cloud Functions deployment. Google Cloud / Firebase infrastructure patching is managed by Google. Critical and high-severity vulnerabilities in dependencies are prioritized and addressed on a risk-assessed basis, taking into account exploitability and whether the affected code is reachable in production.
In the event of a suspected security incident (unauthorized access, data breach, compromised credentials):
User data is retained only as long as the user maintains an active account.
Self-Service Account Deletion: Users can initiate account deletion directly from the App. A 7-day grace period allows the user to cancel by signing back in. After 7 days, all user data is permanently deleted by an automated scheduled process, including:
Bank Account Disconnection: Access tokens are revoked via the Plaid API and deleted from Firestore immediately upon disconnection. Disconnection stops future syncing only — already-synced transactions, splits, settlement history and user classifications are retained. Removing stored data is a separate, explicit action ("Remove Accounts"), scoped to the individual accounts the user selects: it stops syncing each one and deletes its transactions and unsettled splits, while preserving settled splits, since those are shared settlement history belonging to both partners. Full erasure is available via account deletion.
FinanceKit Data: FinanceKit transaction data is treated identically to Plaid transaction data for retention and deletion purposes. Disconnecting Apple Wallet stops future syncing only; already-synced transactions, splits and settlement history are retained until the user removes them or deletes their account. No access tokens exist to revoke — revoking FinanceKit authorization simply prevents future data access.
Consent: Bank account connections are established through Plaid Link, which presents its own data-use disclosure and consent step before any account is connected. Apple Wallet access is authorized through the system-level FinanceKit permission prompt. Access can be revoked at any time by disconnecting the account in Settings.
Users may also contact help@getjointly.co for account deletion assistance. This policy complies with CCPA and NY SHIELD Act requirements.
| Third Party | Data Shared | Security Posture |
|---|---|---|
| Plaid | Bank account access (via tokens) | SOC 2 Type II certified |
| Apple FinanceKit | Transaction data (on-device, user-authorized) | Apple's device-level security infrastructure; no server-side access tokens or API keys |
| Anthropic | TestFlight beta feedback only: the tester's written comment plus device model, iOS version and app version. No financial data, and nothing from App Store builds. | SOC 2 Type II certified; data submitted via the API is not used for model training |
| Notion | TestFlight beta feedback only: the tester's comment and any screenshots they attached, stored as issue-tracker tickets. Screenshots may contain merchant names and amounts. | SOC 2 Type II certified |
| Firebase / Google Cloud | All application data, files (Cloud Storage), analytics, crash reports | SOC 1/2/3, ISO 27001, FedRAMP |
| Google Sign-In | Email, name, profile photo | Google authentication infrastructure |
| Apple Sign-In | Email (or private relay), name | Apple authentication infrastructure |
| Apple StoreKit | Subscription purchases, receipt verification | Apple's in-app purchase infrastructure |
| Postmark (ActiveCampaign) | Account-notice email only: the recipient's email address and the notice text. Internal operational alerts to the operator identify a user only by account identifier. | SOC 2 Type II |
Third-party services are evaluated for security certifications and data handling practices before integration. Data shared with third parties is limited to what is necessary for the service to function.
Jointly maintains a public privacy policy at getjointly.co/privacy-policy covering data collection, processing, storage, third-party sharing, and user rights. Consent for bank account access is obtained through Plaid Link's own data-use disclosure before any account is connected, and through the system-level FinanceKit prompt for Apple Wallet.
This policy is reviewed annually or whenever a significant change occurs to Jointly's infrastructure, third-party integrations, or applicable regulations. All updates are documented with the review date.
This document describes the security practices Jointly aims to follow as of the review date shown at the top of this page. It is provided for information only. It does not form part of any contract, does not create any warranty, representation, guarantee, or service-level commitment, and does not create any right enforceable by any person. Security practices, tools and third-party providers change over time, and this policy may be updated without notice. Nothing here limits or expands the rights and obligations set out in the Terms of Service, which together with the Privacy Policy is the operative agreement between you and Jointly. No system can be guaranteed to be completely secure.
Jointly
Operated by Joshua Knopman
Brooklyn, New York
General inquiries: info@getjointly.co
Data & privacy requests: legal@getjointly.co