Das Problem mit API-Schlüsseln, die nie ablaufen
Ein Schlüssel, der vor Jahren ausgestellt, nie rotiert wurde und heute noch gültig ist, ist keine Bequemlichkeit. Er ist ein Risiko, das sich seit Jahren niemand mehr angesehen hat.
Ein Kontingent auf Kontoebene beantwortet eine einfache Frage: Wie viel hat dieser bestimmte Schlüssel verbraucht? Das ist naheliegenderweise das Erste, was man erfasst, und es reicht allein nicht aus, denn ein Schlüssel ist nur eine Zugangsberechtigung, und Zugangsberechtigungen lassen sich vervielfachen. Wer entschlossen ist, ein Limit auf Kontoebene zu überschreiten, kann oft einfach ein weiteres Konto anlegen, einen weiteren Schlüssel erzeugen und mit einem frischen Kontingent beginnen, es sei denn, etwas anderes erfasst eine Dimension, die sich nicht zurücksetzt, nur weil eine neue Zugangsberechtigung ausgestellt wurde.
Genau dafür gibt es Kontingente auf Netzwerkebene. Jedes Netzwerk, ein /24-Block bei IPv4-Adressen oder ein /48-Block bei IPv6, erhält ein gemeinsames kostenloses Kontingent von 2.500 Anfragen pro Tag, gezählt über den Traffic ohne Schlüssel und alle Schlüssel, die aus diesem Netzwerk registriert wurden. Ein Limit nur auf Kontoebene würde es jemandem erlauben, beliebig viele neue Schlüssel zu erzeugen und so sein kostenloses Kontingent immer wieder zurückzusetzen. Ein Limit auf Netzwerkebene schließt genau diese Lücke, weil es erfasst, woher der Traffic tatsächlich kommt, und nicht nur, welche Zugangsberechtigung zufällig daran hing.
Keines der beiden Maße reicht allein aus, und es lohnt sich, genau zu benennen, wovor jedes schützt, denn sie lösen unterschiedliche Probleme. Die Erfassung auf Kontoebene schützt davor, dass eine einzelne Zugangsberechtigung weit über das hinaus genutzt wird, was vorgesehen ist. Das ist wichtig für eine korrekte Abrechnung und um einen geleakten Schlüssel zu erkennen, der irgendwo verwendet wird, wo er nicht hingehört. Die Erfassung auf Netzwerkebene schützt davor, dass gezielt das kostenlose Kontingent durch wiederholte Registrierungen vervielfacht wird. Das ist ein anderer Fehlermodus, den die Erfassung auf Kontoebene allein nicht sehen kann, da jedes neue Konto für sich betrachtet völlig normal aussieht.
Beides gleichzeitig zu betreiben, bringt durchaus eine berechtigte Komplikation mit sich: Mehrere echte Nutzer, die sich ein Netzwerk teilen, etwa ein Unternehmen hinter einer kleinen Zahl öffentlicher IP-Adressen, könnten theoretisch an eine Obergrenze auf Netzwerkebene stoßen, die nichts mit der tatsächlichen Nutzung eines einzelnen Nutzers zu tun hat. Wir lösen das mit rollierenden IP-Plätzen, einer festen Anzahl unterschiedlicher Adressen, von denen aus ein Schlüssel genutzt werden kann, und mit Kontingent-Headern, die genau zeigen, wie viele dieser Plätze im Verhältnis zum Limit belegt sind. So kann ein legitimes geteiltes Netzwerk seinen echten Stand sehen, statt ohne Erklärung gegen eine undurchsichtige Wand zu laufen.
Wir halten dies für einen Fall, in dem das einfachere Design, also nur eine Dimension zu erfassen, für ehrliche Nutzer tatsächlich schlechter wäre und nicht nur weniger Schutz vor Missbrauch böte. Ein reines Netzwerklimit würde ein Konto für andere, nicht damit zusammenhängende Aktivitäten im selben Netzwerk bestrafen. Ein reines Kontolimit würde das kostenlose Kontingent für jeden offen lassen, der bereit ist, genügend Konten anzulegen, um es beliebig zu vervielfachen. Beides zu betreiben, mit Einblick in jedes über Response-Header, bedeutet mehr bewegliche Teile, aber es ist die Variante, die tatsächlich schützt, was ein kostenloses Kontingent schützen soll, ohne stillschweigend die Menschen zu bestrafen, die es wie vorgesehen nutzen.