---
title: private-ops — Infrastructure Decisions
type: project
tags: [private-ops, infrastructure, security, hosting]
date: 2026-05-14
status: aktiv
related: [[CONTEXT]], [[features-map]]
description: VPS/DB/Storage/LLM-Provider/Auth/Backup-Decisions für private-ops. Alle aus 01-ARCHITECTURE.md, 02-SECURITY.md, ADR-0001/0002 abgeleitet.
---

# Infrastructure Decisions

## VPS

**Phase 0+1:** keine neue VPS.
- Vercel hostet Next.js (Frontend + Server Actions + Route Handlers)
- Supabase EU Frankfurt hostet DB + Auth + Storage + pgvector
- Hetzner srv1649305 läuft Aria (unverändert)

**Phase 2/3:** kleine Hetzner CX22 (~€4/mo) für OCR-Worker, Backup-Jobs, Scheduled-Tasks.
- Kann auf existierendem Hetzner-Account laufen ODER neuer Server
- Entscheidung erst Phase 2

## Datenbank

**Postgres via Supabase EU Frankfurt:**
- Pro-Plan ~€25/mo (Phase 1)
- Built-in: Auth, Storage, Realtime, pgvector, Edge-Functions
- AVV bei Anlage erforderlich
- Region MUSS Frankfurt sein
- Self-Hosting-Schwelle (Q-01): ab €500/mo Cloud-Rechnung Migration auf Hetzner-Postgres erwägen

**RLS-First:** jede Tabelle hat `ENABLE ROW LEVEL SECURITY` + min. 1 Policy in derselben Migration. CI-Check rejected sonst.

## Object Storage (Dokumente)

**Cloudflare R2 EU** (Region-Hint `WEUR` primary, `EEUR` mirror)
- Client-Side-AES-256-GCM VOR Upload — R2 sieht nur Ciphertext
- 2 Buckets: `private-ops-docs-primary` + `private-ops-docs-mirror`
- Lifecycle-Policy: nightly mirror primary→mirror
- Kosten: ~€0.015/GB-month, kein Egress
- AVV bei Anlage

**KEK/DEK-Hierarchie:**
- Tenant Master Key (TMK) im Supabase Vault (Phase 1)
- Document-Encryption-Key (DEK) per Document, gewrapped mit TMK
- KEK wraps TMKs, KEK in 3 Stellen: Vault + verschlüsselte age-Datei auf Kais-Laptop + Paper-Backup im Bankschließfach
- Annual KEK-Rotation oder on-compromise

## Field-Encryption (Tier 4/5 Spalten)

**`pgsodium`** (Phase 1) für: passport_number_enc, iban_enc, steuer_id_enc, medical_diagnosis_enc.
**Migration auf envelope-encryption mit Vault** wenn Audit-Anforderungen steigen (Phase 2+).

Tier 5 (OAuth-Tokens, MFA-Secrets, Recovery-Keys): Supabase Vault, niemals plaintext irgendwo.

## Backups (3 Pfade)

1. **Supabase native:** daily snapshots, PITR mit WAL ~2min Granularität
2. **Hourly pg_dump → Hetzner Storage Box Helsinki:** age-encrypted, SFTP, 30h+30d+12m+7y rolling
3. **R2 Mirror:** primary→mirror nightly, 10y retention (AO §147)

**Verification:** stündlicher Job picks random backup, decrypt, `pg_restore --list`, row-count-check, Telegram-Notify (Aria-Channel).

## LLM-Provider + Routing

**Privacy-Tier-Routing (mandatory per `03-PRIVACY-TIERS.md` §2):**
- Tier 0-1: alle Provider erlaubt
- Tier 2: Anthropic + OpenAI + Mistral (EU-Residency confirmed, no training-retention)
- Tier 3: Anthropic only (Claude family), prefer ZDR-Endpoint
- Tier 4: **NO LLM at all** bis Tier-4-Processing-ADR existiert
- Tier 5: niemals LLM, nur Metadata (key-id, rotation-timestamp, scope-name)

