API-Schlüssel und OAuth lösen verschiedene Probleme, und die Wahl beginnt mit einer einzigen Frage: Ist eine dritte Partei im Spiel?
Ruft Ihr Server eine fremde Schnittstelle im eigenen Namen auf, brauchen Sie einen Schlüssel. Ruft eine fremde Anwendung Ihre Schnittstelle im Namen Ihres Nutzers auf, brauchen Sie OAuth. Fehlt die dritte Partei, fügt OAuth Zeremonie hinzu, aber keine Sicherheit.
Im Folgenden: worin sie sich tatsächlich unterscheiden, was sich in den letzten Jahren an OAuth geändert hat, und eine Eigenschaft von API-Schlüsseln, über die kaum jemand schreibt — obwohl sie bestimmt, wie Sie im Betrieb mit ihnen leben.
Der API-Schlüssel: eine Zeichenkette, die sagt „dieses Programm darf"
Ein Schlüssel ist eine lange Zufallszeichenkette, die Sie in einen Anfrage-Header legen:
X-Api-Key: lix_live_9f2c...
Der Server findet den Schlüssel, ermittelt das zugehörige Konto und lässt die Anfrage durch. Mehr ist der Mechanismus nicht.
Daraus folgen seine Eigenschaften:
- ein Schlüssel läuft nicht von selbst ab. Er gilt, bis ihn jemand widerruft;
- ein Schlüssel weist ein Programm aus, keine Person. Wer im Team den Aufruf abgesetzt hat, bleibt meist unsichtbar;
- ein Schlüssel erlaubt alles, was das Konto kann, sofern Sie die Rechte nicht gesondert einschränken;
- der Schlüssel ist das einzige Geheimnis. Ist er abgeflossen, ist der Zugang abgeflossen — Zwischenstufen gibt es nicht.
OAuth: ein Protokoll über Einwilligung
OAuth 2.0 (RFC 6749) beantwortet eine andere Frage. Es kennt vier Beteiligte: den Eigentümer der Daten, die Anwendung, die sie haben möchte, einen Autorisierungsserver und den Server mit den Daten.
Der Ablauf sieht ungefähr so aus. Die Anwendung schickt die Person auf die Seite des Dienstes selbst. Dort sieht sie, wer worum bittet, und stimmt zu. Die Anwendung erhält einen Code, tauscht ihn gegen ein Access Token und ruft damit die Schnittstelle auf. Das Token lebt kurz — Minuten bis Stunden; läuft es ab, tauscht die Anwendung ein Refresh Token gegen ein neues.
Was das bringt und ein Schlüssel prinzipiell nicht leisten kann:
- das Passwort der Person erreicht die Anwendung nie. Darin liegt der ganze Sinn;
- Rechte zerfallen in Scopes. „Links lesen" und „Links löschen" sind getrennte Erlaubnisse;
- die Einwilligung ist sichtbar und widerrufbar. Der Nutzer sieht eine Liste verbundener Anwendungen und kann eine davon trennen, ohne die übrigen anzurühren;
- Tokens verfallen von selbst. Ein gestohlenes Access Token ist eine Stunde später wertlos.
Der Preis ist Aufwand: ein Autorisierungsserver, Registrierung der Anwendungen, ein Einwilligungsdialog, Ablage und Rotation der Refresh Tokens sowie der Umgang mit Ablauf bei jedem Aufruf.
Vergleich entlang der Achsen, die wirklich entscheiden
| API-Schlüssel | OAuth 2.0 | |
|---|---|---|
| Wen es ausweist | das Programm | den Nutzer, für den das Programm handelt |
| Lebensdauer | unbefristet | Access Token: Minuten bis Stunden |
| Wie der Zugang endet | Schlüssel widerrufen | Einwilligung oder Token widerrufen |
| Umfang der Rechte | in der Regel das ganze Konto | Scopes je Aktion |
| Geheimnis bei der dritten Partei | der Schlüssel selbst | nur Tokens, nie das Passwort |
| Integrationsaufwand | ein Header | Autorisierungsserver und voller Zyklus |
| Passt zu | Server-zu-Server, Skripte, interne Integrationen | öffentliche Apps, Marktplätze, „Anmelden mit …" |
Die Entscheidungsregel
Die Frage lautet nicht, was abstrakt sicherer ist, sondern wer wem Zugriff überträgt.
Ihr Server → fremde Schnittstelle, Ihr eigenes Konto
→ API-Schlüssel
Fremde App → Ihre Schnittstelle, Konto Ihres Nutzers
→ OAuth
Geplanter Job, CI, Backend-Integration
→ API-Schlüssel
Nutzer muss Zugriff je Anwendung sehen und widerrufen
→ OAuth
Der Empfang von Postbacks ist der Lehrbuchfall für einen Schlüssel. Wenn Ihr Server dem unseren meldet, dass eine Bestellung bezahlt wurde, ist an diesem Austausch keine Person beteiligt, es gibt niemanden, der einwilligen könnte, und keinen Ort für einen Einwilligungsdialog. Dasselbe gilt für Webhooks in der Gegenrichtung.
Was sich an OAuth geändert hat, während Sie wegsahen
Die Hälfte der Texte zum Thema beschreibt OAuth im Stand von 2015. Seither ist es deutlich enger geworden.
Im Januar 2025 veröffentlichte die IETF RFC 9700, Best Current Practice for OAuth 2.0 Security. Das Dokument bündelt jahrelange Erfahrung mit realen Angriffen und erklärt zwei Verfahren, die früher als vertretbar galten, förmlich für überholt:
- den Implicit Grant — jenen, der das Token direkt in der Adresszeile zurückgab;
- Resource Owner Password Credentials — wobei die Anwendung Benutzernamen und Passwort direkt abfragte. Genau das, was OAuth abschaffen sollte.
Gleichzeitig wurde PKCE für alle Clienttypen verbindlich, auch für serverseitige, und nicht mehr nur für mobile.
Gesondert zu wissen: OAuth 2.1 ist bis heute ein Entwurf, kein veröffentlichter RFC. Es fasst dieselben Änderungen in einem Dokument zusammen — verbindliches PKCE, exakter Abgleich der Redirect-URI, kein Implicit- und kein Password-Grant, keine Tokens in der Query-Zeichenkette. Es als geltenden Standard zu zitieren, ist verfrüht.
Praktische Folgerung: Empfiehlt eine OAuth-Anleitung den Implicit Flow, ist die Anleitung veraltet.
Die Schwachstelle der Schlüssel, von der selten die Rede ist
Ein Schlüssel läuft nicht ab. Damit ist der Widerruf Ihr einziger Hebel. Und hier wird es unangenehm: der Widerruf wirkt meist nicht sofort.
Den Schlüssel bei jeder Anfrage zu prüfen heißt, jedes Mal in die Datenbank zu gehen. Bei jeder Schnittstelle mit echtem Verkehr wird dieses Ergebnis zwischengespeichert. Bei uns liegt die Zuordnung von Schlüssel zu Konto fünf Minuten im Cache. Zwischen dem Klick auf „widerrufen" und dem tatsächlichen Ende des Zugriffs vergehen also bis zu fünf Minuten, in denen ein kompromittierter Schlüssel weiterarbeitet.
Das ist kein Versehen, sondern ein Tausch: Ohne Cache klopft jede Anfrage an die Datenbank. Nahezu jede schlüsselbasierte Schnittstelle geht einen ähnlichen Handel ein, nur wird darüber selten laut gesprochen. Wichtig ist es aus zwei Gründen. Erstens ist der Widerruf bei einem echten Leck die erste Handlung, nicht die letzte: Danach gehört geprüft, was in diesen Minuten geschah. Zweitens ist es genau das Problem, das die kurzlebigen Tokens von OAuth von der anderen Seite angehen — sie verfallen von allein, ohne Zutun einer Datenbank.
Mit Schlüsseln leben, ohne Schaden zu nehmen
Wenn Schlüssel genügen — und für die meisten Integrationen genügen sie —, sieht das Minimum so aus:
- Nur den Hash speichern. Der Server vergleicht den Hash des übergebenen Schlüssels mit dem hinterlegten; die ursprüngliche Zeichenkette wird genau einmal bei der Erstellung angezeigt. Wir gleichen per SHA-256 ab.
- Dem Schlüssel ein Präfix geben. Eine Zeichenkette der Form
lix_live_...erkennen Secret-Scanner in Repositorien und Logpipelines. - Je Integration ein eigener Schlüssel. Dann reißt ein Widerruf nicht die übrigen mit, und das Protokoll zeigt, was genau kompromittiert wurde.
- Niemals den Schlüssel in die Query-Zeichenkette legen. Adressen landen in Webserver-Logs, im
Referer-Header und im Browserverlauf. Nur der Header. - Nach Plan rotieren, nicht nach Vorfall. Ein Schlüssel, der einmal rotiert wurde, rotiert schnell. Einer, der es nie wurde, steckt am Ende an vier Stellen fest verdrahtet.
- Den Zeitpunkt der letzten Nutzung beobachten. Ein Schlüssel, den ein halbes Jahr niemand angefasst hat, ist keine Reserve, sondern eine offene Tür.
Was wir einsetzen
Die Lix.li-Schnittstelle authentifiziert über Schlüssel: Header X-Api-Key, Anlage und Widerruf im Dashboard, Abgleich per Hash, ein eigenes Anfragelimit je Schlüssel. OAuth gibt es nicht, und zwar bewusst: Die Anwendungsfälle liegen auf der Serverseite — einen Link anlegen, Statistiken abholen, eine Conversion entgegennehmen — und in keinem davon steht eine dritte Partei, der ein Nutzer zustimmen müsste.
Käme die Aufgabe hinzu, fremde Anwendungen in die Konten unserer Kunden zu lassen, würden Schlüssel nicht mehr reichen: Der Nutzer muss sehen können, wem er was erlaubt hat, und eine einzelne Anwendung trennen können, ohne die übrigen zu zerstören. Genau dort hört OAuth auf, Zeremonie zu sein, und wird zur einzigen ehrlichen Möglichkeit.
Die Aufrufe selbst stehen in der API-Dokumentation, einschließlich der Antwortcodes für einen ungültigen und für einen widerrufenen Schlüssel. Aus einem benachbarten Thema lohnt die Aufschlüsselung, warum eine 301-Weiterleitung aus einem POST ein GET macht, für alle, die Postbacks einrichten: Eine authentifizierte Anfrage kann mit einer anderen Methode ankommen, als sie losgeschickt wurde.