8 Min. Lesezeit

Tastenkombinationen zur Bestätigung, die Fehlauslösungen verhindern

Tastenkombinationen zur Bestätigung müssen auf Fokus, Timing, Wiederholungen und Terminaleingaben getestet werden, bevor sie eine Agentenaktion autorisieren können.

Tastenkombinationen zur Bestätigung, die Fehlauslösungen verhindern

Eine Tastatursteuerung zur Bestätigung gehört zur Autorisierungsgrenze. Sie ist kein Komfortmerkmal mit aufgesetztem Sicherheitslabel. Wenn eine gewöhnliche Terminal-Tasteneingabe trotz eines Fokuswechsels, eines gerade geöffneten modalen Dialogs oder einer Warteschlange wiederholter Eingaben einen Agentenaufruf bestätigen kann, hat die Steuerung keine Entscheidung erfasst. Sie hat den richtigen Zeitpunkt erwischt.

Dieser Fehler lässt sich leicht ausliefern, weil der normale Ablauf sich hervorragend anfühlt. Ein Entwickler löst eine Aktion aus, ein Bestätigungsfenster erscheint, die Eingabetaste bestätigt sie, und alle nennen die Interaktion schnell. Dann liest derselbe Entwickler Terminalausgabe, hält beim Fensterwechsel eine Zusatztaste gedrückt oder drückt die Eingabetaste, um einen fremden Dialog zu schließen. Die Bestätigung kommt im falschen Moment, und die Aktion erhält eine Zustimmung, die niemand bewusst gegeben hat.

Eine Tastenkombination zur Bestätigung ist eine Sicherheitsgrenze

Eine Bestätigung per Tastenkombination muss eine neue, zuordenbare Entscheidung über genau eine aktive Aktion darstellen. Dass der Benutzer die Tastatur besitzt oder der anfragende Prozess eine Anfrage stellen darf, macht nicht jedes Zeichen zu einer Bestätigung.

Teams legen regelmäßig drei verschiedene Tatsachen zusammen:

  • Ein Prozess darf eine Aktion anfordern.
  • Ein Mensch befindet sich am Rechner.
  • Dieser Mensch darf genau diese Aktion jetzt bestätigen.

Die erste Tatsache betrifft die Prozessidentität. Die zweite betrifft die Anwesenheit vor Ort. Die dritte ist die Autorisierung. Ein signierter Prozess kann die erste Tatsache zuverlässig belegen. Ein sichtbares Fenster kann auf die zweite hindeuten. Keine von beiden beweist die dritte.

Behandle die Bestätigungsoberfläche wie eine kleine Zustandsmaschine mit einem schmalen Eingang in den bestätigten Zustand. Sie muss wissen, welche Anfrage sie anzeigt, ob sie gerade Eingaben besitzt, wann sie für die Tastaturaktivierung bereit wurde und ob die Anfrage noch gültig ist. Sobald sich eine dieser Tatsachen ändert, muss der alte Weg zur Bestätigung ungültig werden.

Ein verbreiteter Implementierungsfehler bindet die Tastenkombination an einen allgemeinen Command-Handler und prüft nur, ob ein Bestätigungsfenster existiert. In einer Demo wirkt das harmlos. Im Alltag kann ein verspätet zugestelltes Ereignis dadurch eine andere Anfrage bestätigen, eine alte Anfrage nach einem Austausch oder ein Fenster, das gerade aus dem Hintergrund zurückgekehrt ist. Die Schaltfläche musste in dem Moment, in dem die Person die Taste drückte, nicht einmal sichtbar sein.

Die Lösung besteht nicht darin, alle Tastenkombinationen zu entfernen. Bestätigungen ausschließlich per Maus sind für Menschen, die sicher mit der Tastatur arbeiten, hinderlich und treiben sie zu hastigen Klicks. Stattdessen muss eine Tastaturaktivierung schwerer zu qualifizieren sein als ein Schaltflächentext. Das System darf sie nur akzeptieren, wenn der aktuelle Dialog, die aktuelle Anfrage, die aktuelle Fokusgeneration und der aktuelle physische Tastendruck zusammenpassen.

