So sichern wir Figmas interne Systeme mit Agenten


Unser Sicherheitsteam hat einen KI-Agenten entwickelt, der Warnungen priorisiert, forensische Untersuchungen durchführt, unseren Sicherheitsdatenbestand abfragt, zum Beheben von Problemen codet – und sich merkt, was er lernt. Erfahre, wie wir die Zeit bis zur Behebung von Warnungen um 71 % verkürzen und die Abläufe für unser Bereitschaftsdienstteam grundlegend verändern konnten.
So sichern wir Figmas interne Systeme mit Agenten teilen
Illustrationen von Jimmy Simpson
Beim Schutz unserer internen Plattformen müssen wir berücksichtigen, dass sich die Bedrohungen, die unser Sicherheitsteam von Figma abwehren muss, ständig verändern. Die Cloud-Infrastruktur ändert sich häufig, Entwicklungsteams führen neue Tools ein und unsere Mitarbeiter*innen installieren und nutzen auf ihren Laptops jedes Quartal andere Apps und Tools (z. B. weil das Designer Advocate-Team jetzt auch eigene Apps und Automatisierungen entwickelt).
Durch unser SIEM, Panther, sind wir all diesen Bedrohungen einen Schritt voraus. Dazu führt die Plattform in unserer Cloud-Infrastruktur, unseren Endpunkten, SaaS-Apps und Identitätssystemen eine Vielzahl von Überprüfungen durch. Wenn ein potenzielles Problem erkannt wird, sendet die Plattform Warnungen in Slack und erstellt ein Asana-Ticket für das Bereitschaftsdienstteam. In der Vergangenheit bedeutete das eine enorme Menge an manueller Arbeit für das Team. Die größte Herausforderung war dabei die Erfassung des Kontexts. Das Team musste herausfinden, ob die Warnung etwas Ähnlichem ähnelte, das es gerade letzte Woche gesehen hatte, ob es einen ausstehenden Pull Request (PR) gab, der das Problem beheben könnte, ob in Slack-Threads etwas Erwähnenswertes dazu stand und so weiter.
Wie viele Teams haben wir gesehen, dass die Fähigkeiten des LLM-Modells im letzten Jahr schnell beschleunigt wurden. Wir haben kürzlich darüber berichtet, wie Figma Schwachstellen voraus bleibt, indem Agenten in unserer Codebasis (dank früherer Investitionen in die Speicherung von Konfiguration als Code) die Probleme bei Konfigurationsänderungen bei sensiblen Tools wie Okta und AWS erkennen. Um den Arbeitsaufwand sinnvoll zu reduzieren und die Sicherheit der internen Systeme von Figma zu verbessern, mussten wir über die Codebasis hinausgehen und ein neues System aufbauen, das uns bei der Vielfalt der Probleme helfen konnte, die unser SIEM findet.
Zunächst wollten wir eine Abfrageebene schaffen, die bei einer neuen Warnung die vorherige Argumentation des Bereitschaftsdienstteams anzeigen könnte. Dieses Projekt entwickelte sich schließlich zu einem vollständigen agentischen System, das Warnungen untersucht, Audit-Logs abfragt, Code-Änderungen vornimmt, PRs öffnet und sich im Laufe der Zeit durch sein eigenes Gedächtnis verbessert. Dies hat die Arbeitsweise unseres Sicherheitsteams komplett verändert.
Die RAG-Ebene: Warnungen mit einem Gedächtnis
Wir entwickelten im ersten Schritt ein Retrieval-Augmented Classification System auf der Grundlage von AWS Bedrock Knowledge Bases und Amazon Kendra. Auch hier wollten wir zunächst nur historischen Kontext dazu anzeigen, was die gleiche Warnung beim letzten Mal ausgelöst hatte, und eventuell doppelte Warnungen vermeiden.
Wenn eine Panther-Warnung ausgelöst wird, wandelt unser Lambda-Handler sie in ein standardisiertes Dokument um und indexiert es in Kendra. Wir extrahieren strukturierte Felder aus den Rohdaten der Warnung: IP-Adressen aus p_any_ip_addresses, Akteure aus p_any_usernames und aus verschiedenen anbieterspezifischen Benutzerfeldern, AWS-Konto-IDs aus ARNs. Diese werden zusätzlich zu Warnungstitel, Schweregrad, den Tags und Zeitstempeln zu durchsuchbaren Kendra-Dokumentattributen:
const attrs: DocumentAttribute[] = [
{ Key: 'alert_id', Value: { StringValue: doc.alert_id } },
{ Key: 'alert_type', Value: { StringValue: doc.alert_type } },
{ Key: 'severity', Value: { StringValue: doc.severity } },
{ Key: 'status', Value: { StringValue: doc.status } },
{ Key: 'created_at', Value: { DateValue: doc.created_at } },
{ Key: 'has_investigation_context', Value: { LongValue: doc.has_investigation_context } },
]Wenn die nächste ähnliche Warnung ausgelöst wird, fragen wir Bedrock nach semantischen Übereinstimmungen ab. Dabei verwenden wir primär den Warnungstitel (der typischerweise den Namen der Erkennung gefolgt vom Benutzernamen des Akteurs enthält):
function buildQueryFromAlert(alert: Alert): string {
return `${alert.data.title}\n\nhas_investigation_context=1`
}Die Empfehlungen wurden zusätzlich dadurch verbessert, dass wir aktuellere Ergebnisse bevorzugten. Eine ähnliche Warnung von vor zwei Tagen ist weitaus nützlicher als eine exakt doppelte Warnung von vor sechs Monaten. Das liegt daran, dass wir unsere Triage-Workflows für Warnungen stetig weiterentwickeln.
Wir rufen bevorzugt Warnungen ab, die investigation_context enthalten, d. h. Slack-Kommentare von Techniker*innen des Bereitschaftsdienstteams über das, was sie gefunden haben. (Aus einer erledigten Warnung ohne Kommentare können wir fast keine Erkenntnisse gewinnen.) Wir erfassen den Untersuchungskontext, ohne die bestehenden Workflows unserer Techniker*innen zu ändern. Wenn jemand eine Notiz in einem Slack-Warnungs-Thread hinterlässt (und wir haben ein ähnliches Verfahren für Asana-Tickets), indexieren wir diesen Kommentar in Kendra als Untersuchungskontext und weisen ihn der ursprünglichen Warnung zu:
export async function addInvestigationContext(
alertId: string, contextText: string
): Promise<void> {
const existingDoc = await findAlertDocument(alertId)
if (!existingDoc) return
let updatedContext: string[]
updatedContext = [...existingDoc.investigation_context, contextText]
const updatedDoc: AlertDocument = {
...existingDoc,
investigation_context: updatedContext,
has_investigation_context: 1,
}
await reindexDocument(updatedDoc)
}Mit jedem nützlichen Kommentar in einem Warnungs-Thread wird der Triage-Prozess bei jeder zukünftigen ähnlichen Warnung einfacher. Wir benötigten kein spezielles Annotations-Tool oder eine Trainings-Pipeline, weil der bestehende Workflow bereits die Trainings-Pipeline ist.