**Models:**
- OCR + Klassifikation: Mistral OCR oder Gemini Flash
- Document-Extraction: Claude Haiku 4.5
- High-Stakes Drafts: Claude Opus 4.7 mit Multi-LLM Hallucination-Voting
- Vision (Belegbilder): Gemini 2.5-pro Tier 0-2, Claude Opus 4.7 Tier 3+
- DE/FA-Übersetzung: Claude Sonnet 4.6 oder Opus 4.7
- Transcription: Whisper Tier 0-2

**Cost-Cap:**
- Hard-Cap 100€/mo soft, 200€/mo hard (configurable per module)
- Warn at 80%, downgrade at 95% (Opus→Sonnet→Haiku), refuse at 100% mit operator-override
- Trace-DB `aseckzai_ai_calls` für jeden Call

## Auth + MFA

**Supabase Auth** mit Google OAuth primary (most family members have Google).
- E-Mail+Password als Fallback
- Passkey/WebAuthn preferred für sicherheits-bewusste Users

**MFA-Matrix:**
- super_admin (Kais): Passkey + TOTP backup MANDATORY
- family_admin / business_owner / accountant: Passkey oder TOTP MANDATORY
- family_member adult: TOTP STRONGLY RECOMMENDED
- employee: TOTP MANDATORY vor financial access
- viewer (Steuerberater extern): TOTP MANDATORY + IP-Allowlist optional

**Session:** JWT 1h TTL, Refresh-Token 7d rotated, Concurrent-Limit 3, Idle-Timeout 30min in sensitive views.

## Hosting + Deployment

**Vercel Pro** für Frontend+API:
- EU-Region erzwingen (EU-Functions)
- Production-Branch = main
- Preview-Deploys auf jedem PR
- Kosten ~€20/mo

**Region exklusiv EU:** Frankfurt primary, Helsinki backups.
**Domain:** custom domain mit DNSSEC, TLS 1.3 only, HSTS preload.

## Observability

- **Sentry EU** (Frontend + Backend Errors) — PII-Scrubbing für passport_number, iban, etc.
- **Better Stack** oder Logflare für strukturierte Logs (90d retention)
- **Grafana Cloud EU free tier** für Metrics (Supabase Prometheus + Custom)
- **Telegram via Aria-Channel** für kritische Alerts (DB down, auth broken, backup failed, AI-spend > 150% cap)

## Cost-Floor

| Phase | Monthly EUR |
|---|---|
| Phase 1 (family inbox dummy data) | ~69 |
| Phase 3 (Durrani Belege aktiv) | ~140-190 |
| Phase 4 (full BPRUEFUNG-Cockpit) | ~245-345 |
| Phase 5 (multi-tenant per family) | +30-80 per tenant |

Hard-Cost-Floor (Vercel + Supabase + Hetzner + R2 + Storage-Box) ~€55/mo predictable. AI-Spend ist Swing-Item, durch Privacy-Tier-Routing + Cost-Cap bounded.

## Token-Convention

- **Lokal:** `/root/aria/.env` chmod 600 (existiert)
- **Vercel:** Dashboard → Project Settings → Environment Variables (Production-only)
- **Supabase:** Project Settings → Vault für KEK
- **Niemals:** im Repo, niemals via Telegram pasten (LRN-20260506-003 — Audit-Trail-Leak)

**Übergabe-Weg:** Kais via SSH Aria-Control oder direkt → `nano /root/aria/.env` → Telegram-Notify "neue Keys in env" → Aria source-restart.

## Brain-Bridge Topology

**Option A (entschieden 14.05.2026):**
- 2 separate Supabase-Projekte (aria + aseckzai)
- 2 MCP-Server auf verschiedenen Hosts
- `aseckzai-mcp-gateway` proxied read-only requests von Aria
- Aseckzai → Aria one-way für sanitized Tier-0/1-Playbooks (mit Owner-Approval-Gate)
- ~€25/mo extra (akzeptabel)

ADR-0005 wird in Phase 3 geschrieben, nicht jetzt.
