Information Security Policy
Karr Consultants, LLC — operator of the SwipeFund application Tustin, California, United States
| Version | 1.0 |
| Effective | 29 July 2026 |
| Policy owner | Brian Karr, Managing Member — security@getswipefund.com |
| Review cadence | Every 6 months, and upon any material change to systems, vendors, or data handling |
| Next review due | 29 January 2027 |
Control summary
| Area | Position |
|---|---|
| Bank credentials | Never received, never stored. Collected by Plaid Link directly. |
| Passwords | None exist. Authentication is Google OAuth exclusively. |
| Money movement | Structurally impossible. We hold no Plaid product capable of it. |
| Plaid products held | Transactions only. No Auth, Transfer, Payment Initiation, Signal, or FCRA product. |
| Card data (PAN/CVV/PIN) | Never received. Out of PCI-DSS scope. |
| Data isolation | Row-Level Security on every table, enforced at the database layer and verified by executable test. |
| Access tokens | Encrypted at rest, excluded from client-readable grants, never logged, never sent to a browser. |
| Encryption | TLS 1.2+ in transit; AES-256 at rest. |
| Production access | One named individual, MFA required on every account. |
| Vulnerability management | Continuous automated dependency scanning, with documented remediation service levels. |
| Retention and deletion | Retained only while it serves the user. Deletion enforced by database cascade, not by application code. |
| Data sold or shared | None, ever. Revenue is consumer subscription. |
0. Scope and operating model
Karr Consultants, LLC is a California limited liability company with two members. SwipeFund is a product operated by the LLC; it is not a separately incorporated entity, and all obligations under this policy are obligations of Karr Consultants, LLC.
Production system access is limited to a single member, the Managing Member, who is also the sole engineer. The second member holds no credentials to any production system, database, or vendor console. This is least privilege applied at the ownership level: participation in the company does not confer access to customer data.
This policy governs every system that stores, processes, or transmits end-user data, and every vendor relationship through which such data passes. SwipeFund is pre-launch; the controls described here are in force today, and §11 states plainly which additional controls are scheduled and when.
1. Our security posture in one paragraph
We reduce what can go wrong rather than relying on detecting it afterward. The most sensitive data in this product category — bank login credentials — never enters our systems, because Plaid Link collects it directly and we receive only a token. The second most sensitive — passwords — does not exist, because we delegate authentication entirely to Google. The most damaging capability — moving a user's money — is not available to an attacker who fully compromises us, because we never purchased it. What remains is transaction history, isolated per-user at the database layer by controls that hold even if our application code is bypassed entirely. A worst-case breach of SwipeFund exposes a list of purchases. It does not expose credentials, does not enable account takeover at any financial institution, and cannot be used to move a dollar.
2. Data inventory
| Class | Contents | Location | Retention |
|---|---|---|---|
| Authentication identity | Email address, Google account identifier | Supabase Auth | Life of account |
| Transaction data | Amount, date, merchant, category, account name, last-four mask, institution | Supabase Postgres | Life of connection; deleted on disconnect |
| Plaid access token | Opaque token authorizing read access | Supabase Postgres, encrypted column | Life of connection; deleted on disconnect |
| User-authored data | Spending profile, cards owned, travel goals, points ledger | Supabase Postgres | Life of account |
Data we do not receive
Exclusions by design, each eliminating a category of risk rather than managing it:
- Bank and card login credentials. Collected by Plaid Link directly. They never traverse our frontend, backend, database, or logs. We could not produce a user's banking password under any circumstance, including legal compulsion.
- Full account numbers. We receive a four-digit mask, sufficient to match an account to a card in our library and insufficient for anything else.
- Payment card numbers, CVV, or PIN. Never received. We are out of scope for PCI-DSS.
- Social Security numbers, dates of birth, government identifiers. We request no Plaid product that returns them.
- Loyalty program credentials. Automated collection of airline and hotel program logins is prohibited by standing engineering policy, recorded in our architecture documentation so that the prohibition survives personnel change. Any future access to loyalty balance data must come through a licensed aggregation partner. We will not store users' program credentials.
3. Read-only by construction
SwipeFund requests exactly one Plaid product: Transactions.
We hold no product capable of initiating a transfer, payment, or any movement of funds — not Auth, not Transfer, not Payment Initiation, not Signal. This is not a setting an attacker could flip: enabling a money-movement product requires a separate request through the Plaid dashboard subject to Plaid's own review. A total compromise of our infrastructure cannot move a user's money, because the capability does not exist in our integration.
We hold no FCRA-regulated product. We make no lending, credit, or eligibility determination about any person, and we furnish data to no one who does.
4. Identity and access management
4.1 End users
- Authentication is Google OAuth exclusively. We implement no password system, store no password hashes, and operate no password reset flow. There is no credential in our custody to steal.
- The OAuth flow uses PKCE; access tokens never appear in a URL.
- Multi-factor authentication is inherited from the user's Google account.
- Plaid Link is never rendered to an unauthenticated session. Sign-in precedes any connection flow; there is no path around it.
- Sessions are managed by Supabase Auth with automatic token refresh and server-side revocation on sign-out.
4.2 Production access
- Production access is held by one named individual, the Managing Member.
- Multi-factor authentication is required on every account conferring production access: GitHub (source), Supabase (database, authentication, server-side functions), Plaid (dashboard), and the domain registrar.
- No shared logins. No human use of service accounts. No contractor, vendor, or third-party access to production data.
- The LLC's second member holds no production credentials.
- Access is reviewed at each policy review and immediately upon any change in personnel or ownership. Any future grant of production access will be recorded here with its date and justification.
4.3 Authorization at the database layer
Authorization is enforced by the database itself, not solely by application code — so that an application-layer flaw does not become a data breach.
- Row-Level Security is enabled on every table holding user data, without exception.
- Every policy scopes access to the requesting user's own rows. A user cannot read or modify another user's data even holding a valid session and issuing queries directly against the API, bypassing our application entirely.
- The
anonrole is granted nothing. Every table contains per-user data; there is no public read surface. This decision is documented in the schema itself, so that a future engineer following Postgres's default error guidance cannot widen it inadvertently. - Grants are column-scoped where a column must never reach a client. The encrypted Plaid access token is excluded from the authenticated role's read grant entirely — the browser has no reason to hold it in any form.
- Tables written only by server-side processes carry no insert or update grant for end users. Users may correct only specific, non-sensitive columns.
- Isolation is verified by executable test, not by inspection. A test suite provisions two users, writes data as each, and asserts neither can reach the other's rows. It runs against a disposable database on every schema change. This process identified and corrected six authorization defects during initial schema review, before any user data existed.
5. Encryption
- In transit: TLS 1.2 or higher on every connection — browser to application, application to database, application to Plaid. No plaintext transport exists anywhere in the system.
- At rest: AES-256 for database and backups, provided by Supabase on AWS infrastructure.
- Plaid access tokens carry application-layer encryption in addition to at-rest database encryption. They are decrypted only inside server-side functions at the moment of use, are never returned to a client, never written to a log, and never included in an error report.
6. Secrets management
- No secret is ever committed to source control. Local environment files are excluded from version control, and exclusion is verified before such a file is created rather than assumed after.
- Secrets reside only in managed environment stores — Vercel and Supabase — never in the repository, documentation, tickets, or messages.
- Server-only secrets are structurally prevented from reaching the browser. Our build tool exposes only variables carrying a specific prefix. The Plaid client identifier and secret deliberately omit it, so an error in frontend code cannot leak them. This is enforced by architecture, not by discipline.
- The database service key, which bypasses Row-Level Security, appears in no client code and no repository, and is held in a password manager.
- The application validates its own credentials at startup and refuses to construct a database client with a malformed key.
- Rotation occurs immediately upon any suspected exposure, upon any change in personnel or ownership, and at least annually.
7. Secure development
- All code resides in a private repository under version control.
- Changes are developed on feature branches and reviewed before merge.
- An automated suite of 82 tests, static type checking, and a production build must pass before any change ships. Financial calculation logic carries dedicated regression tests, including tests written specifically to pin defects previously identified in production behavior.
- Database changes ship as versioned migration files under version control. Undocumented manual schema edits are not permitted.
- Dependencies come from the public npm registry with a committed lockfile, so builds are reproducible and no dependency can change beneath a deployment.
7.1 Vulnerability management
Automated dependency scanning runs continuously against the full dependency tree via GitHub Dependabot, covering both direct and transitive dependencies. Alerts are raised against the repository as vulnerabilities are disclosed, without waiting for a scheduled scan.
Patches are proposed automatically. Dependabot security updates open a pull request carrying the fix, so remediation begins as a reviewable change rather than a task someone has to notice.
Remediation service levels, measured from the time an alert is raised:
Severity Remediated within Critical 7 days High 30 days Moderate 90 days Low Next routine dependency update A vulnerability reachable from production code takes precedence over one confined to build or test tooling, which cannot be reached by a user request. Where a fix is unavailable within its window, the exposure is assessed and the decision recorded rather than left to lapse silently.
Alerts are configured to notify the Managing Member directly.
Scanning of endpoint devices is not yet in place; see §12.
8. Logging and monitoring
- Application, database, and authentication logs are retained by Supabase and our hosting provider under their standard retention schedules.
- Secrets, access tokens, and account identifiers are never written to logs. A failure involving a token logs the failure, not the token.
- Authentication events — sign-in, sign-out, token refresh — are recorded by Supabase Auth.
- At current scale, monitoring is scheduled review by the Managing Member rather than a staffed alerting rotation. Automated alerting is scheduled; see §11.
9. Vendors and subprocessors
| Vendor | Purpose | Data received |
|---|---|---|
| Plaid Inc. | Account connection, transaction data | Bank credentials (directly from user, never via us); transaction data |
| Supabase Inc. (AWS, US) | Database, authentication, server-side functions | All stored user data |
| Vercel Inc. | Application hosting | Request metadata; no user data at rest |
| Google LLC | OAuth identity provider | Authentication assertion only |
No vendor receives user financial data without first being recorded here. We do not sell, rent, or share user data with any third party, and we do not use it for advertising, resale, model training, or any purpose beyond delivering the product to the user whose data it is. Revenue comes from a consumer subscription — our business model does not depend on the data.
10. Data retention and deletion
10.1 Governing principle
We retain data only while it serves the user it belongs to. There is no business reason for us to hold data past that point: we do not sell it, do not use it for advertising or model training, and do not monetize it in any way that would reward accumulation. Our revenue is a consumer subscription, so retention beyond usefulness is pure liability. This policy is written to reflect that alignment rather than to work around a conflicting incentive.
10.2 Retention schedule
| Data | Retained while | Deleted |
|---|---|---|
| Plaid access token | The institution connection is active | Immediately on disconnect, account deletion, or item revocation |
| Transaction records | The originating connection is active | Immediately on disconnect or account deletion |
| Connected account metadata (name, mask, institution) | The connection is active | Immediately on disconnect or account deletion |
| Spending profile, owned cards, travel goals, points ledger | The account is active | On account deletion |
| Authentication identity (email, Google account ID) | The account is active | On account deletion |
| Application and authentication logs | Vendor standard retention | Aged out automatically by the vendor |
| Database backups | Vendor standard retention window | Aged out automatically by the vendor |
We set no retention period longer than the life of the relationship. No category of user data is archived, warehoused, or retained "for analytics" after the user's connection or account ends.
10.3 Deletion triggers
Deletion is initiated by any of the following, without requiring a support request or a written demand:
- User disconnects an institution. Removes the access token, the connected account records, and the transaction history originating from that institution.
- User deletes their account. Removes every record belonging to that user across every table.
- The connection is revoked upstream — by the user at their bank, or by Plaid. The item is treated as terminated and its data is removed on the same basis as a user-initiated disconnect.
- Statutory deletion request. Honored within the timeframe the applicable law requires; see §10.6.
10.4 Deletion is enforced by the database, not by application code
Completeness of deletion does not depend on an engineer remembering every table that needs cleaning.
- Every table holding user data declares its user reference with
ON DELETE CASCADEagainst the authentication record. Removing a user removes their profile, spending data, owned cards, activations, points ledger, travel goals, Plaid items, connected accounts, and transactions in a single operation, atomically. - Connection-scoped data cascades a second level. Connected accounts and
transactions reference the Plaid item they came from, also with
ON DELETE CASCADE, so disconnecting one institution removes exactly that institution's data and leaves other connections intact. - The result is that orphaned records are not possible by construction. A partial deletion would require violating a foreign key constraint, which the database refuses.
Access tokens are additionally revoked with Plaid at disconnection, so the authorization is withdrawn at the source rather than merely deleted on our side.
10.5 Backups
Deletion from the live database is immediate. Copies may persist in encrypted vendor backups until those backups age out on their normal schedule, after which they are unrecoverable. We state this plainly rather than implying instantaneous erasure everywhere: backup data is encrypted at rest, is not queryable by us in the ordinary course, and is never used to repopulate deleted records.
10.6 User rights
Users may, at any time and at no cost:
- Disconnect any individual institution while keeping their account
- Delete their account and all associated data
- Request confirmation of what is held about them
Where California's CCPA/CPRA or a comparable state privacy law applies, we honor deletion and access requests within the statutory period — 45 days, extendable once where the law permits — and we do not discriminate against users who exercise these rights, which for us is trivially true, since exercising them simply ends the service.
10.7 Review
This policy is reviewed on the cadence stated at the head of this document — every six months, and upon any material change to systems, vendors, or data handling. Any change to a retention period is recorded with its date and the reason for the change.
11. Incident response
The Managing Member is the incident owner and the point of contact for any reported security issue, reachable at the address on this document.
Upon discovering or being notified of a suspected incident:
- Contain. Revoke the affected credential or access token and disable the affected pathway. Because our integration is read-only, no containment step requires halting money movement.
- Assess. Determine what data was reachable, for how long, and for how many users, using database and authentication logs.
- Notify. Inform Plaid's security team without undue delay where the incident involves data obtained through Plaid, consistent with our obligations under the Plaid developer agreement. Notify affected users and applicable regulators as required by California Civil Code §1798.82 and any other applicable breach notification statute.
- Remediate and record. Correct the root cause, add a regression test wherever the failure was one a test could have caught, and document the incident with its timeline and corrective actions.
Suspected vulnerabilities may be reported to the contact above. We will acknowledge good-faith reports and will not pursue legal action against a researcher who acts in good faith and does not access, alter, or retain other people's data.
12. Security roadmap
Controls scheduled but not yet in force, stated explicitly so that our current posture is not overstated. Each is tied to a stage rather than left open-ended.
| Control | Status | Scheduled |
|---|---|---|
| Endpoint (laptop) vulnerability scanning | Not in place | Before public launch |
| Third-party penetration test | Not performed | Before public launch |
| Documented disaster recovery test | Not performed | Before public launch |
| Automated alerting and on-call rotation | Not in place | At meaningful user volume |
| Separation of duties across staff | Not applicable — single operator | Upon first engineering hire |
| SOC 2 Type II | Not held | Upon enterprise or partner requirement |
We report these openly because a reviewer will identify them regardless, and because a policy asserting completeness it does not possess is worth less than one that states its position accurately. Every item above is tracked and revisited at each policy review.
13. Acceptance
This policy is approved and maintained by the undersigned, who is responsible for its implementation and for review on the cadence stated above.
Brian Karr Managing Member, Karr Consultants, LLC 29 July 2026