Dieser Unterschied verändert Code-Reviews. Frage: „Welches genaue Ereignis darf diese Grenze überschreiten?“ und nicht: „Klickt die Eingabetaste die Schaltfläche?“ Eine gute Antwort nennt die Ereignisquelle, den Fensterzustand, die Anfrage-ID und die Fälle, in denen die Eingabe abgelehnt wird. „Der Dialog ist geöffnet“ ist keine Antwort.

Fokus muss bewiesen werden, nicht vorausgesetzt

Ein Dialog sollte seine Berechtigung für Tastatureingaben jedes Mal verwerfen, wenn er den Fokus verliert, selbst wenn er einen Moment später wieder fokussiert ist. Bei Fokuswechseln werden Eingaben, die für eine Oberfläche bestimmt waren, häufig von einer anderen interpretiert.

Betrachte einen typischen Ablauf. Ein Agent führt in einem Terminal einen Befehl aus. Der Benutzer gibt einen Befehl ein, wechselt zur Dokumentation, und dann erscheint ein modales Autorisierungsfenster. Das Betriebssystem wechselt das aktive Fenster, während die Hände des Benutzers noch in Bewegung sind. Je nach Reihenfolge der Ereignisse und App-Framework kann ein Druck auf die Eingabetaste eintreffen, nachdem der Dialog den Fokus übernommen hat, obwohl die Absicht schon vor dem Erscheinen des Dialogs entstanden ist.

Die unsichere Regel ist einfach: Wenn die Autorisierungsschaltfläche die Standardschaltfläche ist und das Fenster im Vordergrund steht, akzeptiere die Eingabetaste. Diese Regel behandelt den Vordergrundstatus als Beweis dafür, dass die Person die Anfrage gesehen und geprüft hat. Er beweist nur, dass das Fenster beim Zustellen des Ereignisses vorne im Stapel stand.

Verwende stattdessen eine Fokusgeneration. Sobald der Dialog aktiv wird, erhöhst du einen Zähler und deaktivierst die Tastaturaktivierung. Akzeptiere eine passende Eingabe erst, nachdem die Anwendung festgestellt hat, dass sich der Fokus für die aktuelle Generation stabilisiert hat und ein neuer Tastendruck des Benutzers eintrifft. Beim Deaktivieren muss der aktivierte Zustand sofort gelöscht werden. Stelle ihn bei der Rückkehr des Fokus nicht automatisch wieder her.

Das ist bewusst konservativ. Wer weg- und zurückwechselt, muss die Tastenkombination nach der Rückkehr erneut drücken. Dieser zusätzliche Tastendruck ist günstig. Einen authentifizierten HTTP-Aufruf oder einen SSH-Befehl versehentlich abzusenden, ist es nicht.

Dieselbe Regel gilt, wenn das System ein anderes modales Blatt, eine Passwortabfrage, ein Bedienungshilfe-Overlay, eine Benachrichtigungsinteraktion oder einen Arbeitsbereichwechsel anzeigt. Deine Anwendung kann nicht wissen, warum der Fokus gewechselt hat, und sollte nicht raten. Sie kann wissen, dass ihre früheren Annahmen nicht mehr gelten.

Verlasse dich nicht ausschließlich auf sichtbare Fokusringe. Sie zeigen dem Benutzer, wohin die Eingabe scheinbar geht. Eine Autorisierungsentscheidung braucht jedoch einen Zustandswechsel, der das tatsächlich aktive Fenster der Anwendung und die aktuelle Generation des Dialogs prüft. Der sichtbare Zustand und der Autorisierungszustand sollten gemeinsam aus einer einzigen Quelle der Wahrheit geändert werden.

Ein nützlicher manueller Test sieht so aus: Öffne einen Bestätigungsdialog, halte eine Zusatztaste gedrückt, wechsle weg, kehre zurück und drücke sofort die Eingabetaste. Wiederhole den Test mit einem Klick außerhalb des Dialogs, einem Systemhinweis und einem schnellen Anwendungswechsel. Jeder Versuch sollte die Anfrage offenlassen, bis eine neue ausdrückliche Aktion erfolgt. Wenn auch nur eine Variante bestätigt, ist der Tastaturpfad zu weit gefasst.

Gehaltene Eingaben brauchen eine eigene Zustandsmaschine

Eine Taste, die schon gedrückt war, bevor der Dialog bereit wurde, darf den Dialog nicht autorisieren. Diese Regel deckt die Fehlerklasse ab, die entsteht, wenn jemand die Eingabetaste, die Leertaste, Escape oder eine Zusatztaste hält, während sich die Oberfläche darunter verändert.

