Geheimer API-Schlüssel in Expo-Apps: was schützen?
Von Mehdi Azizi
Aktualisiert am , 7 Min.
Öffentlicher Supabase-Schlüssel, Server-Secret, Expo-Variablen: Was darf in deine iPhone-App, und wie testest du den Zugriff mit zwei Konten?
Eine Umgebungsvariable ist nicht automatisch ein Geheimnis
In einer Expo-App ist eine Variable mit dem Präfix EXPO_PUBLIC_ für den App-Code gedacht. Sie darf kein Server-Secret enthalten. Expo erklärt, dass diese Werte in das kompilierte JavaScript eingebettet werden und von den Nutzern der App gelesen werden können. Einen Schlüssel in eine .env-Datei zu verschieben, reicht also nicht, um ihn zu schützen. Quelle: Umgebungsvariablen in Expo.
Bevor du eine KI bittest, „die API anzubinden“, ordne ein, was du ihr gibst: eine Service-Adresse, einen Schlüssel, der öffentlich sein darf, oder einen Schlüssel, der privilegierte Aktionen erlaubt. Diese Einordnung bestimmt, wo der Code laufen muss.
Die folgende Tabelle ist ein Entwurfsraster, kein Audit deiner App.
| Element | Wohin damit | Was du prüfen solltest |
|---|---|---|
| Öffentliche Backend-Adresse | App-Konfiguration | Sie zeigt auf die richtige Umgebung. |
| Supabase-Schlüssel publishable oder alter anon-Schlüssel | App, wenn die Berechtigungen korrekt konfiguriert sind | Die Datenregeln blockieren tatsächlich den Zugriff auf das Konto eines anderen Nutzers. |
| Supabase-Schlüssel secret oder service_role | Nur auf dem Server | Er taucht weder im mobilen Bundle noch in Logs auf, die der Client sehen kann. |
| Geheimer Schlüssel eines KI-Anbieters | Nur auf dem Server | Die App ruft deinen Server auf, der Nutzer und Limits prüft, bevor er den Anbieter anfragt. |
Supabase unterscheidet zwischen Schlüsseln für Clients und geheimen Schlüsseln für vertrauenswürdige Umgebungen. Ein öffentlicher Schlüssel identifiziert das Projekt; er ersetzt keine Berechtigungen auf den Daten. Quelle: Supabase-API-Schlüssel.
Beispiel: eine fiktive Lesetagebuch-App
Stell dir eine App vor, in der Léa und Sami ihre Bücher und privaten Notizen speichern. Das Beispiel dient zur Vorbereitung der Tests; es beschreibt keine Ergebnisse aus einer Devoria-App.
Der normale Ablauf wirkt korrekt: Léa meldet sich an und sieht ihre Notizen. Damit ist die wichtige Frage aber noch nicht beantwortet: Lehnt der Server eine Anfrage von Léa ab, die auf eine Notiz von Sami zielt?
Ein Filter in der Oberfläche, etwa „Notizen des angemeldeten Nutzers anzeigen“, verbessert die Anzeige. Die Autorisierung muss aber auch auf Datenebene greifen. In Supabase kannst du mit Row Level Security die zugänglichen Zeilen abhängig von der Session einschränken. Supabase empfiehlt, sie für alle Tabellen zu aktivieren, die über die API erreichbar sind, und erklärt die Richtlinien für Lesen und Schreiben. Quelle: Row Level Security.
Ordne in deinem eigenen Testprojekt jede Notiz ihrem Eigentümer zu und lege getrennt fest, wer sie lesen, erstellen, ändern und löschen darf. Prüf auch die Dateien: Eine geschützte Datenbankzeile beweist nicht, dass ein Bild privat ist.
Der Testablauf mit zwei Testkonten
Leg zwei Konten an, die du kontrollierst, mit je einem anderen Buch und einer kleinen, wiedererkennbaren Notiz. Verwende fiktive Daten in einer erlaubten Testumgebung.
- Eigene Notiz lesen. Konto A findet Notiz A.
- Notiz von B aus A lesen. Die Anfrage gibt keinen privaten Inhalt preis.
- Notiz von B aus A ändern. Der Server lehnt ab; Notiz B bleibt unverändert.
- Im Namen von B aus A erstellen. Der Server lehnt diese Zuordnung ab.
- Ohne Session lesen. Es wird kein privater Inhalt zurückgegeben.
- Private Datei von B aus A öffnen. Die Datei ist nicht zugänglich.
Notier das tatsächliche Ergebnis, die getestete Version und einen eventuellen Fehler. „Die Regeln sind aktiviert“ ist kein Testergebnis. Das Testraster in den Ressourcen kann dir als Grundlage dienen, um diese Nachweise festzuhalten.
Kostenpflichtige Aufrufe über deinen Server leiten
Für eine Funktion, die ein Buch mit einer KI-API zusammenfasst, kann der Ablauf so aussehen: App → dein Server → Anbieter → dein Server → App. Der geheime Schlüssel bleibt auf dem Server. Diese Architektur allein reicht nicht: Auch der Zugriff auf den Server muss kontrolliert werden.
Im fiktiven Beispiel muss der Server unter anderem die Session prüfen, prüfen, ob das Buch der Person gehört, wiederholte Anfragen begrenzen und einen verständlichen Fehler zurückgeben, wenn der Anbieter nicht antwortet. Der Client entscheidet nicht selbst, ob ein Nutzer bezahlten Zugang hat.
Bereite vier Tests vor: nicht angemeldeter Nutzer, Buch eines anderen Kontos, erreichtes Limit und nicht erreichbarer Anbieter. Mit dem letzten prüfst du, ob die App den Ladezustand verlässt, ohne die Eingabe zu verlieren.
Was du deinen Coding-Assistenten fragen kannst
Hier ist eine Review-Anweisung, die du an dein Repository anpassen kannst, ohne deine geheimen Werte einzufügen:
Liste die Variablen auf, die der mobile Code und der Server verwenden, und zeige nur ihre Namen an. Identifiziere privilegierte Aufrufe auf der Client-Seite. Beschreibe für private Daten die Lese- und Schreibkontrollen und schlage dann einen Testablauf mit zwei Testkonten vor. Führe ohne Freigabe keine Schlüsselrotation und keine Änderung an der Produktion durch.
Lies die Antwort zusammen mit dem zugehörigen Code. Ein Assistent kann eine Unstimmigkeit erkennen; seine Antwort ersetzt nicht das Ausführen der Tests. Der Guide eine App mit Claude Code erstellen erklärt, wie du diese Arbeit aufteilst.
Bevor du an deiner App weitermachst
Du solltest drei Dinge einfach erklären können: welche Werte öffentlich sind, welche Operationen über den Server laufen und welche Tests zeigen, dass ein Konto die Daten eines anderen nicht sieht. Wenn einer dieser Punkte unklar bleibt, kläre ihn, bevor du neue Funktionen hinzufügst.
Die Seite eine iPhone-App erstellen ordnet diesen Schritt in das Gesamtprojekt ein. Wenn du der Reihe nach vorgehen willst, bietet das iOS Kit einen Weg in vier Schritten und einen Starter Code, der Konten und KI bereits enthält. Wenn du nicht mehr weißt, bei welchem Schritt du weitermachen sollst, bringt die kostenlose Diagnose dein Projekt in die richtige Reihenfolge und schickt dir meine Checkliste gegen Apple-Ablehnungen.
Häufige Fragen
Wohin gehört ein geheimer API-Schlüssel in einer Expo-App?
Auf deinen Server, nie in die App. Der Supabase-Schlüssel secret oder service_role bleibt genau wie der geheime Schlüssel eines KI-Anbieters ausschließlich auf dem Server. Die App ruft deinen Server auf, der Nutzer und Limits prüft, bevor er den Anbieter aufruft. Prüf, dass keiner dieser Schlüssel im mobilen Bundle oder in Logs auftaucht, die der Client sehen kann.
Schützt eine .env-Datei meinen API-Schlüssel in Expo?
Nicht allein. Eine Variable mit dem Präfix EXPO_PUBLIC_ ist für den App-Code gedacht und darf kein Server-Secret enthalten. Expo erklärt, dass diese Werte in das kompilierte JavaScript eingebettet werden und von den Nutzern der App gelesen werden können. Einen Schlüssel in eine .env-Datei zu verschieben, reicht also nicht, um ihn zu schützen.
Was ist der Unterschied zwischen einem öffentlichen und einem geheimen API-Schlüssel?
Ein öffentlicher Schlüssel ist dafür gedacht, mit der App ausgeliefert zu werden: Er identifiziert das Projekt, ersetzt aber keine Berechtigungen auf den Daten. Ein geheimer Schlüssel erlaubt privilegierte Aktionen und ist vertrauenswürdigen Umgebungen vorbehalten. Bei Supabase kann der publishable-Schlüssel oder der alte anon-Schlüssel in der App bleiben, wenn die Berechtigungen korrekt konfiguriert sind. Die Schlüssel secret und service_role bleiben auf dem Server.
Wie rufe ich eine KI-API aus einer Expo-App auf, ohne den Schlüssel offenzulegen?
Leite den Aufruf über deinen Server: Die App ruft den Server auf, der den Anbieter anfragt und die Antwort an die App zurückgibt. Der geheime Schlüssel bleibt auf dem Server. Der Server muss außerdem die Session prüfen, wiederholte Anfragen begrenzen und einen verständlichen Fehler zurückgeben, wenn der Anbieter nicht antwortet. Der Client entscheidet nicht selbst, ob ein Nutzer bezahlten Zugang hat.
Wie prüfe ich, dass jeder Nutzer nur seine eigenen Daten sieht?
Leg zwei Testkonten an, die du kontrollierst, mit je einer wiedererkennbaren Notiz. Versuch von Konto A aus, im Namen von Konto B zu lesen, zu ändern und zu erstellen, und dann die private Datei von B zu öffnen. Mach die Tests auch ohne Session: Jede Anfrage muss abgelehnt werden oder darf nichts preisgeben. Notier das tatsächliche Ergebnis, denn „die Regeln sind aktiviert“ ist kein Testergebnis.
Wie lasse ich die Schlüssel meiner App von einer KI prüfen?
Bitte sie, die Variablen des mobilen Codes und des Servers aufzulisten und dabei nur ihre Namen anzuzeigen, ohne deine geheimen Werte einzufügen. Bitte sie außerdem, privilegierte Aufrufe auf der Client-Seite zu identifizieren und einen Testablauf mit zwei Testkonten vorzuschlagen. Untersage jede Schlüsselrotation und jede Änderung an der Produktion ohne Freigabe. Ihre Antwort ersetzt nicht das Ausführen der Tests.