Zum Hauptinhalt springen
EngineeringSicherheitAPI
Non-Custodial-Trading gestalten: API-Schlüssel-Berechtigungen und warum wir Auszahlungen nie anfassen

Non-Custodial-Trading gestalten: API-Schlüssel-Berechtigungen und warum wir Auszahlungen nie anfassen

„Non-Custodial" ist meist ein Marketingbegriff. Präzise verwendet, ist es eine architektonische Einschränkung, und Einschränkungen dieser Art sind interessant, weil sie Arbeit streichen, statt sie hinzuzufügen.

Ein Trading-Bot muss in Ihrem Namen Orders platzieren. Börsen ermöglichen das über API-Schlüssel, und API-Schlüssel tragen Berechtigungen: Lesen, Handeln und, bei den meisten Börsen, Auszahlen. Die Designfrage lautet also nicht, ob man Berechtigungen anfordert. Sie lautet, welche, und was zu tun ist, wenn man mehr bekommt, als man angefordert hat.

Das Wichtigste

  • Ein Versprechen, eine Berechtigung nicht zu nutzen, ist schwächer als sie gar nicht zu besitzen. Wir lehnen Schlüssel mit Auszahlungsberechtigung ab, statt sie anzunehmen und zu ignorieren.
  • Ablehnen ist eine stärkere Garantie als Vertrauen, weil es nicht davon abhängt, dass unser Code korrekt oder unser Team ehrlich ist.
  • Wenn ein Verbindungsablauf in das Konto des Nutzers schreibt, müssen diese Schreibvorgänge nach der Entscheidung zur Annahme erfolgen, nicht davor. Sonst ändern Sie jemandes Einstellungen auf dem Weg dazu, ihm abzusagen.
  • Keine Gelder zu verwahren streicht eine ganze Klasse schwieriger Probleme: kein Verwahrungsbuch, kein Abgleich, keine Auszahlungswarteschlange.
  • Was an seine Stelle tritt, ist enger und schärfer: Ihr System muss in Echtzeit korrekt sein, weil es niemals etwas rückgängig machen kann.

1. Eine Berechtigung abzulehnen schlägt das Versprechen, sie nicht zu nutzen

Die naheliegende Umsetzung besteht darin, Nutzer nach einem Schlüssel mit Lese- und Handelsberechtigung zu fragen und die Auszahlungs-Endpunkte einfach nie aufzurufen. Der Großteil der Branche macht das, und es ist nicht unvernünftig.

Wir gehen strenger vor. Trifft ein Schlüssel mit Auszahlungsberechtigung ein, wird er abgelehnt. Der Nutzer sieht eine Meldung, die ihm genau sagt, was zu tun ist:

Dieser API-Schlüssel hat die Auszahlungsberechtigung aktiviert. Freya zahlt niemals Gelder aus, daher werden Schlüssel mit dieser Berechtigung nicht akzeptiert. Bitte erstellen Sie einen Schlüssel nur mit Lese- und Handelsberechtigung.

Dieselbe Regel gilt auf allen drei von uns unterstützten Börsen. Es gibt keine Ausnahmeregelung und keine Admin-Ausnahme.

Zunächst wirkt das wie Reibung um ihrer selbst willen. Der Schlüssel würde funktionieren. Der Nutzer hat sich Mühe gegeben, ihn zu erstellen. Ihn abzulehnen bedeutet, ihn zur Börse zurückzuschicken, um einen neuen anzulegen.

Der Grund ist, dass die beiden Designs unterschiedliche Versprechen geben, und der Unterschied wird erst an Ihrem schlimmsten Tag sichtbar.

  • „Wir rufen Auszahlungs-Endpunkte niemals auf" ist eine Aussage über unser Verhalten. Sie gilt, solange unser Code korrekt ist, unsere Abhängigkeiten sauber sind und alle mit Deploy-Zugriff ehrlich bleiben. Das sind vernünftige Erwartungen. Es sind keine Dinge, die ein Nutzer überprüfen kann.
  • „Der Schlüssel kann nicht auszahlen" ist eine Aussage über den Schlüssel. Sie gilt unabhängig davon, was unser Code tut, weil die Börse sie durchsetzt, und der Nutzer kann sie selbst in seinen eigenen Börseneinstellungen bestätigen.