Ereignis-APIs liefern oft Phasen für Drücken, Wiederholen und Loslassen. Anwendungscode reduziert sie jedoch gern auf „Eingabetaste empfangen“. Dabei gehen genau die Informationen verloren, die wichtig sind. Ein Tastendruck, der im Terminal begonnen hat, bedeutet etwas anderes als ein Tastendruck, der beginnt, nachdem die Bestätigungsanfrage sichtbar und fokussiert ist.

Verfolge den physischen Lebenszyklus jeder akzeptierten Tastenkombination. Der Dialog darf eine Tastenkombination nur akzeptieren, wenn er nach seiner eigenen Aktivierungsepoche ein neues Ereignis zum Drücken beobachtet, das keine Wiederholung ist, während er den Fokus besitzt, gefolgt von der Abschlussregel deiner Plattform. Wenn die Taste beim Öffnen des Dialogs bereits gedrückt ist, setze für diese Taste eine Sperre und warte auf das Loslassen. Leite aus einer Wiederholung niemals einen neuen Tastendruck ab.

Für die Leertaste gilt dieselbe Sorgfalt wie für die Eingabetaste. Viele Steuerelemente verwenden die Leertaste zur Tastaturaktivierung, und Menschen halten sie für Vorschauen, zum Scrollen oder für Bedienungshilfen gedrückt. Auch Escape muss genau geprüft werden. Die Taste darf nur die aktuelle Anfrage auf dem Bildschirm abbrechen und niemals eine Ersatzanfrage, die nach ihrem Tastendruck erschienen ist.

Kombinationen mit Zusatztasten brauchen eine strengere Regel. Behandle den bloßen Zustand einer Zusatztaste nicht als Berechtigung und vermeide Tastenkombinationen, die sich mit Terminalgewohnheiten wie Control-C, Control-D oder Control-R überschneiden. Wenn du eine Kombination auswählst, muss die vollständige Kombination beginnen, nachdem der Dialog aktiviert wurde. Sie muss abgelehnt werden, wenn sich der Fokus verändert hat, während ein Bestandteil gedrückt war. Eine Kombination, die in einem anderen Fenster beginnt, ist keine Entscheidung über deinen Dialog.

Eine kleine interne Aufzeichnung reicht aus:

requestId: 84f2
focusGeneration: 17
armedAfterEvent: 912
returnIsBlockedUntilUp: true
approvalState: pending

Die Namen spielen keine Rolle. Die Regel schon: Ein Ereignis muss neuer sein als die aktuelle Fokusgeneration des Dialogs und zu einem neuen Eingabezyklus gehören. Teams ergänzen diesen Zustand oft erst nach einem Bericht über eine versehentliche Bestätigung. Füge ihn ein, bevor du die Tastenkombination hinzufügst.

Das Timing modaler Dialoge macht normale Eingaben zur Autorisierung

Ein modaler Dialog, der im falschen Moment erscheint, kann Eingaben erhalten, die für die darunterliegende Aufgabe bestimmt waren. Die Gefahr entsteht durch das Timing der Ereignisse, nicht durch die Qualität des Bestätigungstextes.

Mehrere Zeitlücken verdienen eine eigene Bezeichnung. Eine Anfrage kann zwischen dem Drücken und dem Loslassen einer Taste eintreffen. Die Oberfläche kann gerendert werden, bevor der Anwendungszustand die Anfrage-ID vollständig übernommen hat. Eine vorherige Anfrage kann geschlossen werden, während ein wartender Callback noch ihren Abschluss-Handler enthält. Ein neuer Dialog kann dasselbe Schaltflächenobjekt wiederverwenden, sodass eine alte Tastaturaktion auf neue Inhalte zeigt.

Der bekannte Fehler sieht so aus:

  1. Der Benutzer drückt im Terminal die Eingabetaste, um einen Befehl abzusenden.
  2. Der Agentenprozess fragt nach einer Berechtigung, während der Tastendruck noch läuft.
  3. Die Anwendung zeigt einen Bestätigungsdialog an und aktiviert seine Standardschaltfläche.
  4. Das Loslassen der Taste oder ein wiederholtes Ereignis erreicht den neuen Responder.
  5. Die Anwendung behandelt dieses Ereignis als Bestätigung und sendet die Aktion.

