RebreakVpnService.onStartCommand crashed with SecurityException because Android 16's validateForegroundServiceType rejects the implicit 2-arg startForeground(). Now passes FOREGROUND_SERVICE_TYPE_SPECIAL_USE explicitly (Google's documented best practice) and guards the call so a failed foreground promotion stops the service cleanly instead of crashing the app. Verified vs reported Galaxy A54 / Android 16 signature (97% of crash events, 1-user crash loop). Bundles pending working-tree work across native/marketing/locales/mac + graphify-out rebuild. gitignore: google-services.json + /screenshots/. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebreak Magic (Mac)
End-User-Wizard für Self-Binding eines Macs + iPhones an Rebreak. Macht in einem 6-Step-Flow:
- Mac Registration — Mac im Backend registrieren + DNS-Filter-Profil installieren
- Welcome — Detect iPhone via USB (lockdownd)
- Pre-Flight — Find-My-iPhone + Stolen-Device-Protection prüfen/ausschalten
- Supervise —
supervise-magicPlist-Inject + Reboot (kein Erase) - Enroll — MDM-Enrollment-Profile auf iPhone installieren
- Configure — NanoMDM pusht: Lock-Profile + Take-Management + Settings(mdmSupervised=true)
Resultat:
- Mac: DNS-Filter aktiv (Gambling-Domains blockiert via DoH-ClientID)
- iPhone: supervised by "Rebreak", App nicht löschbar, NEFilter aktiv (kein User-Toggle in Settings)
Status
✅ Phase 2 abgeschlossen — Backend-Auth-Integration + Mac-Registration
Was ist neu in Phase 2?
- Login-Gate: User muss sich mit Rebreak-Account anmelden bevor Wizard startet
- Mac-Device-Registration: Jeder Mac wird im Backend registriert (max. 3 Devices pro Account)
- DNS-Filter für Mac: Installation eines personalisierten DNS-Filter-Profils (DoH-ClientID)
- Managed Bindings: UI zum Verwalten gebundener Geräte + 24h-Release-Cooldown
Siehe PHASE2_SUMMARY.md für Details.
Warum "Magic"?
Normalerweise muss ein iPhone komplett zurückgesetzt werden um es zu supervisen (alle Daten weg, Werks-Setup, Apple-Configurator-Kabel-Pairing mit komplexem Setup).
Rebreak Magic macht das ohne Reset — deine Fotos, Apps, Settings bleiben. Das ist in der Branche unüblich und spart den Betroffenen massiv Zeit und Frust beim Onboarding.
Pre-Requirement:
- Rebreak-Account (Login via Supabase-Auth)
- Rebreak-App muss VOR Wizard-Start aus TestFlight installiert sein (nur für iPhone-Binding)
- Config-File mit Supabase + Backend-URLs (siehe Config-Section)
Status
🚧 Phase 1 — Skelett. Nur lokal nutzbar (User+Olfa+Dev-iPhones).
Voraussetzungen
| Tool | Wie |
|---|---|
| Xcode 16+ | App Store |
| xcodegen | brew install xcodegen |
| libimobiledevice | brew install libimobiledevice |
| supervise-magic binary | aus ../../ops/mdm/supervise-magic/ (make build) |
| cfgutil | Apple Configurator (App Store) → /Applications/Apple Configurator.app/Contents/MacOS/cfgutil für silent profile install |
| create-dmg | brew install create-dmg (für DMG-Build) |
Ja. Es nutzt Apple-offizielle MDM-APIs (gleiche wie Schul-iPads). Es installiert nichts Apple-Fremdes. Die Supervision kann jederzeit aufgehoben werden (Settings → Allgemein → VPN & Geräteverwaltung → Profile entfernen → Reboot).
Was bedeutet das für mich?
- Die Rebreak-App ist nicht mehr per "App wackelt → X tippen" löschbar
- Der NEFilter (Gambling-Domain-Blocker) lässt sich nicht in den Settings ausschalten
- Du brauchst die Rebreak-Vertrauensperson um die Bindung zu lösen
Kann ich das rückgängig machen?
Ja, aber mit Absicht — nicht im Affekt. Siehe Rebreak-App → Settings → Trustee-Override (7-Tage-Cooldown).
Welche Daten sieht Rebreak?
Nur dass dein Device supervised IST + an unseren MDM-Server enrollt. Keine Inhalte, keine Browsing-History, keine Telemetrie über deine Nutzung.
Status
🚧 Phase 1 — Skelett. Nur lokal nutzbar (User+Olfa+Dev-iPhones).
Voraussetzungen
| Tool | Wie |
|---|---|
| Xcode 26+ | App Store |
| xcodegen | brew install xcodegen |
| libimobiledevice | brew install libimobiledevice |
| supervise-magic binary | aus ../../ops/mdm/supervise-magic/ (make build) |
| cfgutil | Apple Configurator (App Store) → /Applications/Apple Configurator.app/Contents/MacOS/cfgutil für silent profile install |
Build
Development-magic-mac
Einmalig: dependencies + supervise-magic-binary bauen
(cd ../../ops/mdm/supervise-magic && make tidy && make build)
Xcode-Project generieren (oder neu generieren nach project.yml Änderungen)
xcodegen generate
Bauen + öffnen
open RebreakMagic.xcodeproj
→ ⌘R in Xcode
Oder CLI-only:
```bash
xcodebuild -project RebreakMagic.xcodeproj -scheme RebreakMagic -configuration Debug build
open build/Build/Products/Debug/RebreakMagic.app
Production-DMG (für Distribution)
./build-dmg.sh
Output: build/RebreakMagic-0.1.0.dmg
Hinweis: App ist unsigned (ad-hoc signature). User braucht Right-Click → Öffnen beim ersten Start (Gatekeeper-Warning). Für Production: Developer ID Application Cert nötig.
Falls das Icon nicht sofort erscheint nach Installation:
sudo rm -rf /Library/Caches/com.apple.iconservices.store && killall Dock
- Notarization via
xcrun notarytool - Staple Notarization-Ticket:
xcrun stapler staple - DMG dann ohne Gatekeeper-Warning installierbar
App-Icon
Das Rebreak-Logo ist im Sources/Resources/Assets.xcassets/AppIcon.appiconset/ integriert (alle macOS-Größen von 16x16 bis 1024x1024). Icons werden aus apps/rebreak-native/assets/icon.png generiert.
Falls Icons neu generiert werden müssen (z.B. nach Logo-Update):
# Master-Icon aus rebreak-native kopieren
cp ../rebreak-native/assets/icon.png /tmp/master-icon.png
# macOS-Icon-Größen generieren via sips
cd Sources/Resources/Assets.xcassets/AppIcon.appiconset/
sips -z 16 16 /tmp/master-icon.png --out icon_16x16.png
sips -z 32 32 /tmp/master-icon.png --out icon_16x16@2x.png
sips -z 32 32 /tmp/master-icon.png --out icon_32x32.png
sips -z 64 64 /tmp/master-icon.png --out icon_32x32@2x.png
sips -z 128 128 /tmp/master-icon.png --out icon_128x128.png
sips -z 256 256 /tmp/master-icon.png --out icon_128x128@2x.png
sips -z 256 256 /tmp/master-icon.png --out icon_256x256.png
**WICHTIG**: Seit Phase 2 braucht die App ein Config-File mit Supabase + Backend-URLs.
### Schritt 1: Config-File erstellen
```bash
mkdir -p ~/.config/rebreak-magic
cp config.example.json ~/.config/rebreak-magic/config.json
chmod 600 ~/.config/rebreak-magic/config.json
Schritt 2: Config-Werte eintragen
Editiere ~/.config/rebreak-magic/config.json:
{
"supabaseUrl": "https://your-project.supabase.co",
"supabaseAnonKey": "your-supabase-anon-key",
"backendBaseUrl": "https://staging.rebreak.org",
"mdmServer": "https://mdm.rebreak.org",
"mdmUser": "admin",
"mdmApiKey": "your-nanomdm-api-key"
}
Wo finde ich die Werte?
| Key | Quelle |
|---|---|
supabaseUrl |
Supabase-Dashboard → Project Settings → API → Project URL |
supabaseAnonKey |
Supabase-Dashboard → Project Settings → API → anon public key |
backendBaseUrl |
Staging: https://staging.rebreak.org, Prod: https://api.rebreak.org |
mdmServer |
https://mdm.rebreak.org (rebreak-mdm-VM) |
mdmUser |
admin (NanoMDM-Basic-Auth-User) |
mdmApiKey |
/root/.nanomdm_admin_pass auf rebreak-mdm (32-char-hex) |
Hinweis: mdmServer, mdmUser, mdmApiKey werden nur für iPhone-Setup (Steps 5-6) benötigt. Falls du nur den Mac-DNS-Filter testen willst, kannst du Dummy-Werte eintragen.
Alte Config (pre-Phase-2)
Falls du ein altes ~/.config/rebreak-binder/config.json hast (nur MDM-Keys), lösche es und erstelle ~/.config/rebreak-magic/config.json neu. Der alte Pfad wird nicht mehr verwendet
"mdmApiKey": "<32-char-hex from /root/.nanomdm_admin_pass on rebreak-mdm>"
}
EOF
chmod 600 ~/.config/rebreak-binder/config.json
Production-Version legt das in Keychain ab — heute reicht plain JSON.
## Troubleshooting
### iPhone wird nicht erkannt
```bash
# Prüfe libimobiledevice
idevice_id -l
# Falls leer: USB-Kabel-/Port-Problem oder "Diesem Computer vertrauen?" Dialog nicht bestätigt
# PRelated Docs
- [ops/mdm/ARCHITECTURE.md](../../ops/mdm/ARCHITECTURE.md) — MDM-Infrastruktur-Overview
- [ops/mdm/PHASES.md](../../ops/mdm/PHASES.md) — Roadmap (Self-Binding → ABM-DEP → Mac-Support)
- [ops/mdm/RUNBOOK.md](../../ops/mdm/RUNBOOK.md) — NanoMDM-Server-Operations
- [ops/mdm/supervise-magic/README.md](../../ops/mdm/supervise-magic/README.md) — supervise-magic-Technical-Deep-Dive
## License
Proprietary. © 2026 Raynis GmbH.
../../ops/mdm/supervise-magic/bin/supervise-magic --device <udid>
# Check stdout/stderr
MDM-Enrollment schlägt fehl
- Prüfe NanoMDM-Server:
ssh rebreak-mdm 'pm2 status'→nanomdm-servermussonlinesein - Prüfe nginx:
ssh rebreak-mdm 'curl -I https://mdm.rebreak.org'→ 200 OK - Prüfe APNs-Cert-Ablauf: siehe
ops/mdm/RUNBOOK.md→ APNs-Cert-Renewal-Section
Icon wird als Placeholder angezeigt
macOS Icon-Cache clearen:
sudo rm -rf /Library/Caches/com.apple.iconservices.store
killall Dock Finder
Dann App neu starten.
TODOs (post-Phase-2)
Phase 3 (geplant)
- Code-Signing + Notarization (Developer-ID-Cert)
- Unit-Tests für AuthService, MagicAPIClient, MacDeviceDetector
- Profile-Signierung (Apple-Developer-Cert für DNS-Filter-Profil)
- Offline-Retry-Logic (Network-Error-Handling mit Retry-Button)
- Mac-Supervision via UAMDM (aktuell: nur DNS-Filter, keine Supervision)
Backlog
- Lock-Profile-Refactor:
allowAppRemoval=falseGLOBAL raus ausrebreak-content-filter-sideload.mobileconfig. Per-App-Lock kommt über Managed-App-State (MDMInstallApplicationmitChangeManagementState: Managed→ iOS deaktiviert App-Wackel-„X" automatisch für managed apps). Andere Apps bleiben löschbar (bessere UX). - App-Versions-Mgmt:
InstallApplication-Manifest-URL-Pointer auf latest IPA (sieheops/mdm/PHASES.mdPhase F.5) - [ Auth-Stack** (Phase 2):
- Supabase-JWT-Login (
AuthService.swift) - Keychain-Persistence (Service:
org.rebreak.magic) - Auto-Refresh bei Token-Expiry
- Supabase-JWT-Login (
- Backend-API-Client (
MagicAPIClient.swift):/api/magic/register— Mac-Device-Registration/api/magic/devices— List own bindings/api/magic/devices/{id}/request-release— 24h-Cooldown/api/magic/profile.mobileconfig— Personalisiertes DNS-Filter-Profil (DoH-ClientID)
- Services sind dünne Wrapper um:
ideviceinfo(libimobiledevice) — Device-Detectionsupervise-magicGo-CLI — Supervise + Status-Checkcfgutil(optional, Apple Configurator 2) — Silent Profile-Install- NanoMDM HTTP-API (
mdm.rebreak.org) — InstallProfile + Settings-Commands profilescommand (macOS) — Mac-DNS-Filter-Installation
- Mac-Device-Registration API
- DNS-Filter-Profil-Installation
- Manage-Bindings-UI (Device-Limit, Release-Cooldown)
- Login-Gate vor Wizard
Architektur
- SwiftUI macOS-App mit
@ObservableState-Machine (WizardModel) - Services sind dünne Wrapper um:
ideviceinfo(libimobiledevice) — Device-Detectionsupervise-magicGo-CLI — Supervise + Status-Checkcfgutil(optional, Apple Configurator 2) — Silent Profile-Install- NanoMDM HTTP-API (
mdm.rebreak.org) — InstallProfile + Settings-Commands
- Kein Backend-Account-Login für MVP — API-Key in lokalem Config
Sicherheit
- API-Key sollte langfristig in Keychain (heute: plain JSON, chmod 600)
- App ist unsigned für lokales Testen — Gatekeeper-Warning beim ersten Öffnen (Right-Click → Öffnen)
- Production: Developer ID Application Cert + Notarization nötig (siehe Build → DMG)
- Process-Spawn von go-binaries braucht disabled App-Sandbox (gesetzt in
project.yml)