Was das Abrufsystem leisten konnte und wo es seine Grenzen hatte
Unser Abrufsystem generiert und postet für jede Warnung eine für Menschen lesbare Zusammenfassung in Slack/Asana. Diese Neuerung entlastete unser Bereitschaftsdienstteam praktisch sofort. Wir hörten von verschiedenen Seiten, dass die Triage von Warnungen beschleunigt wurde. Zudem konnten wir einige programmatische Änderungen vornehmen, die die Alarmmüdigkeit reduzierten. Und wenn wir ähnliche Warnungen als mit hoher Wahrscheinlichkeit harmlos oder doppelt identifizieren konnten, haben wir den Schweregrad automatisch heruntergestuft:
if (autoResolutionConfidence >= 7) {
if (updatedSeverity === 'high' || updatedSeverity === 'critical') {
await alertsDb.updateAlertSeverity(alert.alertId, 'medium')
}
}Allein durch diese Änderung konnten wir die Anzahl der Bereitschafts-Alarme um 20 % reduzieren.
Nachdem unser RAG-System eingerichtet war, überlegten wir, was der nächste logische Schritt sein könnte: eine Art agentische Ebene zur Unterstützung der Warnungsuntersuchung und zur automatischen Behebung von Problemen.
Hinzufügen einer agentischen Ebene
Wir nutzen Tines für die Workflow-Automatisierung. Dieses Tool bietet die Möglichkeit, LLM-Agenten-Schleifen mit expliziten Tool-Benutzeroberflächen zu betreiben, d. h. einen Slack-Thread lesen, nach Okta-Benutzer*innen suchen, eine Abfrage Panther-Daten abfragen, einen PR in einem bestimmten Repository öffnen usw. Techniker*innen können die Tool-Liste aufrufen und überlegen, was der Agent kann und was nicht. Wenn ein automatisiertes System auf Produktions-Sicherheitsdaten zugreifen kann, ist diese Prüfbarkeit sehr wertvoll.
Wir haben Tines verwendet, um eine agentische Ebene zu erstellen, die sich oberhalb unseres RAG-Systems befindet. Wenn Panther ein Ereignis erkennt, postet unser Lambda-Stream-Handler die Warnung zusammen mit der ersten LLM-Zusammenfassung und ähnlichen Verweisen auf ähnliche Warnungen aus der RAG-Ebene in Slack und taggt dann automatisch @Tines Sicherheit Slackbot im Thread. Mitglieder des Bereitschaftsdienstteams können den Bot auch manuell in jedem Thread taggen, um ihn bei Bedarf aufzurufen, Nachfragen zu stellen oder je nach Situation andere spezifische Erkenntnisse zu erhalten.
Wenn der Bot getaggt wird, werden Webhooks in Tines ausgelöst und zuerst ein Intent Routing durchgeführt. Ein ressourcenschonenderes Modell (wie Claude Sonnet) liest den gesamten Slack-Thread und klassifiziert die Anfrage: Handelt es sich um eine Warnungs-Triage, eine Plattform-Sicherheitsfrage, eine App-Genehmigungsanfrage oder etwas anderes? Jede Klassifizierung wird an einen spezialisierten Agenten übergeben. Diese Agenten haben jeweils eigene eingeschränkte Tool-Inventare, eine eigene Autorisierungs-Ebene und eigene System-Prompts. Der Warnungs-Triage-Agent übernimmt den Großteil der Arbeit. Doch dadurch, dass wir separate Agenten für unterschiedliche Absichten haben, können wir jedem ein fokussiertes Toolset geben, ohne zu riskieren, dass ein Agent Zugriff auf alles hat.