Der Benutzer hat den Dialog möglicherweise nie gelesen. Trotzdem schreibt die Anwendung einen Audit-Eintrag, der besagt, der Benutzer habe zugestimmt. Dadurch wird der Fehler noch schlimmer. Der Eintrag beschreibt den Codepfad korrekt, aber die menschliche Handlung falsch.

Verhindere das mit einer Aktivierungsbarriere. Speichere beim Anzeigen eine monotone Eingabesequenz oder einen Zeitstempel aus dem Ereignissystem und lehne Ereignisse ab, die vor dieser Barriere begonnen haben. Wenn die Plattform keine zuverlässige Sequenz liefern kann, verlange einen vollständig neuen Tastendruck, nachdem der Dialog sichtbar aktiv ist. Wenn die Plattform Unsicherheit lässt, ist die konservative Gestaltung vorzuziehen.

Verwende neben Eingabegenerationen auch Anfragegenerationen. Binde jede Schaltflächenaktion und jeden Tastatur-Handler an ein unveränderliches Anfrage-Token. Wenn der Dialog geschlossen wird, widerrufe dieses Token. Wenn eine andere Anfrage ihn ersetzt, erstelle ein neues Token, statt das alte Objekt zu verändern. Ein Callback mit einem alten Token muss eine Ablehnung zurückgeben, selbst wenn zufällig ein neuer Dialog sichtbar ist.

Versuche nicht, das Timing allein mit einer Verzögerung wie „Eingabetaste 300 Millisekunden ignorieren“ zu lösen. Verzögerungen sind beliebt, weil sie leicht zu erklären und zu programmieren sind. Sie versagen auf langsamen Rechnern, bei schnellen Fokuswechseln, bei Eingaben über Bedienungshilfen und bei Menschen, die berechtigterweise länger brauchen. Eine Verzögerung misst Zeit. Du musst die Beziehung zwischen Eingabeereignis und aktuellem Dialogzustand messen.

Terminalgewohnheiten sind feindselige Eingaben

Eine Sitzung sofort widerrufen
Widerrufe einen Agentenlauf im Sitzungsjournal, sobald seine Autorisierung enden soll.

Die Arbeit im Terminal erzeugt genau die Tastendrücke, denen ein Bestätigungsdialog misstrauen muss. Entwickler drücken die Eingabetaste, um Befehle abzusenden, Control-C, um Arbeit zu stoppen, die Leertaste, um durch Ausgaben zu blättern, und Escape, um eine Bearbeitung abzubrechen. Agenten erhöhen die Häufigkeit von Terminalaktivität, sodass das Autorisierungsfenster neben einem Strom gewohnter Eingaben erscheint.

Gehe nicht davon aus, dass sich ein Terminal hinter einer eigenen Anwendungsgrenze befindet. Menschen verwenden eingebettete Terminals, geteilte Bereiche, Remote-Shells, Vollbildfenster und Werkzeugbereiche, die wie Terminals aussehen. Ein Prozess kann eine Autorisierungsanfrage auch direkt nachdem eine Ausgabe den Entwickler zum Drücken einer Taste aufgefordert hat auslösen. Die sichtbare Situation kann sich schneller ändern als der motorische Ablauf des Benutzers.

Die sichere Standardeinstellung ist, dass ein Bestätigungsdialog keine geerbte Eingabe übernimmt. Er darf einen neuen Druck der Eingabetaste nach Fokus und Aktivierung empfangen, muss aber die Eingabetaste ablehnen, mit der ein Shell-Befehl abgesendet wurde, die zum Blättern gehaltene Leertaste und jede Wiederholung einer dieser Tasten. Wenn die Oberfläche diesen Unterschied nicht feststellen kann, entferne die Tastenkombination und verlange eine Bestätigung per Maus oder Biometrie.

Binde eine riskante Bestätigung nicht in einer globalen Befehlszuordnung an terminalähnliche Befehle. Ein globaler Listener sieht Ereignisse außerhalb der lokalen Responder-Kette des Modals. Dadurch lässt sich schwer beweisen, wo eine Aktivierung begonnen hat. Halte den Handler am konkreten aktiven Dialog und verlange anschließend, dass der Dialog sein eigenes Anfrage-Token prüft, bevor er die Autorisierungsschicht zum Handeln auffordert.

