Amberize saves your business emails to your computer — searchable, tamper-proof, and ready when the Finanzamt asks. No cloud. No subscription. No IT department needed.
Website: amberize.fly.dev
Available for macOS, Windows, and Linux. Built for freelancers, small businesses, and tax advisors in Germany. Open source and free forever.
Go to latest release to download for MacOS, Windows or Linux
.eml files or a complete auditor package (ZIP)Download the latest release from the Releases page:
.dmg installer — open it and drag Amberize to your Applications folder.msi installer — run it and follow the setup wizard.deb package or .AppImage — install via your package manager or run directlyClick Add Account → Google / Gmail, enter your Gmail address, and sign in via the browser. Amberize handles the OAuth flow automatically.
On first use, you'll need to enter a Google OAuth Client ID and Secret. You can create one for free at the Google Cloud Console (type: Desktop app, enable the Gmail API). These credentials are stored in your system's credential store, not in the archive.
Passwords and OAuth tokens never touch the archive database — they live exclusively in your OS credential store (macOS Keychain, Windows Credential Manager, or Linux Secret Service).
Amberize supports GoBD-compliant email archiving — it is not GoBD-compliant on its own. No software is: the BMF guidelines (GoBD — Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern, Aufzeichnungen und Unterlagen in elektronischer Form) require both technical measures and organizational policies. Even commercially certified archiving software carries the disclaimer "bei sachgerechter Anwendung" (when used properly).
Important context: GoBD is a Verwaltungsvorschrift (administrative regulation), not a law. Not following it doesn't mean you broke a law — but it may cause a tax auditor to question your bookkeeping, which can lead to estimated additions to your tax base (Hinzuschätzungen).
| GoBD requirement | How Amberize addresses it |
|---|---|
| Immutability (Unveränderbarkeit) | Raw MIME bytes stored once, never modified. SHA-256 hashes verify integrity. Any tampering is detected. |
| Completeness (Vollständigkeit) | All messages in selected IMAP folders are archived automatically every few minutes. |
| Traceability (Nachvollziehbarkeit) | Hash-chained audit trail records every sync, export, and configuration change. |
| Machine readability (Maschinelle Auswertbarkeit) | Full-text search (FTS5). Export to .eml or auditor ZIP. |
| Verfahrensdokumentation | Auto-generated procedural documentation (German template). |
| GoBD requirement | What you need to do |
|---|---|
| Completeness guarantee | Amberize archives via IMAP after delivery, not at the mail server (no SMTP journaling). This is how all desktop archiving tools work. Emails deleted before the next sync are lost. Set a short sync interval and do not delete tax-relevant emails from your inbox. |
| Retention periods (Aufbewahrungsfristen) | GoBD requires 6-year retention for commercial correspondence and 10 years for accounting documents. Amberize does not track or enforce these periods. Keep backups of your archive file for the required duration. |
| Deletion prevention | The archive is a regular SQLite file that can be deleted or corrupted. Use backups (ideally on a separate drive) and consider write-protecting the file. |
| Tax authority access (Datenzugriff) | GoBD requires three forms of auditor access (Z1/Z2/Z3). Amberize provides an auditor ZIP export (partial Z3). It does not provide interactive auditor login (Z1) or IDEA/GDPdU export. |
For sole proprietors (Einzelunternehmer), freelancers (Freiberufler), and small businesses using Amberize:
BODY.PEEK[] — never alters server flags or messageslibgtk-3-dev, libwebkit2gtk-4.1-dev, libayatana-appindicator3-dev, librsvg2-dev, patchelfcd apps/desktop
npm ci
cd apps/desktop
npx tauri dev
This starts the Vite dev server and the Tauri backend with hot-reload.
Credential store prompts in dev mode: each rebuild produces a new binary signature, so your OS may prompt for credential access on each restart. This does not happen with signed production builds.
cd apps/desktop
npm run build # Build the frontend
cd src-tauri
cargo run # Run the backend
# Rust
cargo fmt --all -- --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace
# Frontend (19 tests, coverage gates enforced)
cd apps/desktop
npm test -- --coverage
Amberize supports two ways to provide Google OAuth credentials:
Build-time embedding (for distribution): set GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET in .cargo/config.toml. They're compiled into the binary via option_env! and saved to the credential store on first use. Users get a seamless "Sign in with Google" without needing their own Google Cloud project.
User-provided (fallback): if no credentials are embedded, users enter their own Client ID and Secret in the app UI. Stored in the credential store.
To set up for development:
.cargo/config.toml.example to .cargo/config.toml and fill in your values..cargo/config.toml is gitignored — credentials are never committed.
Why is the client secret not really secret? Google documents that native/desktop apps "cannot keep secrets" — the client secret for a Desktop-type OAuth client is not expected to remain confidential. Security relies on PKCE + user consent, not the client secret. This is the same approach used by Thunderbird, which ships its Google OAuth credentials in public source code.
apps/desktop/ Tauri v2 desktop application
├── src/ Svelte 5 frontend (runes, no SvelteKit)
│ ├── components/ UI components
│ ├── lib/ Shared utilities (Tauri bridge, config)
│ └── App.svelte Root component
└── src-tauri/ Rust backend
└── src/
├── main.rs Entry point + plugin setup
├── app_commands.rs IPC command handlers
├── app_state.rs Application state
├── auditor_export.rs Compliance ZIP export
├── background_sync.rs Periodic sync scheduler
├── documentation.rs Verfahrensdokumentation generator
└── menubar.rs Menu bar + system tray
crates/
├── storage/ SQLite schema, queries, integrity, FTS5
└── adapters/ IMAP client, credential secrets, sync engine
Rule: The UI contains no business logic. It calls Tauri commands and renders results.
The archive is a single SQLite file. Key tables:
| Table | Purpose |
|---|---|
accounts |
IMAP account config (passwords in credential store, not here) |
mailboxes |
Per-account folder state (uidvalidity, cursor, sync status) |
message_blobs |
Deduplicated raw MIME + metadata (SHA-256 keyed) |
message_locations |
Where each message was seen (account × mailbox × UID) |
messages_fts |
FTS5 virtual table for full-text search |
events |
Hash-chained audit trail |
uidvalidity + last_seen_uid)UID SEARCH + batched UID FETCH with BODY.PEEK[] (read-only)UIDVALIDITY change triggers full re-scanapp_commands.rsmain.rs → tauri::generate_handler![...]src-tauri/capabilities/default.json if neededtauri_invoke('command_name', { args })cd apps/desktop
# macOS — Debug .app bundle
CI=false npx tauri build --debug --bundles app
# macOS — Release DMG installer
CI=false npx tauri build --bundles dmg
# Windows — MSI installer
npx tauri build --bundles msi
# Linux — .deb and .AppImage
npx tauri build --bundles deb,appimage
The
CI=falseprefix may be needed when building from Cursor's integrated terminal on macOS.
For the full end-to-end release checklist (key setup, draft release flow, DMG install smoke test, and updater verification), see:
docs/release-checklist.mdFor distribution, set these environment variables before building:
export APPLE_SIGNING_IDENTITY="Developer ID Application: Your Name (TEAMID)"
export APPLE_ID="[email protected]"
export APPLE_PASSWORD="app-specific-password"
export APPLE_TEAM_ID="TEAMID"
See Tauri's macOS distribution guide.
Windows builds can be signed with an EV or standard code signing certificate. See Tauri's Windows distribution guide.
| Context | Convention | Example |
|---|---|---|
| JS variables & functions | snake_case |
load_messages |
| Svelte components | PascalCase |
MainDashboard.svelte |
| CSS classes | kebab-case |
.message-list-item |
| Rust functions | snake_case |
get_message_detail |
| Rust types | PascalCase |
UiMessageDetail |
GitHub Actions (.github/workflows/ci.yml) runs on every push:
All GitHub Actions are pinned to commit SHAs for supply chain security.
MIT