Das Toolset des Warnungs-Triage-Agenten
Der Warnungs-Triage-Agent (mit einem Modell wie Claude Opus) führt die meisten Untersuchungen durch. Er erhält den gesamten Verlauf des Slack-Threads als Kontext, sein eigenes Steuerungsgedächtnis (dazu später mehr) und eine Reihe von Tools, die die Möglichkeiten bieten, die die Techniker*innen des Bereitschaftsdienstteams während der Triage typischerweise benötigen:
- Okta: Benutzerprofile abrufen, deren Gruppen auflisten, Login-Verlauf überprüfen, Benutzer*innen nach Filter suchen. Wenn eine Warnung über verdächtige Aktivitäten von einem bestimmten Akteur ausgelöst wird, ruft der Agent normalerweise zuerst das Okta-Profil dieses Akteurs ab, um zu verstehen, um welche*n Benutzer*in es sich handelt und worauf diese Person Zugriff haben sollte.
- North Pole Security Workshop (das unser Endpunkt-Sicherheitstool Santa verwaltet): Suchregeln, Suchereignisse, Host-Sync-Status überprüfen, Regeln an Hosts senden. Wenn die Warnung eine blockierte Binärdatei oder eine Endpunkt-Richtlinienverletzung betrifft, kann der Agent die Signatur-ID überprüfen, die Ereignishistorie für diese Binärdatei überprüfen und feststellen, ob andere Benutzer*innen ebenfalls blockiert werden.
- Wiz: Audit-Logs, Inventar von Cloud-Ressourcen, Daten zu Schwachstellen, offene Probleme und gefährdete Ressourcen abrufen. Bei Warnungen zur Cloud-Infrastruktur kann der Agent überprüfen, ob eine gekennzeichnete Ressource bekannte Schwachstellen oder Fehlkonfigurationen aufweist.
- Slack: Thread-Antworten lesen, Benutzerprofile abrufen, Fortschrittsupdates senden. Der Agent liest frühere Threads, die mit ähnlichen Warnungen verlinkt sind, um die damaligen Überlegungen und Diskussionen der Techniker*innen einzubeziehen.
- Panther: Details zur Warnung abrufen, Rohdaten zu Ereignissen abrufen, die eine Warnung ausgelöst haben, und verwandte Warnungen auflisten. Damit erhält der Agent Zugriff auf die strukturierte Payload der Warnung, nicht nur auf die Meldungen in Slack.
- Code-Änderung: PRs in unserem Panther-Detektions-Repo oder unserem Monorepo öffnen. Mehr dazu später.
- Der Unteragent für Panther-Untersuchungen: ein separater LLM-gestützter Agent, der Snowflake-SQL in unserem gesamten Sicherheits-Data Lake schreiben und ausführen kann. Dies ist das leistungsstärkste Tool im Set. Wir werden als Nächstes darüber sprechen.
Abfrage des Sicherheits-Data Lake
Der Triage-Agent kann viele Fragen mit seinen direkten Tools beantworten: „Wer ist diese*r Benutzer*in in Okta?“, „Welche Santa-Regeln gelten für dieses Binärprogramm?“ „Ist diese Cloud-Ressource in Wiz?“ Viele Untersuchungen müssen jedoch tiefer gehen. Was hat diese*r Benutzer*in in AWS in den zwei Stunden vor der Warnung gemacht? Welche Prozesse liefen auf dem Benutzerendpunkt und waren diese Prozesse ungewöhnlich? Gab es während dieses Zeitfensters Zugriffe auf andere Apps oder Konfigurationsänderungen?
Für diese Fragen delegiert der Triage-Agent an einen separaten Unteragenten für Untersuchungen. Dieser Unteragent (ebenfalls ein Modell wie Claude Opus) nimmt eine Abfrage in natürlicher Sprache vom übergeordneten Agenten entgegen und übersetzt sie in Snowflake SQL. Er nutzt die Daten aus unserem Data Warehouse, das Audit-Logs aus dem gesamten Unternehmen enthält: AWS CloudTrail, Okta-System-Logs, GitHub-Audit-Ereignisse, GCP-Audit-Logs, Osquery-Endpunkt-Telemetrie, Workshop/Santa-Ereignisse, Wiz-Erkenntnisse und etwa hundert weitere Tabellen.
Der übergeordnete Agent geht dabei ähnlich vor wie bei einer Bitte an Kolleg*innen: „Finde die neuesten Okta-Logins für Benutzer*in X in den letzten 48 Stunden“ oder „Überprüfe, welche Prozesse Benutzer*in Y in den letzten 2 Tagen auf ihrem*seinen Endpunkt ausgeführt hat“ oder „Was hat Benutzer*in Z in AWS EKS am 10. März zwischen 10:21 und 20:21 UTC gemacht?“ Der Unteragent findet heraus, welche Tabellen und welche Spalten benötigt werden und wie nach Zeit gefiltert werden soll.
Diese Vorgehensweise funktioniert, aber die Tabellenschemata können etwas unübersichtlich sein. Die Spaltennamen sind über die Protokollquellen hinweg inkonsistent, die Verbindungsschlüssel sind nicht gut dokumentiert und die Zeitpartitionierungsfunktionen variieren je nach Tabelle. Ohne Hilfe würde der Unteragent vier oder fünf Anfragen benötigen, um das Schema zu erkennen, bevor er die eigentliche Frage beantworten könnte. Schlimmer noch: Er könnte eine Abfrage so durchführen, dass falsche oder unvollständige Ergebnisse ausgegeben werden. Wir werden im nachfolgenden Abschnitt zum Agentengedächtnis aufzeigen, wie wir dieses Problem gelöst haben.
Entwicklung und Segmentierung des Agentengedächtnisses
Es stellte sich heraus, dass das Agentengedächtnis den größten Einfluss darauf hatte, wie nützlich das System im Laufe der Zeit wurde. Wir haben mehrere Arten von Agentengedächtnissen, und es zeigte sich, dass sie separat bleiben sollten.
Den RAG-Korpus betrachten wir als Fallgedächtnis. Wir haben dieses System bereits beschrieben. Es enthält historische Warnungen plus Untersuchungskontext von Slack und Asana. Wenn der Agent wissen muss, wie ähnliche Situationen aussahen oder was Techniker*innen des Bereitschaftsdienstteams die zu einem vergangenen Vorfall herausgefunden haben, dann schaut er hier nach.
Darüber hinaus haben wir das, was wir als Steuerungsgedächtnis bezeichnen. Dies ist eine Verhaltensrichtlinie für den Agenten, die als Markdown-Dokument gespeichert wird und bei jedem Start in den Kontext des Agenten geladen wird. Stellen Sie sich das wie eine AGENTS.md-Datei oder das Bedrohungsmodell vor, das ein Agent benötigt, um die Codebasis auf Schwachstellen zu prüfen. Es enthält Regeln wie „Wenn du veraltete Okta-Synchronisierungswarnungen siehst, überprüfe sowohl die resource-sync- als auch die group-sync-Jobs, bevor du abschließend urteilst, ob es systemisch ist“ oder „Benutzer*in X führt diese Woche Wartungsarbeiten an System Y durch, behandele diese Warnungen als erwartet“.
Der Agent kann sein eigenes Steuerungsgedächtnis aktualisieren, wenn Sicherheitstechniker*innen es korrigieren. Wenn jemand sagt: „Du hast das falsch gemacht. Du solltest stattdessen das hier tun“, bleibt die Korrektur für zukünftige Durchläufe bestehen. Wir haben gelernt, dass wir genau überlegen sollten, was in das Steuerungsgedächtnis gelangt und was in der RAG-Ebene bleibt. Eine einmalige Lektion zu einem bestimmten Warnungstyp sollte in den Untersuchungskontext gehen, damit sie als Präzedenzfall für ähnliche zukünftige Warnungen dient. Eine Verhaltensregel, die das Vorgehen des Agenten bei allen Warnungen ändern sollte, gehört ins Steuerungsgedächtnis. Anfangs machten wir den Fehler, alles im Steuerungsgedächtnis zu speichern. Dadurch wurde das Verhalten des Agenten jedoch auf unerwünschte Weise verändert. Präzedenzfälle und Richtlinien sind unterschiedliche Dinge und sollten unterschiedlich gehandhabt werden.
Wir verwenden auch datenbankgestützte Datensätze in Tines für zustandsbehaftete Objekte: vom Agenten erstellte offene PRs, Panther-Untersuchungsstatus, Dinge, die stabile Schlüssel und Statusverfolgung statt natürlicher Sprachabfrage benötigen. Diese sind eher alltäglich, aber notwendig.
Die interessanteste Gedächtnisebene ist die prozedurale, und sie löst direkt das oben beschriebene Schema-Erkennungsproblem. Wir gaben dem Unteragenten für Untersuchungen ein eigenes Gedächtnis, das mithilfe von Tags (aws, okta, osquery, workshop, etc.) organisiert ist. Bevor eine Abfrage gestartet wird, lädt der Agent relevante Erinnerungen für die Datenquellen, die er abrufen möchte. Nach Abschluss einer Untersuchung, die eine Schemaerkennung erforderte, speichert er das Gelernte:
Title: Job Description Fields in Workiva Logs (2026-03-12T16:25:21 UTC)
Memory: Job descriptions for each user within the system can be found within the field 'jd' in the table 'WORKIVA_USERS'.Ein zweites LLM (das ein ressourcenschonenderes Modell verwendet) übernimmt die eigentliche Speicherformatierung: Es nimmt die Rohdaten, generiert einen Titel mit einem UTC-Zeitstempel, taggt ihn und überträgt die Daten in den eigenen Speicher (das Gedächtnis). Als wir den Untersuchungsagenten zum ersten Mal nach Zoom-Aktivitäten fragten, benötigte er mehrere Erkennungsabfragen. Nachdem er diese Informationen im Gedächtnis gespeichert hatte, kostete dieselbe Frage nur eine einzige Abfrage. Dieses Muster wiederholte sich über Datenquellen hinweg, während der Agent durch Versuch und Irrtum sein eigenes Betriebshandbuch erstellte.
Beispiele für Agentenuntersuchungen
Hier findest du drei aktuelle Beispiele, die die Funktionsweise des Agenten in der Praxis veranschaulichen.
Beispiel 1: Es wurde eine Warnung ausgelöst, weil jemand eine macOS-Audio-Transkriptions-App installiert hat, die von Figma nicht überprüft und nicht zur Verwendung freigegeben wurde. Der Triage-Agent las den Warnungs-Thread, rief ähnliche historische Warnungen aus der RAG-Ebene ab und verwendete dann seine Okta- und Workshop-Tools, um das Gesamtbild zu erhalten: Der Akteur war derselbe Techniker, der die Erkennungsregel verfasst hatte – ich, Matthew! Workshop zeigte eine Regel an, die zu Testzwecken am selben Tag erstellt wurde und sich auf eine Einzelperson bezog. Fazit: Der Autor der Regel testete seine eigene Erkennung. Keine Aktion erforderlich. Der Agent machte sogar eine Notiz, dass mein Slack-Status darauf hinweist, dass ich beschäftigt bin und es eine Weile dauern könnte, bis ich meine Aktivitäten bestätigen kann.

