In connic schreiben Apps und Agenten ihre Zugriffsregeln auf dieselbe Weise. Die Regeln einer App legen fest, was der Browser eines Besuchers lesen und ändern darf. Bei einem Agenten bestimmen die Regeln, was seine eingebauten Database, File und Retrieval Tools dürfen. Hat ein App-Besucher den Run gestartet, können die Regeln den Agenten auf die Datensätze dieses Besuchers beschränken. Aufgerufene Agenten sehen in ihren eigenen Regeln denselben Besucher. Dieses Tutorial richtet beides für ein Kundenportal ein und stellt Agenten von den älteren Einstellungen database, retrieval und files auf access um.
Eine Regelsprache, zwei Voreinstellungen
Die Regeln stehen unter access in apps/<key>.yaml oder agents/<name>.yaml. Jede Regel gehört zu einer Ressource, etwa einer Collection der Datenbank, einem Dateiordner oder einem Retrieval-Namespace, und zu einer Operation. Die Regel enthält einen Ausdruck darüber, wer fragt, und über den Datensatz, geschrieben in der Ausdruckssprache von connic, die auch Freigaberegeln und bedingte Tools nutzen. Für Datenbank und Dateien haben Apps und Agenten dieselben Operationen. In Retrieval können Apps nur suchen, Agenten auch speichern und löschen. Regeln für Runs, Sessions und Freigaben gibt es nur in Apps.
Der Unterschied liegt darin, was ohne Regeln passiert:
access kann keine Daten lesen oder ändern.connic.tools aufrufen. Ein Agent ohne access und ohne die älteren Einstellungen kann alle Daten seines Environments nutzen.Sobald ein Agent access hat, ist er so streng wie eine App: Eine Collection, ein Ordner, ein Namespace oder eine Operation ohne Regel ist verboten. Hat der Agent hinter dem Chat einer App keine Regeln, zeigt die App jedem Kunden nur die eigenen Bestellungen, der Agent antwortet demselben Kunden aber mit einem Database Tool, das jede Bestellung lesen kann.
Beispiel: ein Bestellportal
Als Beispiel dient ein Bestellportal für einen fiktiven Onlineshop. Kunden melden sich mit dem Login des Shops an, sehen ihre Bestellungen, laden Fotos beschädigter Ware hoch und stellen dem Agenten order-support im Chat Fragen. Der Chat läuft über einen WebSocket-Connector mit apps_only: true. Die Collection members verknüpft die E-Mail jedes Kunden mit einer customer_id, und jede Bestellung und jede Zahlung trägt diese ID.
Die Regeln der App finden über einen Lookup den Eintrag des Besuchers in members und zeigen nur die Bestellungen dieses Kunden. Uploads landen im Ordner uploads, und set schreibt die ID des Besuchers in die Metadaten jeder Datei, egal, was der Browser schickt:
connectors:
- portal-chat
lookups:
member:
collection: members
where: doc.email == user.email
access:
database:
orders:
read: doc.customer_id == member.customer_id
files:
uploads:
read: file.metadata.uploaded_by == user.id
write: new.size <= 10000000
set:
uploaded_by: user.idFür Bestellungen gibt es keine Regel für insert, update oder delete. Der Browser kann sie also nicht ändern, und jeder Besucher sieht nur die Dateien mit seiner eigenen ID. Anmeldung, Connectors und Data API beschreibt die Ankündigung von connic Apps.
Den Agenten auf die Datensätze des Besuchers beschränken
Eine Chatnachricht aus dem Portal startet einen Run, der den Besucher mitführt. connic übernimmt den Besucher aus der signierten App-Anfrage. Middleware, Tools und die Nachricht selbst können ihn nicht ändern, und die Regeln des Agenten sehen ihn als user. Die Agent-Datei bekommt denselben Lookup wie die App und Regeln für die Database Tools des Agenten. Die Regeln für Dateien und Retrieval folgen im nächsten Abschnitt:
name: order-support
tools:
- db_find
- db_count
- db_update
- file_list
- file_read
- file_write
- retrieval_query
- trigger_agent
lookups:
member:
collection: members
where: doc.email == user.email
access:
database:
orders:
read: user == null or doc.customer_id == member.customer_id
update: user == null or doc.customer_id == member.customer_idconnic wertet zuerst user und den Lookup aus und hängt den Rest der Regel an die Abfrage des Tools. Für einen angemeldeten Kunden liefern db_find und db_count nur dessen Bestellungen, und db_update ändert nur diese. Fragt der Kunde nach der Bestellnummer eines anderen Kunden, findet der Agent nichts, als gäbe es die Bestellung nicht.
user == null deckt Runs ohne Besucher ab, etwa per Cron, Webhook oder aus dem Dashboard. Diese Runs erreichen weiterhin jede Bestellung. Ohne die Bedingung verbieten die Regeln solche Runs.
Kann eine Regel für keinen Datensatz gelten, etwa bei einem Besucher ohne Eintrag in members, liefert der Tool-Aufruf statt eines Ergebnisses den Fehler „Access denied“. Die Logs des Runs halten ihn als Warnung fest. Auch jedes Database, File oder Retrieval Tool unter tools braucht Regeln: Sobald access gesetzt ist, scheitert connic lint bei jedem dieser Tools, dessen Ressource keine Einträge hat, denn jeder Aufruf wäre verboten.
Dateien und Retrieval-Namespaces
Derselbe access-Block enthält Regeln für die File und Retrieval Tools des Agenten:
access:
files:
uploads:
read: user == null or file.metadata.uploaded_by == user.id
write: true
set:
uploaded_by: user.id
retrieval:
help:
search: trueDer Agent versieht Dateien in uploads mit demselben uploaded_by wie die App. Ein Kunde sieht im Portal die Dateien, die der Agent für ihn gespeichert hat, und der Agent liest nur die Fotos dieses Kunden. Weil set auf user zugreift, können Runs ohne Besucher nicht in uploads schreiben. Ohne Regeln für update und delete kann der Agent keine Dateien umbenennen, verschieben oder löschen.
In Retrieval durchsucht der Agent nur help und die Namespaces darunter. Eine Suche ohne Namespace bräuchte einen Eintrag "*", und Einträge speichern oder löschen darf der Agent nicht. Eine Suche in help liefert dabei auch Passagen aus Namespaces wie help.internal, unabhängig von deren eigenen Regeln. Inhalte für das eigene Team gehören deshalb in einen getrennten Namespace wie internal.help.
Aufgerufene Agenten arbeiten für denselben Besucher
Bei Fragen zu Erstattungen startet order-support den Agenten refund-check mit trigger_agent. connic gibt den Besucher an diesen Run weiter. Die Regeln von refund-check sehen also denselben user, ebenso die Agenten, die refund-check seinerseits startet. Die Regeln selbst bleiben beim jeweiligen Agenten: refund-check wendet seinen eigenen access-Block mit eigenen Lookups an.
name: refund-check
tools:
- db_find
lookups:
member:
collection: members
where: doc.email == user.email
access:
database:
orders:
read: user == null or doc.customer_id == member.customer_id
payments:
read: user == null or doc.customer_id == member.customer_idEin aufgerufener Agent ohne access kann alle Daten seines Environments nutzen, auch wenn er für einen Besucher arbeitet. Jeder Agent, den der Run eines Besuchers über trigger_agent erreichen kann, braucht deshalb eigene Regeln. Nur Runs, die die App startet, tragen den Besucher in end_user, im Run-Kontext von refund-check fehlt er also. Braucht refund-check für die Antwort den Namen des Kunden, gibt order-support ihn in der Payload mit.
Die älteren Einstellungen database, retrieval und files ersetzen
Vor access haben Agenten ihre Tools mit den Einstellungen database, retrieval und files beschränkt. Diese Einstellungen sind veraltet, funktionieren aber weiter: connic setzt sie als Zugriffsregeln durch, und Deployments warnen im Log davor. Ein Agent kann sie nicht mit access kombinieren. Eine typische ältere Konfiguration:
database:
collections:
orders:
prevent_delete: true
files:
prevent_delete: trueconnic lint warnt davor und gibt einen access-Block mit demselben Verhalten aus:
! agents/order-support.yaml: database, retrieval and files are deprecated; replace them with:
access:
database:
orders:
read: true
insert: true
update: true
files:
'*':
read: true
write: true
update: true
retrieval:
'*':
search: true
store: true
delete: trueDer Block zeigt auch, was die älteren Einstellungen erlaubt haben. Der Agent hat retrieval nie gesetzt und durfte deshalb in jedem Namespace suchen, speichern und löschen, und prevent_delete bei Dateien ließ das Schreiben in jeden Ordner weiterhin zu. Wer den Block anstelle der alten Einstellungen einfügt, behält das bisherige Verhalten genau bei. In einem zweiten Schritt lässt sich der Block auf die Collections, Ordner und Namespaces eingrenzen, die der Agent braucht, mit Bedingungen an user, wo der Agent für App-Besucher arbeitet. Die Dokumentation der Zugriffsregeln ordnet jeder älteren Einstellung ihre Regeln zu.
Runs mit und ohne Besucher prüfen
Prüfe das Projekt. Ab composer SDK 0.1.63 meldet
connic lintkeine veralteten Einstellungen mehr und kein Database, File oder Retrieval Tool ohne Regeln.Melde dich als zwei Kunden an. Nimm zwei Testkonten, deren Einträge in
membersauf verschiedene Kunden zeigen. Jedes Konto sieht nur die eigenen Bestellungen, im Portal und in den Antworten des Agenten. Eine Frage nach der Bestellnummer des anderen Kunden bleibt ohne Treffer.Melde dich ohne Eintrag in members an. Die Datenbankaufrufe des Agenten liefern den Fehler „Access denied“, und die Logs des Runs zeigen für jeden eine Warnung.
Starte den Agenten ohne Besucher. Aus dem Dashboard oder per Cron gestartet, erreicht
order-supportjede Bestellung, und Schreibzugriffe aufuploadswerden abgelehnt.Verfolge den Run des aufgerufenen Agenten. Frag im Portal nach einer Erstattung und öffne den Run von
refund-checkaus dem Trace des aufrufenden Runs. Seine Datenbankaufrufe liefern nur die Bestellungen und Zahlungen dieses Kunden.
Gib jedem Kunden nur die eigenen Daten
Baue deine Agenten und die App, die sie aufruft, in einem connic-Projekt, mit Zugriffsregeln im Code.