Das zweite ist eine schwächere Anforderung und eine stärkere Garantie. Bevorzugen Sie Designs, deren Sicherheitseigenschaft von jemand anderem als Ihnen durchgesetzt wird, besonders wenn der Nutzer keine Möglichkeit hat, Ihre Seite zu prüfen.

Es gibt einen kleineren Vorteil, der in der Praxis zählt: Er macht den Fehlerfall laut. Ein Schlüssel mit zu vielen Berechtigungen wird zum Zeitpunkt der Verbindung abgefangen, vor den Augen eines Nutzers, der gerade alles einrichtet und es in einer Minute beheben kann. Die Alternative ist, dass der überberechtigte Schlüssel dort liegt und einwandfrei funktioniert, und niemand etwas erfährt, bis es darauf ankommt.

2. Sagen Sie Nein, bevor Sie irgendetwas anfassen

Das ist das Detail, das ich einem anderen Entwickler am ehesten mitgeben möchte, weil man es leicht falsch macht und es dann fast unsichtbar ist.

Eine Börse zu verbinden ist keine reine Leseoperation. Je nach Börse kann es Schreibvorgänge erfordern, ein Konto in einen nutzbaren Zustand zu bringen: Anpassen eines Kontomodus, Setzen eines Positionsmodus und so weiter. Das sind legitime Schritte, die zur Einrichtung gehören.

Betrachten Sie nun die Reihenfolge. Wenn die Berechtigungsprüfung nach diesen Schreibvorgängen erfolgt, hinterlässt ein abgelehnter Schlüssel dennoch Spuren. Der Nutzer hat Ihnen eine Anmeldeinformation übergeben, Sie haben Einstellungen in seinem Konto verändert, und dann haben Sie ihm abgesagt. Aus seiner Sicht erklärt nichts, warum seine Börsenkonfiguration anders ist, als er sie hinterlassen hat.

Deshalb die Regel, auf die wir uns festgelegt haben: Eine abgelehnte Anmeldeinformation muss das Konto des Nutzers genau so hinterlassen, wie sie es vorgefunden hat. Jeder Schritt, der schreibt, gehört hinter die Entscheidung zur Annahme, niemals davor. Die Ablehnung muss ohne Nebenwirkungen erreichbar sein.

Verallgemeinert ist das einfach transaktionales Denken, angewendet auf das System eines anderen. Sie können einen Schreibvorgang in ein Drittkonto nicht rückgängig machen, daher ist die Reihenfolge Ihr einziger Schutz. Wenn Sie nichts rückgängig machen können, ordnen Sie die Schritte sorgfältig an.

Eine Implementierungsnotiz, die uns vor einer ganzen Kategorie von Bugs bewahrt hat: Die Ablehnung wird als ungültiges Ergebnis ausgedrückt statt als spezielles Flag, sodass jeder Pfad, der ein Validierungsergebnis verarbeitet, sie behandelt, ohne von ihrer Existenz wissen zu müssen. Wir haben zwei Verbindungsabläufe, und beide erben dieselbe Ablehnung, weil keiner von beiden daran denken musste, danach zu fragen. Eine Regel in einem Typ zu kodieren, den alle Konsumenten ohnehin lesen, schlägt es, sie zu dokumentieren und zu hoffen.

3. Was die Einschränkung streicht

Hier wird der Handel eindeutig vorteilhaft.

Gelder verlassen niemals das Börsenkonto des Nutzers. Bots handeln mit Lese-und-Handel-Schlüsseln, und das Guthaben bleibt dort, wo es begonnen hat. Daraus folgt eine lange Liste von Dingen, die es in unserem System schlicht nicht gibt:

  • Kein Verwahrungsbuch, also kein Abgleich zwischen einem internen und einem externen Guthaben
  • Keine Auszahlungswarteschlange, kein Genehmigungsworkflow, keine Tageslimits für Handelskapital
  • Keine Aufteilung in Hot- und Cold-Wallet für dieses Kapital und kein Schlüsselmanagement darum herum
  • Keine Frage, was mit Nutzergeldern geschieht, wenn das Unternehmen verschwindet

