Security
This page is the formal answer to "how do you keep our books safe?" It's written for IT-buyers, security teams, and auditors evaluating Solid Accounting against a checklist. We tried to be honest about what we do well, what we explicitly don't try to do, and where the trade-offs lie.
If you need a signed disclosure for a vendor-risk-review, email support@solidaccounting.com and we'll send you the most current version with our signature.
Architecture summary
Solid Accounting is a desktop-first product. The application runs on your computer; your books live in a single encrypted file on your computer; nothing about your accounting data is required to leave your machine.
| Component | Where it runs | What it holds |
|---|---|---|
| Solid Accounting (the app) | Your computer | Application code only — no user data |
Your .solid file | Your computer | Every transaction, list, attachment, audit-log entry |
| License Server | Solid's infrastructure | License keys, activation records, billing |
| Cloud Backup (managed) | Backblaze B2 (your data) | Encrypted blocks of your file (you hold the key) |
| Bank Feeds (Plaid) | Plaid's infrastructure | Bank-data brokering only — credentials never touch us or you |
The core security property: your accounting data is not on our servers. Cloud Backup is the optional exception, and even there the data is encrypted with a key you control before it leaves your machine.
Encryption
File at rest
Every .solid file is a SQLCipher-encrypted SQLite database. SQLCipher is the same library Apple uses for iMessage's local database and that 1Password uses for vault storage.
| Algorithm | Use |
|---|---|
| AES-256 in CBC mode | Page-level data encryption |
| HMAC-SHA512 | Per-page integrity verification |
| PBKDF2-HMAC-SHA512, 256,000 rounds | Key derivation from your password |
The file's bytes on disk are indistinguishable from random data without your password. Backups, file transfers, cloud-sync intermediaries — all see only ciphertext.
Cloud Backup encryption
When Cloud Backup is enabled, the data flow is:
.solid file → chunked (FastCDC) → compressed (zstd L3) → encrypted (AES-256-GCM) → uploaded
Two keys are at play:
- BEK (Block Encryption Key) — 256-bit random key, generated once on your machine, never leaves the wrapped form on disk
- KEK (Key Encryption Key) — 256-bit derived from your login password using Argon2id with 256 MB / 3 iterations / 1 parallelism (resistant to GPU attacks)
The KEK wraps the BEK in the manifest. Each backup block is encrypted with AES-256-GCM using the BEK and a fresh 96-bit random nonce. The GCM authentication tag (16 bytes) on every block makes ciphertext-tampering detectable.
The BEK is also encoded as a 24-word BIP39 mnemonic that you save offline as your recovery path.
The key is never in our possession. Even an attacker with full access to our license-server infrastructure cannot decrypt your Cloud Backup. The B2 bucket Solid manages on your behalf holds opaque blocks; nobody at Solid (or Backblaze) can read them.
In transit
All network traffic from Solid Accounting uses TLS 1.3 where the server supports it (1.2 minimum). Endpoints involved:
- License server —
license.solidaccounting.comover HTTPS, certificate-pinned - Update server —
updates.solidaccounting.comover HTTPS, signed updates - Cloud Backup destination — Backblaze B2 over HTTPS for managed; whatever your destination uses for BYO
Solid never accepts self-signed certificates from its endpoints — a MITM attempt fails to establish a connection rather than continuing on a compromised channel.
Threat model
What we defend against
| Threat | Defense |
|---|---|
| Disk theft / lost laptop | File encrypted at rest; no plaintext recovery without password |
| Cloud-storage compromise (B2 / S3) | End-to-end encryption; the key isn't on the server |
| Network eavesdropping in transit | TLS 1.2/1.3 with cert pinning |
| Tampering with encrypted backup blocks | Per-block AES-GCM authentication tags; weekly automatic verification |
| Bit-rot in storage | Per-block content-hash checks during integrity verification |
| Supply-chain compromise of a dependency | See Supply chain below |
| Sequential-write corruption | SQLCipher's WAL + per-page HMAC |
| Replayed / forged license activations | License keys signed; activation tokens machine-bound |
What we don't defend against
- A compromised running session — a keylogger that captures your password during a normal workday can decrypt your file the same way you do. Endpoint hygiene (antivirus, OS updates, locked screens) is your responsibility.
- Loss of both password and recovery phrase — encryption is real; there's no backdoor. If you lose both, the data is unrecoverable. We're explicit about this trade-off — recoverable encryption isn't really encryption.
- Insider attacks at Solid — we don't have access to your data (it's not on our servers), but an insider could in theory ship malicious code in an update. Mitigations: update signing (see below), audit log on the license server, code reviews on every release.
- Insider attacks at Plaid — Bank Feeds rely on Plaid's security. Plaid is SOC 2 certified and used by Fortune-500 banks; we trust them inside their published threat model. Read-only API scopes mean Plaid couldn't change anything in your bank account, only read it.
- State-level adversaries with physical access to your decrypted laptop — out of scope.
Network isolation
The app runs on your machine; the embedded API server (Pro/Accountant tiers) binds to 127.0.0.1 by default — only processes on the same machine can reach it. Three configurations for wider access:
| Configuration | Network exposure |
|---|---|
| Default (localhost) | Same machine only |
| Bind to 0.0.0.0 | Any device on the same network — safe only on trusted LANs |
| Reverse proxy with TLS | Public internet via your hostname; auth via API key |
| VPN (Tailscale, WireGuard) | Specific peers only; no public internet exposure |
We recommend the reverse-proxy or VPN options for any non-localhost access. Direct binding to 0.0.0.0 is supported but flagged in setup as a deliberate-trade-off action.
Authentication
File-level
Every .solid file is encrypted with a password you set. Without the password, the file is opaque bytes — Solid Accounting (the app) refuses to open it; raw SQLite can't read it; SQLCipher tools can't extract anything without the right password.
Multi-user
In multi-user mode (Pro/Accountant tier), each user has:
- A unique user record on the file (created with a one-time invite code)
- A personal password used for subsequent logins
- A role that the authority enforces on every read/write
The host or dedicated server is the authority. Clients can't bypass role enforcement by editing files locally — there's no local file to edit; everything goes through the authority.
API
The embedded API uses an X-API-Key header. Keys are:
- 64 characters of cryptographically-random base64
- Hashed (Argon2id) before storage; we can't show you a key after creation
- Optionally time-limited
- Per-user (each key is tied to a user record); each key's writes are logged with that user's identity in the audit trail
- Revocable from Settings → API & Integrations
Update signing
Every Solid Accounting update is signed with our Ed25519 code-signing key. The public key is embedded in every Solid binary (in tauri.conf.json); the private key never leaves our build server.
The auto-updater verifies the signature before applying any update. If verification fails — the update was tampered with, the signature key was rotated, the update file was corrupted in transit — the updater refuses to apply and surfaces the failure.
This protects against:
- A compromised update CDN serving malicious binaries
- A MITM during update download
- A stolen developer machine (without our code-signing key, an attacker can't ship signed updates)
We can rotate the code-signing key in an emergency; rotation requires a manual step from users (downloading a fresh binary signed with both old and new keys) so we don't surprise them.
Audit
File-level audit log
Every meaningful change to the .solid file is recorded in an append-only audit log. The log is in the same SQLCipher-encrypted database; even Admins can't edit or delete entries.
Recorded events include:
- All data changes (creates, updates, deletes, posts, voids)
- Privileged operations (TIN view, password change, period close, role change)
- Authentication events (logins, logouts, failed attempts, API key creates/revokes)
- Cloud Backup operations (a separate
backup_audit.dbfile holds these)
Solid's own infrastructure audit
The license server, ops portal, and update CDN all log every administrative action. Internal access is restricted to a small operations team; access logs are retained 1 year.
We're working toward SOC 2 Type II certification — see Compliance → SOC 2 for status.
Supply chain
Solid Accounting is built from a known set of dependencies. The full SBOM (software bill of materials) is published with each release.
Specifically:
- Tauri for the cross-platform shell (Rust + system webview)
- SQLCipher for the encrypted database engine
- Argon2id, AES-GCM, BIP39 crypto primitives via well-known crates (
argon2,aes-gcm,bip39) - Plaid SDK for Bank Feeds
- Stripe SDK for license sales
Mitigation against supply-chain attacks:
- Pinned versions in
Cargo.lockandpackage-lock.json— exact versions required - Build reproducibility — the same source produces the same binary (with timestamping caveats)
- Code signing — the binary you download is signed by us; if it weren't built from the source we publish, it wouldn't pass verification
- Dependency audits —
cargo auditandnpm auditrun on every CI build; failing audits block release
We deliberately keep the dependency tree lean. Each new dependency is reviewed for license, maintenance status, and security history before adoption.
Data residency
| Data | Stored where |
|---|---|
Your .solid file | Your computer |
| Cloud Backup blocks (managed) | Backblaze B2 region you choose at setup; default US East |
| Cloud Backup blocks (BYO) | Wherever your S3 bucket lives |
| Bank Feeds metadata | Plaid's infrastructure (US for US accounts; EU options available) |
| License records | Solid's infrastructure (US); see GDPR for EU customers |
For EU customers with data-residency requirements: Cloud Backup with BYO destination in an EU bucket keeps your accounting data in the EU. The license-server records (your name, email, billing address, license key) are in the US — see GDPR compliance.
Incident response
If you discover a security issue:
- Email:
security@solidaccounting.com - PGP key: published at
solidaccounting.com/.well-known/security.txt(RFC 9116) - Response time: within 24 hours for verified reports
We commit to:
- Acknowledge receipt within 24 hours
- Communicate findings within 7 days
- Patch critical issues within 14 days for current and supported-back versions
- Credit the reporter (if they want) in the release notes
Currently we don't run a public bug-bounty program but we'll discuss case-by-case rewards for verified critical finds.
Reading the code
Solid Accounting's source code is not open. The accounting engine (Rust, in src-tauri/src/accounting.rs and the GL module) is proprietary; we believe the value of the product is the accuracy and ergonomics of that code, not the bare-fact existence of an accounting library.
That said:
- Cryptographic primitives are all well-known open libraries (
argon2,aes-gcm,bip39,sqlcipher) — we don't roll our own crypto - The OpenAPI spec is published at every Solid Pro/Accountant install (
/openapi.jsonwhen API is enabled) - Documentation (this site) describes every meaningful behavior
If you need to verify a specific claim about the code (e.g. for a security audit), email security@solidaccounting.com and we can arrange a controlled code review.
Cross-references
- Cloud Backup module — the most security-relevant feature in detail
- Audit Log module — the in-file audit log
- Multi-User module — multi-user threat model
- Compliance — SOC 2, GDPR, etc. status pages
- REST API → Network access — exposing the API safely