Firestore Collections – Zugriffs-Matrix¶
Vollständige Übersicht aller Collections in core/firestore.rules mit Zugriffsbeschränkungen.
Legende: - 🟢 PUBLIC_READ: Unauthentifizierte Reads erlaubt - 🔵 ERP_ONLY: Nur ERP-User (appType='erp') - 🟠 CUSTOMER_SCOPED: Multi-Tenant, Customer-ID-basierte Isolation - 🟣 PERMISSIONS_BASED: Feingranulare Permissions (canEdit, canCreate) - 🔴 SERVER_ONLY: Kein Client-Zugriff (nur Cloud Functions via Admin SDK) - 🟡 MIXED: Unterschiedliche Regeln für Read/Write
🟢 PUBLIC_READ¶
| Collection | Read | Write | Beschreibung |
|---|---|---|---|
system_settings/web_app_theme_settings |
✅ Alle | 🔵 Admin | Theme-Einstellungen für Login-Seite |
system_settings/mobile_app_theme_settings |
✅ Alle | 🔵 Admin | Mobile Theme-Einstellungen |
🔵 ERP_ONLY (ERP-User + Admin)¶
| Collection | Read | Write | Beschreibung |
|---|---|---|---|
users/{userId} |
🟡 Siehe Notiz¹ | 🟡 Siehe Notiz² | ERP-Benutzerverwaltung |
system_settings/order_reminders/notifications/{settingId} |
🔵 ERP | 🔵 Admin | Bestellerinnerungen-Konfiguration |
system_settings/customer_categories/entries/{categoryId} |
🔵 ERP | 🟣 Admin + canEditCustomers | Kundenkategorien |
system_settings/{settingId}/{subcollection=**} |
🔵 ERP | 🔵 Admin | Alle anderen Settings-Subcollections |
notifications/{notificationId} |
🔵 ERP | 🔵 Admin | Benachrichtigungen |
notificationGroups/{groupId} |
🔵 ERP | 🔵 Admin | Benachrichtigungsgruppen |
customerLists/{listId} |
🔵 ERP | 🔵 Admin | ERP-Kundenlisten-Verwaltung |
customerLists/{listId}/customerListCustomers/{customerId} |
🔵 ERP | 🔵 Admin | Kunden in Listen |
customerLists/{listId}/customerListStatus/{statusId} |
🔵 ERP | 🔵 Admin | Listen-Status |
customerLists/{listId}/customerListActions/{actionId} |
🔵 ERP | 🔵 Admin | Listen-Aktionen |
statistics/{periodId} |
🔵 ERP | 🔴 Functions | Statistiken pro Zeitraum (today, thisWeek, …) |
statistics/{periodId}/articlesByRevenue/{articleId} |
🔵 ERP | 🔴 Functions | Top-Artikel nach Umsatz |
statistics/{periodId}/customerSales/{customerId} |
🔵 ERP | 🔴 Functions | Top-Kunden nach Umsatz |
statistics/{periodId}/countries/{countryCode} |
🔵 ERP | 🔴 Functions | Länder-Umsätze |
statistics/{periodId}/articleSpecific/{articleId} |
🔵 ERP | 🔴 Functions | Artikelspezifische Detailstatistiken |
statisticsCustomerSales/{statisticId} |
🔵 ERP | 🔴 Functions | [Legacy] Kunden-Umsatz (migriert → statistics) |
statisticsCountries/{statisticId} |
🔵 ERP | 🔴 Functions | [Legacy] Länder-Umsätze (migriert → statistics) |
statisticsSalesVolume/{periodId} |
🔵 ERP | 🔴 Functions | [Legacy] Umsatz-Timeline (migriert → statistics) |
savedNotificationFilters/{filterId} |
🔵 ERP | 🔵 ERP (eigene) | Gespeicherte Benachrichtigungs-Filter |
connectors/{connectorId} |
🔵 ERP | 🔵 Admin | Connector-Metadata |
connectors/{connectorId}/history/{historyId} |
🔵 ERP | 🔴 Functions | Connector-Historie |
connectorLogs/{logId} |
🔵 ERP | 🔴 Functions | Connector-Logs |
jobExecutions/{executionId} |
🔵 ERP | 🔴 Functions | Job-Ausführungs-Logs |
triggerLogs/{logId} |
🔵 ERP | 🔴 Functions | Firestore-Trigger-Logs |
_orderIdempotency/{key} |
🔵 ERP | 🔴 Functions | Doppelbestellungs-Schutz |
counters/{counterId} |
🔵 ERP + canCreateOrders | 🔵 ERP + canCreateOrders | Sequenz-Zähler (z.B. Auftragsnummern) |
Notizen:
- ¹ users/{userId} Read: ERP-User, Admin ODER eigenes Dokument (für Social-Login-Registrierung)
- ² users/{userId} Write:
- Update eigene Daten (außer userRole/permissions): ✅ ERP-User/Admin
- Update User-Profile inkl. Rolle user/admin (aber NICHT SuperAdmin): ✅ Admin
- Create/Delete/Update SuperAdmins: ❌ Nur SuperAdmin
🟠 CUSTOMER_SCOPED (Multi-Tenant mit Customer-ID-Isolation)¶
| Collection | Read | Write | Beschreibung |
|---|---|---|---|
customers/{customerId} |
🟡 ERP + Shop (eigene) | 🟣 Permissions³ | Kundenstammdaten |
customers/{customerId}/purchaseLists/{listId} |
🟡 ERP + Shop (eigene) | 🟡 Admin/Permissions + Shop-Admin⁴ | Bestelllisten |
customers/{customerId}/deliveryBreaks/{breakId} |
🟡 ERP + Shop (eigene) | 🟡 Admin/Permissions + Shop-Admin⁴ | Lieferpausen |
customers/{customerId}/{subcollection=**} |
🟡 ERP + Shop (eigene) | 🟣 Permissions³ | Alle anderen Customer-Subcollections |
customers/{customerId}/deliveryAddresses/{addressId} |
🟡 ERP + Shop (eigene) | 🟡 Siehe Notiz⁵ | Lieferadressen (Shop: nur source=customer) |
customers/{customerId}/customerFeed/{feedItemId} |
🟡 ERP + Shop (eigene) | 🟡 Siehe Notiz⁶ | Customer-Feed (Shop: nur isRead/popupShown/isArchived) |
customers/{customerId}/devices/{deviceId} |
🟡 ERP + Shop (eigene) | 🟡 Shop (deviceId==uid) + Admin | Push-Notification-Devices |
customerUsers/{customerUserId} |
🟡 Siehe Notiz⁷ | 🟡 Siehe Notiz⁸ | Shop-User-Zugriffsverwaltung |
customerUsers/{customerUserId}/devices/{deviceId} |
🟡 ERP + Shop (eigene) | 🟡 Shop (eigene) + Admin | FCM-Tokens |
orders/{orderId} |
🟡 ERP + Shop (eigene) | 🔴 Siehe Notiz⁹ | Bestellungen (K-01: Keine direkten Creates!) |
orders/{orderId}/{subcollection=**} |
🟡 ERP + Shop (eigene) | 🔵 ERP + canEditOrders | Order-Subcollections (Positionen, History) |
Notizen:
- ³ Permissions: canCreateCustomers (create), canEditCustomers (update), canDeleteCustomers (delete)
- ⁴ Shop-Admin für gleichen Customer darf ebenfalls create/update/delete
- ⁵ deliveryAddresses Shop-User: nur source=1 (customer) create/update/delete. ERP-Adressen (source=0) sind read-only
- ⁶ customerFeed Shop-User: nur isRead, popupShown, isArchived dürfen geändert werden
- ⁷ customerUsers Read: ERP + eigene Einträge (auch pending) + Shop-Admin des Kunden
- ⁸ customerUsers Write:
- Create: Auth-User (email==own, registrationState=0) + ERP-Admin/canEditCustomers
- Update: Shop-User (eigene Profildaten, außer customerId/email/registrationState) + Admin + Shop-Admin (Freigabe/Rolle)
- Delete: Admin + Shop-Admin
- ⁹ orders Write:
- Create: ❌ VERBOTEN (K-01: nur via Callable createOrder / createOrderErp)
- Update: ERP (canCancelOrders): Stornierung (4 Felder) | Shop-User: eigene Bestellung stornieren (Status ≤1)
- Delete: Admin
🟣 PERMISSIONS_BASED (Feingranulare Permissions)¶
| Collection | Read | Write | Beschreibung |
|---|---|---|---|
system_settings/license_config |
🟡 ERP + Shop (approved) | 🔴 SuperAdmin | Lizenz-Konfiguration |
system_settings/article_categories/entries/{categoryId} |
🟡 ERP + Shop (approved) | 🟣 Admin + canEditArticles | Artikelkategorien |
system_settings/{settingId} |
🟡 ERP + Shop (approved) | 🔵 Admin | Allgemeine Settings |
articles/{articleId} |
🟡 ERP + Shop (approved) | 🟣 Siehe Notiz¹⁰ | Artikel |
articles/{articleId}/articleDocuments/{documentId} |
🟡 ERP + Shop (approved) | 🟣 Siehe Notiz¹⁰ | Artikel-Dokumente |
articles/{articleId}/extensions/{extensionKey} |
🟡 ERP + Shop (approved) | 🟣 Siehe Notiz¹⁰ | Artikel-Erweiterungen |
articles/{articleId}/{subcollection=**} |
🟡 ERP + Shop (approved) | 🟣 Siehe Notiz¹⁰ | Artikel-Subcollections (images, packageSizes, etc.) |
articlePackageSizes/{packageSizeId} |
🟡 ERP + Shop (approved) | 🟣 Admin + canEditArticles | Paketgrößen |
priceLists/{priceListId} |
🟡 ERP + Shop (approved) | 🟣 Admin + canEditPrices | Preislisten |
priceLists/{priceListId}/priceListArticles/{articleId} |
🟡 ERP + Shop (approved) | 🟣 Admin + canEditPrices | Preislisten-Artikel |
Notizen: - ¹⁰ Artikel-Permissions: - Create: Admin + canCreateArticles - Update: Admin + canEditArticles - Delete: Admin + canDeleteArticles
🔴 SERVER_ONLY (Kein Client-Zugriff, nur Cloud Functions)¶
| Collection | Read | Write | Beschreibung |
|---|---|---|---|
connectorCredentials/{credentialId} |
⚠️ SuperAdmin | 🔴 Functions | Connector API-Keys (sensibel) |
auditLogs/{logId} |
⚠️ SuperAdmin | 🔴 Functions | Audit-Logs |
_rateLimits/{limitId} |
🔴 Functions | 🔴 Functions | DDoS-Schutz / Rate Limiting |
_quotas/{quotaId} |
🔴 Functions | 🔴 Functions | Killswitch Quota-Counter |
_system/{docId} |
🔴 Functions | 🔴 Functions | Killswitch System-Docs |
_claimsUpdateLocks/{lockId} |
🔴 Functions | 🔴 Functions | K-02: Race-Condition-Prevention |
securityIncidents/{incidentId} |
🔴 Functions | 🔴 Functions | Storage-Content-Validation-Logs |
orderExportQueue/{docId} |
🔴 Functions | 🔴 Functions | Auftragsexport-Warteschlange |
receivedOrders/{orderId} |
🔴 Functions | 🔴 Functions | Empfangene Aufträge (orderReceiverApi, TTL 90d) |
mailQueue/{docId} |
🔴 Functions | 🔴 Functions | E-Mail-Versand-Queue |
_geocodingCache/{docId} |
🔴 Functions | 🔴 Functions | Nominatim-Geocoding-Cache |
tenants/{docId} |
🔴 Functions | 🔴 Functions | Connector-Multi-Mandantenfähigkeit |
devSyncSnapshots/{docId} |
🔴 Functions | 🔴 Functions | Prod→Dev Datensynchronisation |
settings/appConfig |
🔴 Functions | 🔴 Functions | App-Store-URLs für E-Mail-Templates |
systemChecks/{checkId} |
⚠️ SuperAdmin | 🔴 Functions | GitHub Actions Systemprüfungen |
🟡 SPECIAL RULES¶
userTokenSignals/{uid}¶
- Read: ✅ Nur eigenes Dokument (uid == request.auth.uid)
- Write: 🔴 Functions
- Zweck: Force Token Refresh bei Custom Claims Änderungen
notifications/{notificationId}/notificationCustomerEntries/{entryId}¶
- Read: 🔵 ERP
- Write: 🔴 Functions
❌ DEPRECATED (Deny-by-default, Migration erforderlich)¶
| Collection | Read | Write | Beschreibung |
|---|---|---|---|
articleCategories/{categoryId} |
❌ | ❌ | Alter Top-Level-Pfad (deprecated) |
customerCategories/{categoryId} |
❌ | ❌ | Alter Top-Level-Pfad (deprecated) |
🛡️ CATCH-ALL RULE¶
Alle nicht explizit definierten Collections sind gesperrt!
Jede neue Collection MUSS explizit mit spezifischen Rules definiert werden.
🔑 Helper Functions¶
| Function | Beschreibung |
|---|---|
isAuthenticated() |
User ist eingeloggt |
isErpUser() |
appType='erp' Claim |
isShopUser() |
appType='shop' Claim |
isApprovedShopUser() |
Shop-User mit min. 1 freigeschaltetem Kunden |
hasCustomerAccess(customerId) |
Shop-User hat Zugriff auf Kunden (via customerIds Claim) |
isShopAdminForCustomer(customerId) |
Shop-Admin für Kunden (via adminCustomerIds Claim) |
isSuperAdmin() |
userRole==2 Claim |
isAdmin() |
userRole>=1 Claim |
hasPermission(permission) |
Prüft permissions Claim (z.B. canEditArticles) |
📊 Collections-Statistik¶
- Total: ~70 Collections/Subcollections
- PUBLIC_READ: 2
- ERP_ONLY: 23
- CUSTOMER_SCOPED: 11
- PERMISSIONS_BASED: 10
- SERVER_ONLY: 16
- SPECIAL: 2
- DEPRECATED: 2
🔒 Security Notes¶
K-01: Server-Only Order Creation¶
Bestellungen dürfen NICHT direkt von Clients angelegt werden. Verhindert: - CWE-602 (Client-Side Security Enforcement) - Preis-Manipulation durch Shop-User - Fehlende Audit-Trails
K-02: Claims Update Locks¶
Distributed Lock-Mechanismus für parallele Shop-User-Approvals (Race Condition Prevention)
Cloud Functions Bypass¶
⚠️ WICHTIG: Cloud Functions nutzen das Admin SDK und haben VOLLEN Zugriff auf Firestore – unabhängig von diesen Rules!
Diese Rules gelten nur für: - Client-Apps (Web, iOS, Android) - Direkte Firestore-Zugriffe über Firebase SDK
Generiert: 19. Mai 2026
Quelle: core/firestore.rules