Information Security Policy
System: Koda Finance (Android app + Firebase backend) · Owner: Ivy, Founder, Koda Digital · Contact: contact-us@kodadigital.ai · Effective: 2026-09-03 · Review: every 6 months
1. Purpose and scope
This policy governs how consumer financial data obtained through Plaid is protected in Koda
Finance. It covers the mobile app, the backend (Firebase Cloud Functions + Firestore in
Google Cloud project koda-finance-e1c74, region us-central1), the Plaid integration, and
the operator's workstation and accounts.
2. Context
Koda Finance is a personal net-worth tracker used by exactly one person, who is also its sole developer and administrator. There are no employees, contractors, or third-party integrators. Because there is one operator and one end user, several controls that a multi-person organisation implements procedurally are implemented structurally here (for example, there is no one to de-provision). Each policy notes what would change before the app is offered to additional users.
3. Architecture (the basis for every control)
Android app ──TLS──▶ Cloud Functions (api) ──TLS──▶ Plaid API
│ biometric lock │ x-koda-api-key check ▲
│ no local data store ├──▶ Firestore (tokens, cache, manual assets, history)
│ └──▶ Secret Manager (Plaid keys, API key)
└── Plaid Link SDK (bank credentials never touch Koda code)
- Bank credentials are entered only inside Plaid Link; Koda never sees them.
- Plaid access tokens exist only in Firestore, readable only by the backend service account.
- The app stores nothing financial on the device; every screen loads from the backend.
- All transport is HTTPS/TLS 1.2+ (Google-managed certificates on cloudfunctions.net; Plaid's on plaid.com).
4. Zero-trust access architecture
No network location is trusted. There is no VPN, office network, or IP allow-list that grants access; every request to every component is authenticated and authorised individually:
- App → backend: each HTTP request carries an API key checked by middleware (
functions/src/apiKeyAuth.ts); unauthenticated requests receive 401 and no data. - Backend → Firestore / Secret Manager: Google-issued short-lived service-account credentials, scoped by IAM; Firestore security rules deny all direct client access (
firestore.rules). - Backend → Plaid: client ID + secret from Secret Manager, per request, over TLS.
- Operator → Google Cloud / Firebase / Plaid dashboards: Google account with 2-Step Verification (phishing-resistant method), Plaid dashboard with MFA. No standing sessions on shared machines.
- Device: the app requires device biometric authentication on every launch and re-locks when backgrounded (
app/src/components/lock-screen.tsx).
5. Risk identification, mitigation and monitoring
| Risk | Mitigation | Monitoring |
|---|---|---|
| Backend URL discovered and scanned | API key required; 401 on failure | Cloud Functions logs; Cloud Monitoring error rate |
| API key extracted from the APK | Key grants read access to one user's aggregated balances only, never to Plaid tokens or bank credentials; key can be rotated in minutes (Secret Manager + app rebuild) | Unusual call volume in Cloud Monitoring; Plaid dashboard usage |
| Plaid credential leak | Secrets only in Google Secret Manager; never in git (.gitignore), never in the app |
Secret Manager access audit logs |
| Lost/stolen phone | Biometric lock; no offline data; app can be wiped remotely via Google Find My Device | — |
| Operator account compromise | 2SV with passkey/security key on Google; MFA on Plaid; unique passwords in a password manager | Google security alerts |
| Data over-retention | Cache TTLs and automatic purge; unlink endpoint revokes Plaid Items (see data-retention policy) | Scheduled job logs |
6. Change management
Code lives in a private GitHub repository. Changes are deployed only by the operator via
firebase deploy after a TypeScript build passes. Dependencies are updated on a monthly
cadence or immediately on a published critical vulnerability.
7. Incident response
If compromise of the backend, secrets, or a device is suspected: (1) rotate the API key and
Plaid secret in Secret Manager and redeploy; (2) remove affected Plaid Items via
/item/remove (the app's unlink function) and re-link; (3) review Cloud audit logs for the
window; (4) notify Plaid via the dashboard support channel if Plaid data may have been
exposed. As the only affected consumer is the operator, no external consumer notification
is required; this section will be expanded before any multi-user release.
8. Related policies
See access-control-policy.md, authentication-and-secrets.md, data-retention-and-deletion.md, privacy-policy.md.