Auch Kopieren und Einfügen verdienen hier Aufmerksamkeit. Ein eingefügter Zeilenumbruch kann in einem Terminal gewöhnlicher Text und in einem Formularelement eine Aktivierung sein. Bestätigungselemente sollten Texteingaben und Befehlsausführung ignorieren, wenn ihnen kein passendes physisches Tastaturereignis zugrunde liegt. Ein eingefügtes Zeichen ist Dateninhalt, keine Zustimmung.

Teste mit einem echten Terminalablauf, nicht nur mit einem künstlichen Fenster. Starte einen Befehl, der wiederholt Eingaben anfordert, löse während eines Drucks auf die Eingabetaste eine Anfrage aus und teste danach die Verwendung von Control-C und der Leertaste. Teste bei aktivem Terminal, bei aktivem Dokumentationsfenster und wenn das Autorisierungsfenster während eines Fensterwechsels erscheint. Entscheidend ist, eine Absicht nachzustellen, die an anderer Stelle begonnen hat.

Teste die Ereignishistorie, nicht die dargestellte Schaltfläche

Am nützlichsten sind Tests, die einer Reduzierfunktion eine feindselige Ereignishistorie geben und prüfen, dass sie erst bei genau der richtigen Folge eine Bestätigung ausgeben kann. Snapshot-Tests können bestätigen, dass ein Dialog fokussiert aussieht. Sie können nicht feststellen, ob ein veraltetes Ereignis die Grenze überschritten hat.

Modelliere den Dialog mit ausdrücklichen Ereignissen wie present, focusGained, focusLost, keyDown, keyRepeat, keyUp, requestRevoked und approveClick. Gib jedem Ereignis ein Anfrage-Token und eine monoton steigende Eingabesequenz. Der Reduzierer sollte eines von drei Ergebnissen erzeugen: offen bleiben, abbrechen oder eine Bestätigung für ein passendes Token ausgeben.

Dieses Fixture ist klein genug, um direkt neben dem Interaktionscode zu liegen:

[
  {"seq": 41, "type": "keyDown", "key": "Return"},
  {"seq": 42, "type": "present", "request": "r-19"},
  {"seq": 43, "type": "focusGained", "request": "r-19"},
  {"seq": 44, "type": "keyUp", "key": "Return"},
  {"seq": 45, "type": "keyDown", "key": "Return"},
  {"seq": 46, "type": "keyUp", "key": "Return"}
]

Die Form der erwarteten Ausgabe ist ebenso wichtig:

[
  {"seq": 44, "decision": "pending", "reason": "inherited-input"},
  {"seq": 46, "decision": "approved", "request": "r-19"}
]

Wenn deine Implementierung bei Sequenz 44 bestätigt, hat sie einen Tastendruck akzeptiert, der begann, bevor der Dialog existierte. Das ist der Fehler, ausgedrückt ohne Screenshot und ohne einen Race-Zustand, der nur einmal pro Woche auftritt.

Erstelle eine kompakte Testmatrix, die sich an Zustandsänderungen statt an Beschriftungen orientiert. Decke mindestens diese Fälle ab:

  • Eine Tastenkombination wird vor dem Anzeigen gedrückt und losgelassen, nachdem der Fokus angekommen ist.
  • Der Fokus verlässt das Fenster, nachdem ein neuer Tastendruck begonnen hat, und kehrt vor dem Loslassen zurück.
  • Ein Wiederholungsereignis trifft ein, während eine Anfrage offen bleibt.
  • Anfrage A wird geschlossen, Anfrage B geöffnet, und ein alter Handler wird ausgelöst.
  • Der Tresor oder eine andere Voraussetzung ändert seinen Zustand, nachdem der Dialog erschienen ist.

Prüfe in jedem Fall sowohl, dass keine Aktion gesendet wird, als auch, dass das Audit-Log je nach Design eine Ablehnung oder keine Entscheidung verzeichnet. Eine still ignorierte Eingabe kann in Ordnung sein. Ein Eintrag, der eine Bestätigung behauptet, obwohl der Reduzierer sie abgelehnt hat, ist es nicht.