Beispiel 2: Wiederholte Snowflake-Warnseiten lösten immer wieder für dasselbe Dienstkonto aus. Der Agent beschrieb den aktuellen Zustand, delegierte an den Unteragenten zur Untersuchung, um eine Abfrage der relevanten Audit-Logs durchzuführen, identifizierte den Grund für die wiederholten Warnungen, stellte fest, dass ein Entwurf für einen PR zur Vermeidung dieser Wiederholungen bereits geöffnet wurde, und erklärte, dass die langfristige Lösung in einem anderen Thread diskutiert wurde. Der*die Techniker*in des Bereitschaftsdienstteams erhielt ein vollständiges Bild, ohne einen einzigen Tab öffnen zu müssen. Dies war vor wenigen Monaten noch undenkbar.
Beispiel 3: Wir lösen oft Warnungen für Situationen aus, die mit Malware zusammenhängen könnten, aber meist legitimes Verhalten darstellen (z. B. wenn ein unbekannter Startdienst auf MacBooks von Figma-Mitarbeiter*innen installiert wird). Früher wäre das undenkbar gewesen; unser Team unterstützt Tausende Figma-Mitarbeiter*innen, sodass wir schnell von der Menge an Warnungen überwältigt gewesen wären. Bei diesem neuen Modell kann unser Agent jedoch überprüfen, ob die Binärdatei von einer vertrauenswürdigen Quelle signiert wurde, per Panther-Abfrage feststellen, wie der Dienst installiert wurde (brew, App Store usw.), und dann automatisch die notwendigen Änderungen coden, damit die Warnung in Zukunft unter den bekannten sicheren Bedingungen unterdrückt wird. All dies ist ohne menschliches Eingreifen möglich.
Von der Untersuchung zu Code-Änderungen
Was uns in Bezug auf die Zeiteinsparung am meisten überraschte, war der Schritt des Agenten von „Ich habe herausgefunden, was los ist“ zu „Hier ist ein PR, der das Problem behebt“.
Es gibt zwei Codepfade. Für Änderungen an Erkennungsregeln, Zulassungslisten und Warnmeldungsunterdrückungen öffnet der Agent PRs für unser Panther-Detektions-Repo. Dies ist der häufige Fall: Eine Warnung wird ständig für ein bekannt harmloses Muster ausgelöst, ein*e Techniker*in des Bereitschaftsdienstteams bestätigt im Slack-Thread, dass es sich um einen Fehlalarm handelt, und der Agent erstellt einen Eintrag in der Zulassungsliste oder passt die Erkennungsregel an. Für alles andere (z. B. Infrastrukturänderungen, Service Configs, Terraform oder RBAC- und Identitätsanbieter-Konfigurationen) arbeitet der Agent direkt mit unserem Monorepo.
Von Bots erstellte PRs führen dazu, dass git blame auf ein Dienstkonto verweist, was nicht hilfreich ist, um den Kontext einer Änderung Monate oder Jahre später zu verstehen. Wir ergänzen jetzt den Namen der anfordernden Sicherheitsperson in der PR-Beschreibung und verlinken zurück zum ursprünglichen Slack-Thread. Das hätten wir von Anfang an tun sollen.
Wenn Prüfer*innen Kommentare zum PR hinterlassen, greift der Agent diese über GitHub-Webhooks auf und kann zusätzliche Änderungen vornehmen oder darauf reagieren. Er kann auch veraltete Zweige auf den neuesten Master verschieben, wenn PRs eine Weile offen bleiben.
Leitlinien
Alle Tool-Aufrufe enthalten deterministische Schutzmaßnahmen, um sicherzustellen, dass der Agent nichts versucht, von dem nicht möchten, dass er es tun kann. Zum Beispiel wird jeder vom Agenten erstellte PR automatisch als Entwurf generiert. Dies erfolgt als deterministischer Nachschritt im Tines-Workflow und nicht als Prompt, da wir frühzeitig herausfanden, dass sich das LLM nicht zuverlässig daran erinnert hat, PRs immer als Entwurf zu erstellen.
Wir verwenden diesen Tool-Aufrufansatz, um alle möglichen Kontrollen deterministisch durchzusetzen. Damit stellen wir sicher, dass der Agent beim Abrufen von Okta-Daten keine sensiblen Mitarbeiterinformationen erhält oder verarbeitet. Außerdem wird so garantiert, dass der Agent keine PRs abschließt oder verändert, die er nicht selbst erstellt hat. Da die Sicherheit eines Systems von gestaffelten Kontrollen abhängt, achten wir auch darauf, dass die dem Agenten zur Verfügung stehenden Tools ordnungsgemäß abgegrenzt, autorisiert und überwacht werden und dass der Agent selbst im Auftrag eines autorisierten Teammitglieds arbeitet.
Wir haben auch versucht, die Konsequenzen von schlechtem Kontext einzudämmen. Der Agent hat keinen allgemeinen Zugriff auf ganze Slack-Kanäle, und abgesehen von direkten Nachrichten kann er Threads nur dann lesen, wenn die neuesten Nachricht diese erneut per Tag referenzieren.
Hinzu kommt, dass wir uns mit Autonomie deutlich wohler fühlen, wenn Aktionen begrenzt, reversibel und durch klare Beweise gestützt sind, als wenn sie umfassend, destruktiv oder schwer zu prüfen sind. In der Praxis bedeutet das, dass leseintensive Untersuchungen, Dublettenerkennung, Präzedenzfälle und Entwurfsverbesserungen besser für eine agentische Ausführung geeignet sind als generische, leistungsstarke Schreibvorgänge.
Wir erwarten, dass ein größerer Teil der Warnungen im Laufe der Zeit automatisch verarbeitet wird, jedoch nur hinter strengeren Schutzvorkehrungen: engeren Handlungsspielräumen, besserer Evaluierung (wie bei diesem Beispiel zum Aufbau von Vertrauen in KI-Agenten durch Metriken) und klareren Herkunftsangaben dazu, warum das System zu einem Schluss gekommen ist.
Nachbetrachtung
Hier sind ein paar Dinge, die wir anders machen würden, wenn wir noch einmal bei null anfangen müssten:
- Das prozedurale Gedächtnis hätte von Anfang an vorhanden sein sollen. Das selbsterstellte Schema-Gedächtnis des Untersuchungsagenten war eine späte Ergänzung, und die Verbesserung war so deutlich, dass alles davor rückblickend fast wie verschwendete Arbeit erscheint.
- Konfiguration-als-Code ist entscheidend, um die Fragmentierung der Agenten-Ebene zu verhindern. Weil Teammitglieder schnell iterieren wollen, kommt es dazu, dass verschiedene Personen den gleichen Kern-Agenten mit leicht unterschiedlichen Tool-Konfigurationen in leicht unterschiedlichen Versionen erstellen und für verschiedene Zwecke einsetzen. Wie du dir vorstellen kannst, lässt sich in dieser Situation kaum sicherstellen, dass alle Tools, die diesen Agenten zur Verfügung stehen, konsistent sind und auf die gleiche Weise funktionieren. Heute wird unser Kern-Toolset außerhalb von Agenten konfiguriert und verwaltet und per Konfiguration-als-Code betrieben. Dadurch wird sichergestellt, dass alle Agenten von einem standardisierten Satz von Aktionen profitieren, die sorgfältig gepflegt werden.
- Wenn du einen Agenten mit Slack-Integration erstellst, sollte das Vertrauensmodell für öffentliche Kanäle frühzeitig bedacht werden. Unsere Agenten verfügen über Autorisierungskontrollen, um sicherzustellen, dass nur Teammitglieder des Sicherheitsteams ihnen Aufträge geben können. Wenn ein Agent jedoch beschließt, detaillierte Logs der Benutzeraktivitäten zu durchsuchen, könnten alle möglichen sensiblen Daten auftauchen. Daten, die die Aktivitäten von Benutzer*innen an diesem Tag beschreiben, sind in einem privaten Sicherheits-Thread völlig in Ordnung, werden aber in einem Raum mit Hundert Personen zu einem großen Problem. Wir beheben dieses Problem durch kanalbezogenes Prompt-Design und andere deterministische Kontrollen. Nichtsdestotrotz ist wichtig, dies von Anfang an zu entwerfen, anstatt später hinzuzufügen.
Aktueller Stand und nächste Schritte
Das System übernimmt alle anfänglichen Sicherheitsreaktionen für das Team. Die Arbeit des Bereitschaftsdienstteams hat sich gewandelt von „von Grund auf untersuchen“ zu „die Erkenntnisse des Agenten überprüfen, bestätigen oder korrigieren und die Fälle bearbeiten, die menschliches Urteilsvermögen erfordern".
Der Zeitaufwand für die Lösung komplexer Warnungen wurde um etwa 70 % reduziert, die Zahl der Bereitschafts-Alarme ist durch KI-gesteuertes Herunterstufen der Schweregrade um 20 % gesunken und es gab 25 % weniger Anfragen zur Genehmigung von Endpunktsoftware (der Agent erkennt Tool-Genehmigungsanfragen und weist Benutzer*innen auf vergleichbare genehmigte Alternativen hin). Zudem vertraut das Bereitschaftsdienstteam stärker auf die Qualität der Behebungsmaßnahmen, weil die Beweiskette des Agenten explizit und überprüfbar ist.
In einem Jahr wird das System Tausende Triage-Entscheidungen, Schema-Zuordnungen und Verhaltenskorrekturen verinnerlicht haben, die niemand im Team allein im Kopf haben könnte. Hier sind wir besonders optimistisch: Es geht nicht um ein einzelnen Agenten-Durchlauf, sondern darum, dass jeder Durchlauf den nächsten kostengünstiger und genauer macht.
In der nächsten Phase geht es vor allem darum, eine bessere Kontrollebene um das Modell herum zu entwickeln. Wir möchten schärfer zwischen unseren Ebenen für Präzedenzfälle, Richtlinien und Zustände unterscheiden. Wir möchten besser entscheiden können, ob eine Warnung sicher automatisch geschlossen werden kann oder ob sie eskaliert werden sollte, obwohl das Modell keine Zweifel hat. Und wir möchten, dass unsere wichtigsten Workflows sich nicht mehr auf Prompt-Verhalten beschränken, sondern deterministische und überprüfbare Automatisierung bieten.
Ein abschließender Hinweis: Es wird viel darüber gesprochen, ob es sich lohnt, KI zur Untersuchung von Problemen einzusetzen, da KI nicht perfekt ist. Aber auch Menschen sind nicht perfekt. Wir glauben, dass es keine Entweder-oder-Entscheidung zwischen Menschen oder KI ist. Vielmehr gibt es viele Dinge, die man zwischen diesen beiden Extremen tun kann, mit denen sich Risiken reduzieren lassen und die Effizienz verbessert wird. Für die Umsetzung gibt es jedoch noch keinen Leitfaden.
Wir stellen technische Fachleute ein!
Erfahre mehr über das Leben bei Figma und sieh dir unsere offenen Stellen an.
Wir sind begeistert und stolz auf das, was wir geschaffen haben, aber wir wissen, dass dies erst der Anfang einer längeren Reise mit enormem Potenzial und einigen Stolpersteinen ist. Wenn andere Teams ähnliche Systeme aufbauen, kontaktiere uns bitte! Wir würden uns über einen Austausch freuen.




