At-Rest Encryption (AES-256-GCM): Your expense categories, merchant names, and
descriptions
are encrypted before being stored in the database using AES-256-GCM — the same standard used by
banks and
government agencies. The encryption key is stored separately from the database and never exposed in
logs.
What is NOT encrypted at rest: Expense amounts, dates, and currencies remain
unencrypted
in the database so SQL aggregations (totals, comparisons) can run efficiently. These fields are not
considered personally identifying.
In-Transit Encryption (TLS 1.3): All communication between your browser and our
servers
is encrypted via modern TLS. No data travels in plain text across the internet.
Key Management: The AES master key is stored as a Cloudflare secret environment
variable,
encrypted at rest by Cloudflare's infrastructure. It is never committed to source code or logs.
🔑 Authentication & Sessions LIVE
Password Hashing (PBKDF2-SHA256): Your password is never stored. It is hashed using
PBKDF2 with SHA-256, 100,000 iterations, and a unique per-user random salt. Reversing this is
computationally
infeasible. We cannot recover your password if lost.
JWT Tokens (HMAC-SHA256): Authentication sessions use signed JSON Web Tokens.
Tokens contain
your user ID, email, and a 7-day expiry. They are cryptographically signed — any tampering is
immediately
detected.
Secure Cookies: Auth tokens are stored in HttpOnly,
Secure,
SameSite=Lax cookies. They are inaccessible to JavaScript running on the page,
protecting
against XSS attacks.
Idle Session Timeout: Sessions auto-expire after 5 minutes of
inactivity.
A warning is shown at 4 minutes. This protects you if you leave the app open on a shared device.
Email Verification: All new accounts must verify their email address before gaining
access.
This prevents unauthorized account creation.
Input Length Limits: All API endpoints enforce strict input size limits (email ≤
254 chars,
password ≤ 1024 chars, messages ≤ 2000 chars) to prevent denial-of-service attacks via expensive
crypto operations.
🧱 Data Isolation LIVE
User-Scoped Queries: Every database query is filtered by your authenticated user
ID,
extracted from your verified JWT. There is no way to query another user's data even by manipulating
API parameters.
Server-Side Enforcement: Data isolation is enforced at the server — not just the
UI.
Even if you bypassed the frontend entirely and called the API directly, you can only access data
belonging to your own account.
Infrastructure: The app runs on Cloudflare Pages (edge compute) with Cloudflare D1
(SQLite) as the database. Both benefit from Cloudflare's DDoS protection and global security
infrastructure.
We do NOT collect: Browsing history, device fingerprints, location data, or any
telemetry.
AI Processing: When you use the AI chat feature, your message and spending summary
(totals only, for Insights) are sent to Groq's API. No raw expense records are ever sent to Groq.
📋 Terms of Use
Personal Use Only: Ledger is a personal finance tracking tool intended for
individual use. Account sharing is not permitted.
Your Data Responsibility: You are responsible for the accuracy of expenses you
enter. Ledger is a tracking tool, not a financial advisory service.
No Data Sales: We do not sell, rent, or share your personal data with third parties
for marketing, analytics, or any commercial purpose.
Data Retention: Your data is stored as long as your account remains active. You may
delete your account at any time by contacting support.
Service Availability: Ledger is provided as-is. While we strive for high
availability, we make no guarantees regarding uptime.
Liability Limitation: We are not liable for any financial decisions made based on
data in the app. Always consult a qualified financial advisor for investment or tax advice.
Changes to Terms: We may update these terms from time to time. Continued use of the
app constitutes acceptance of updated terms.