Teste anschließend die Integration der Oberfläche, denn dort werden viele ansonsten gute Reduzierer umgangen. Prüfe, dass jeder Aktivierungsweg dasselbe Tor durchläuft: Mausklick, Eingabetaste, Leertaste, Bedienungshilfe-Aktion, programmatische Standardschaltflächenaktion und jeder Menübefehl. Ein separater Tastaturpfad, der die Aktion direkt aufruft, wird sich mit der Zeit vom Schaltflächenpfad entfernen.

Verwende in diesen Tests Dependency Injection für den Aktionsausführer. Der Test darf ein Aufrufobjekt erst erhalten, nachdem der Reduzierer eine Bestätigung für das aktuelle Token ausgegeben hat. Zähle die Aufrufe, erfasse das Anfrage-Token und lasse den Test fehlschlagen, wenn ein altes Token den Ausführer erreicht. Teste dies nicht mit einem echten HTTP-Aufruf oder SSH-Befehl. Die Autorisierungsgrenze muss ohne Anmeldedaten und Netzwerk testbar sein.

Manuelle Tests bleiben wichtig, weil Betriebssysteme Fokus- und Bedienungshilfeereignisse über Wege zustellen, die Mocks übersehen können. Halte ein kurzes Regressionsskript in einfacher Sprache fest, führe es auf dem ältesten unterstützten System und auf einem aktuellen System aus und verwende eine physische Tastatur. Nimm schnelle Fensterwechsel, gehaltene Tasten, wiederholte Tasten, Systemhinweise, Bildschirmsperre, das Aufwachen aus dem Ruhezustand und eine sichtbare Anfrage, die widerrufen wird, auf. Das Skript sollte nach jeder Aktion die erwartete Entscheidung nennen und nicht nur festhalten, dass sich der Dialog korrekt verhalten hat.

Ein abgelehntes Ereignis muss abgelehnt bleiben

Anmeldedaten hinter dem Gateway halten
HTTP-Aufrufe und SSH-Befehle laufen über Sallyport, ohne die Anmeldedaten dem Agenten offenzulegen.

Sobald ein Ereignis die Bestätigungsbedingung nicht erfüllt, dürfen spätere Änderungen an der Oberfläche es nicht nachträglich gültig machen. Das klingt offensichtlich, bis eine Implementierung ein allgemeines Flag wie „Bestätigung ausstehend“ speichert und es nach der Rückkehr des Fokus oder dem Ende einer Animation erneut prüft.

Mache die Ablehnung für dieses Ereignis endgültig. Wenn die Eingabetaste im deaktivierten Zustand eintrifft, verzeichne sie als geerbte Eingabe oder verwerfe sie und warte auf einen späteren neuen Tastendruck. Wenn sich der Fokus während einer Kombination ändert, mache diese Kombination ungültig. Wenn sich die Anfrage ändert, mache alle mit der vorherigen Anfrage verbundenen Ereignisse und Callbacks ungültig. Der Code darf eine mögliche Bestätigung nicht aufbewahren, falls sich die Bedingungen verbessern.

Dieses Prinzip schützt auch vor doppelten Aktionen. Ein Doppelklick, eine Tastaturaktion gefolgt von einer Mausaktion oder eine wiederholte Zustellung darf nicht zwei externe Aufrufe auslösen. Sobald die Autorisierungsschicht ein Bestätigungs-Token akzeptiert, muss sie die Anfrage vor dem Weiterleiten der Aktion als verbraucht markieren. Nachfolgende Aktivierungen für dieses Token sollten zu einer harmlosen Ablehnung wegen Doppelverwendung führen.

Trenne das Ergebnis der Oberfläche vom Ergebnis der externen Aktion. Die Oberfläche darf erst „für die Ausführung bestätigt“ anzeigen, nachdem sie den Entscheidungszustand geschlossen hat. Der Ausführer kann anschließend unabhängig davon erfolgreich sein oder scheitern. Wenn eine Netzwerkanfrage fehlschlägt, reaktiviere das alte Bestätigungs-Token nicht und wiederhole sie nicht stillschweigend bei einer späteren Tasteneingabe. Frage erneut, wenn der Benutzer einen weiteren Versuch autorisieren muss, besonders wenn sich Nutzlast oder Ziel geändert haben könnten.

Hier zahlt sich ein gutes Audit-Design aus. Protokolliere genug Kontext, um nachvollziehen zu können, dass eine Eingabe wegen Veraltung, Wiederholung, fehlendem Fokus, Widerruf oder bereits erfolgter Verwendung abgelehnt wurde. Mache das Log nicht zu einer Aufzeichnung jeder einzelnen Tasteneingabe. Du brauchst Belege für Entscheidungen, keine Überwachungsaufzeichnung.