Jedes davon ist ein ganzes Subsystem in einem verwahrenden Produkt, und jedes ist ein Ort, an dem Geld verloren gehen kann. Sie fehlen hier nicht, weil wir sie gelöst haben, sondern weil wir das, was sie erzeugt, nie übernommen haben.

Ich möchte allerdings präzise statt pauschal sein: Das gilt für Handelskapital. Plattform-Guthaben, die für Abonnements verwendet werden, sind eine eigene Angelegenheit mit eigener Handhabung. Die Non-Custodial-Eigenschaft betrifft das Geld, das handelt, und das ist das Geld, auf das es am meisten ankommt.

4. Was sie nicht behebt

Eine Einschränkung, die Probleme beseitigt, beseitigt auch die Werkzeuge, mit denen Sie Fehler beheben würden, und es lohnt sich, dabei ehrlich zu sein.

Trades sind endgültig. Mit Verwahrung lässt sich eine interne Überweisung im Prinzip rückgängig machen. Eine Order, die auf dem Börsenkonto eines anderen ausgeführt wurde, nicht. Das gesamte technische Gewicht verlagert sich darauf, korrekt zu sein, bevor die Anfrage abgeht, statt danach abzugleichen, wenn sie angekommen ist. Das ist eine härtere Disziplin, als es klingt, und deshalb dreht sich so viel unserer Arbeit um Validierung, Präzision und Idempotenz.

Handelsberechtigung ist immer noch echte Berechtigung. Ein geleakter Lese-und-Handel-Schlüssel kann ein Konto nicht an eine externe Adresse leeren, was das Ergebnis ist, das Menschen tatsächlich fürchten. Aber er kann Orders platzieren. Der Wirkungsradius ist begrenzt, nicht null, und es wäre unehrlich, ihn als null zu beschreiben.

Der Nutzer trägt weiterhin Verpflichtungen. Schlüsselrotation, Schlüssel nicht über Dienste hinweg wiederzuverwenden und im Blick zu behalten, was sonst noch Zugriff auf dasselbe Konto hat, bleiben seine Sache. Unsere Architektur begrenzt den Schaden; sie macht den Schlüssel nicht harmlos.

Was ich einem anderen Team sagen würde

  • Fordern Sie die engste Berechtigung an und prüfen Sie dann, dass Sie sie bekommen haben. Weniger anzufordern ist nicht dasselbe wie weniger zu erhalten.
  • Bevorzugen Sie Garantien, die außerhalb Ihres eigenen Codes durchgesetzt werden, besonders solche, die der Nutzer überprüfen kann, ohne Ihnen zu vertrauen.
  • Machen Sie die Ablehnung nebenwirkungsfrei. Wenn Ihr Ablauf in ein Drittkonto schreibt, gehört alles, was schreibt, hinter die Entscheidung zur Annahme.
  • Kodieren Sie die Regel dort, wo Konsumenten ohnehin hinschauen. Eine Regel, die in einem gemeinsam genutzten Typ ausgedrückt ist, muss nicht von jedem Aufrufer erinnert werden.

Der übergeordnete Punkt ist, dass „wir werden X nicht tun" und „wir können X nicht tun" auf einer Landingpage ähnlich klingen und in einem Vorfall völlig verschieden sind. Wann immer Sie ein Versprechen von der ersten Kategorie in die zweite verschieben können, sind die Kosten meist gering und der Nutzen zeigt sich genau dann, wenn alles andere schiefgeht.


Weiterführende Lektüre

Bereit, Ihren Handel zu automatisieren?

Starten Sie Ihre Reise mit Freya Finance und lassen Sie KI-gestützte Bots für Sie arbeiten.

Kostenlos starten
Dieser Inhalt dient nur zu Bildungszwecken und stellt keine Finanzberatung dar. Der Handel mit Kryptowährungen birgt erhebliche Risiken. Investieren Sie nie mehr, als Sie sich leisten können zu verlieren.