Identität, Autorisierung und Umfang brauchen getrennte Antworten

Sehen, wer die Anfrage stellt
Sallyport zeigt vor der Bestätigung der Sitzung die Code-Signing-Autorität des anfragenden Prozesses.

Ein vertrauenswürdiger Bestätigungsablauf beantwortet, wer die Anfrage stellt, was diese Person oder dieser Prozess tun möchte und ob der Mensch genau diese Aktion bestätigt. Eine Antwort darf nicht als Ersatz für eine andere dienen.

Die Prozessidentität ist nützlich, weil sie dem Menschen ermöglicht zu entscheiden, ob der Anfragende erwartet wird. Unter macOS kann die Code-Signing-Autorität ein aussagekräftigeres Signal liefern als ein veränderlicher Prozessname. Doch auch ein erwarteter Prozess kann eine unerwartete Anfrage stellen, und ein Mensch kann durch eine falsche Tastenkombination weiterhin die falsche Anfrage bestätigen.

Der Umfang ist wieder etwas Eigenes. Eine Sitzungsberechtigung kann für risikoarme Arbeit angemessen sein, die ein Mensch geprüft hat. Sie macht jedoch nicht jeden künftigen Aufruf zu derselben Entscheidung. Eine Bestätigung pro Aktion hat einen anderen Zweck: Sie erzwingt eine neue Bewertung in dem Moment, in dem eine Aktion Anmeldedaten verwendet oder ein sensibles Ziel erreicht. Gestalte die Interaktion so, dass der Benutzer erkennen kann, welche Ebene er gerade ändert.

Vermeide ungenaue Beschriftungen wie „Erlauben“, wenn die Anfrage eine externe Wirkung hat. Nenne Methode, Ziel und die konkrete relevante Operation in einer Sprache, die der Bediener prüfen kann. Mache den Dialog aber auch nicht zu einem dichten Paketdump. Zeige zuerst die entscheidungsrelevanten Fakten und stelle genaue Details bereit, ohne die Bestätigung von einer Scrollübung abhängig zu machen.

Sallyport hält diese Ebenen bewusst eng gefasst: Ein gesperrter Tresor verweigert jede Aktion, ein neuer Agentenprozess fordert standardmäßig eine Sitzungsautorisierung an, und ausgewählte Anmeldedaten können für jede Verwendung eine neue Bestätigung verlangen. Dadurch wird die Tastaturinteraktion nicht automatisch sicher. Die Tastenkombination muss weiterhin beweisen, dass die aktuelle Person den aktuellen Aufruf bestätigt hat.

Erst ausliefern, wenn die Fehlerspur langweilig ist

Gib die Tastenkombination erst frei, wenn feindselige Eingaben zu gewöhnlichen, nachvollziehbaren Ablehnungen führen. Eine Person sollte die Eingabetaste während des Anzeigen des Dialogs gedrückt halten, mitten in einer Kombination das Fenster wechseln, eine wiederholte Leertaste auslösen oder mit einer Ersatzanfrage um die Wette laufen können, ohne einen externen Aufruf zu verursachen.

Lege das Test-Fixture in dasselbe Review wie die Änderung an der Oberfläche. Verlange, dass ein Reviewer die Ereignisfolge liest, die beweist, dass eine veraltete Taste die Grenze nicht überschreiten kann. Die Implementierung sollte eine einzige Autorisierungsfunktion bereitstellen, die Anfrageidentität, Fokusgeneration, Aktualität der Eingabe und Verbrauchszustand prüft. Komfort-Handler dürfen diese Funktion aufrufen, sie aber niemals umgehen.

Beobachte Produktionslogs auf Muster, die auf Reibung hindeuten, ohne die Bedingung zu lockern. Viele Ablehnungen geerbter Eingaben nach dem Erscheinen eines Modals können bedeuten, dass die Anfrage zu einem ungünstigen Zeitpunkt eintrifft. Verbessere, wann und wie die Anfrage angezeigt wird, oder biete eine Maus- und Biometrie-Route an. Behebe die Kennzahl nicht, indem du Eingaben akzeptierst, die das System zu Recht abgelehnt hat.

Eine gute Tastenkombination zur Bestätigung fühlt sich ereignislos an, nachdem eine Person die Anfrage angesehen hat. Nur diese Geschwindigkeit ist es wert, optimiert zu werden. Jeder andere schnelle Weg verwandelt lediglich Terminalgewohnheiten in Autorisierung.

FAQ

Sind Tastenkombinationen sicher, um Agentenaktionen zu bestätigen?

Eine Tastenkombination kann Reibung verringern, darf aber niemals allein deshalb autorisieren, weil eine vertraute Taste ankommt. Akzeptiere die Eingabe nur, wenn ein aktives, aktuelles Bestätigungsfenster eindeutig an eine bestimmte Anfrage gebunden ist.

Was sollte passieren, wenn ein Bestätigungsdialog den Fokus verliert?

Die sicherste Standardeinstellung ist, die Bestätigung zu verwerfen. Wenn der Fokus weg und wieder zurück wechselt, sollte das Fenster eine neue, bewusste Aktion verlangen, statt anzunehmen, dass die alte Tastenkombination noch gemeint ist.

Kann eine gehaltene Eingabetaste einen modalen Dialog bestätigen?

Lass eine Taste, die schon vor dem Öffnen des Dialogs gedrückt wurde, nichts bestätigen. Akzeptiere eine Tastaturaktion erst, nachdem das System einen neuen Tastendruck und das Loslassen beobachtet hat, während das aktuelle Fenster den Fokus besitzt.

Soll die Tastenwiederholung eine Bestätigungsschaltfläche auslösen?

Nein. Ein wiederholtes Tastenereignis zeigt, dass jemand eine Taste gedrückt hält, nicht dass eine neue Autorisierungsentscheidung getroffen wird. Wiederholungen sollten bei Bestätigungselementen wirkungslos bleiben.

Welche Eingabe gilt als bewusste Bestätigung?

Verwende einen Mausklick, Touch ID oder einen neuen Tastendruck, der erst beginnt, nachdem der aktuelle Bestätigungsbildschirm aktiv geworden ist. Das Ereignis muss außerdem zur Anfrage passen, die noch auf dem Bildschirm steht.

Warum ist die Eingabetaste im Umfeld von Terminal-Agenten riskant?

Terminals gewöhnen Menschen daran, die Eingabetaste schnell und häufig zu drücken. Wenn ein Dialog erscheint, während ein Agent Ausgabe schreibt oder auf einen Befehl wartet, kann diese Gewohnheit eine fremde Tasteneingabe in Zustimmung verwandeln.

Was sollte ein Audit-Log für Bestätigungen enthalten?

Protokolliere die Anfrage-ID, die Dialoggeneration, den Fokusstatus, die Eingabequelle und die Entscheidung. Zeichne das konkrete Zeichen nicht auf, wenn dadurch unnötig sensible Daten im Audit-Log landen würden.

Wie teste ich Bestätigungsdialoge auf Race Conditions?

Beginne mit einem kleinen deterministischen Modell des Dialogs und speise feindselige Ereignisfolgen ein: Fokusverlust, erneutes Öffnen, gehaltene Tasten, Wiederholungen, wartende Ereignisse und veraltete Callbacks. Screenshot-Tests allein finden diese Fehlerklasse nicht.

Macht Code Signing die Bestätigung per Tastenkombination sicher?

Nein. Die Signatur beantwortet, welcher Prozess die Anfrage gestellt hat. Sie beweist nicht, dass die Person an der Tastatur genau diese Aktion bestätigen wollte. Halte diese Entscheidungen getrennt.

Soll eine Bestätigung per Tastenkombination funktionieren, wenn ein Anmeldedatentresor gesperrt ist?

Ein gesperrter Tresor sollte die Aktion ablehnen, bevor eine Tastenkombination überhaupt Wirkung hat. Die Bestätigung ergänzt eine ansonsten zulässige Aktion um menschliche Zustimmung, sie darf die Tresorsperre nicht umgehen.

Sallyport

Sallyport führt API-Aufrufe und SSH-Befehle für Ihren KI-Agenten aus. Die Schlüssel bleiben in einem lokalen Tresor auf Ihrem Mac; Sie geben jeden Lauf frei, und jede Aktion landet in einem versiegelten Journal.

© 2026 Sallyport · Open Source unter Apache-2.0 · Oleg Sotnikov