[{"data":1,"prerenderedAt":748},["ShallowReactive",2],{"search-de":3,"content-de-developer\u002Fplugin-capabilities":4,"surround-de-\u002Fdeveloper\u002Fplugin-capabilities":741},[],{"id":5,"title":6,"body":7,"description":733,"extension":734,"meta":735,"navigation":736,"path":737,"seo":738,"stem":739,"__hash__":740},"content_de\u002F3.developer\u002F43.plugin-capabilities.md","Capabilities, Grants & Vertrauen",{"type":8,"value":9,"toc":713},"minimark",[10,15,33,43,46,61,66,219,256,268,272,279,305,325,329,336,409,416,420,432,493,496,500,513,516,523,527,534,551,559,574,578,589,593,597,604,614,618,625,630,634,645,650,653,657,660],[11,12,14],"h2",{"id":13},"capabilities-sind-anfragen-grants-sind-berechtigungen","Capabilities sind Anfragen, Grants sind Berechtigungen",[16,17,18,19,23,24,28,29,32],"p",{},"Das ",[20,21,22],"code",{},"capabilities","-Array eines Manifests ist eine ",[25,26,27],"strong",{},"Anfrage",": die Menge der Host-Operationen, die das Plugin jemals anfordern darf. Die Grants eines Betreibers sind die ",[25,30,31],{},"Berechtigung",": welche dieser Anfragen für diese Installation erlaubt sind.",[34,35,41],"pre",{"className":36,"code":38,"language":39,"meta":40},[37],"language-text","manifest capabilities  ⊇  operator grants  ⊇  what actually runs\n","text","",[20,42,38],{"__ignoreMap":40},[16,44,45],{},"Grants können das Manifest ausschließlich einschränken. Es gibt keinen Mechanismus, mit dem ein Betreiber, eine Connected App, ein API-Key oder ein Plugin eine Capability über das im Manifest Deklarierte hinaus ausweiten könnte. Das Deklarieren einer Capability gewährt sie nie.",[16,47,48,49,52,53,56,57,60],{},"Capability-Namen sind kleingeschriebene ",[20,50,51],{},"domain:action","-Paare mit ",[25,54,55],{},"Exact-Match","-Semantik. Wildcards sind nicht Teil des Vertrags. Der Namensraum ist offen — eine neue Contribution-Naht erfordert keine neue ",[20,58,59],{},"@owlat\u002Fplugin-kit","-Major-Version, nur um ein Capability-Literal hinzuzufügen — und der Host bleibt die alleinige Instanz, die entscheidet, welche Capabilities er kennt und durchsetzt.",[62,63,65],"h3",{"id":64},"das-vokabular","Das Vokabular",[67,68,69,82],"table",{},[70,71,72],"thead",{},[73,74,75,79],"tr",{},[76,77,78],"th",{},"Capability",[76,80,81],{},"Gewährt",[83,84,85,96,106,116,126,143,153,163,173,186,196,206],"tbody",{},[73,86,87,93],{},[88,89,90],"td",{},[20,91,92],{},"send:transport",[88,94,95],{},"Einen Send-Transport beitragen",[73,97,98,103],{},[88,99,100],{},[20,101,102],{},"send:gate",[88,104,105],{},"Ein ausschließlich einschränkendes Autonomy-Gate beitragen",[73,107,108,113],{},[88,109,110],{},[20,111,112],{},"agent:step",[88,114,115],{},"Einen Schritt der Inbox-Agent-Pipeline beitragen",[73,117,118,123],{},[88,119,120],{},[20,121,122],{},"draft:strategy",[88,124,125],{},"Eine Strategie zur Entwurfserzeugung beitragen",[73,127,128,140],{},[88,129,130,133,134,133,137],{},[20,131,132],{},"automation:trigger"," \u002F ",[20,135,136],{},"automation:step",[20,138,139],{},"automation:condition",[88,141,142],{},"Zur jeweils passenden Automation-Registry beitragen",[73,144,145,150],{},[88,146,147],{},[20,148,149],{},"webhooks:publish",[88,151,152],{},"Namensraum-gebundene Webhook-Events veröffentlichen",[73,154,155,160],{},[88,156,157],{},[20,158,159],{},"imports:provide",[88,161,162],{},"Einen Import-Provider beitragen",[73,164,165,170],{},[88,166,167],{},[20,168,169],{},"scheduler:cron",[88,171,172],{},"Einen Hintergrund-Cron mit festem Intervall registrieren",[73,174,175,183],{},[88,176,177,133,180],{},[20,178,179],{},"ui:navigation",[20,181,182],{},"ui:settings",[88,184,185],{},"Ein Sidebar- oder Einstellungsziel hinzufügen",[73,187,188,193],{},[88,189,190],{},[20,191,192],{},"worker:enqueue",[88,194,195],{},"Reserviert für gesandboxte Tier-3-Jobs; es wird kein Host-Enqueue-Adapter ausgeliefert",[73,197,198,203],{},[88,199,200],{},[20,201,202],{},"llm:invoke",[88,204,205],{},"Verbrauchsgemessene Textgenerierung über Owlats LLM-Dispatch",[73,207,208,216],{},[88,209,210,133,213],{},[20,211,212],{},"plugin-storage:read",[20,214,215],{},"plugin-storage:write",[88,217,218],{},"Namensraum-gebundener JSON-Key\u002FValue-Storage",[16,220,221,222,225,226,225,229,225,232,225,235,238,239,225,242,225,245,225,248,225,251,225,253,255],{},"Connected Apps fordern zusätzlich API-Scopes an, die auf einem plugin-gebundenen Key zugleich als Capabilities wirken: ",[20,223,224],{},"contacts:read",", ",[20,227,228],{},"contacts:write",[20,230,231],{},"events:write",[20,233,234],{},"transactional:send",[20,236,237],{},"topics:write"," (auch auf eigenständigen Keys gültig) sowie die ausschließlich für Tier 2 gültigen ",[20,240,241],{},"campaigns:read",[20,243,244],{},"mail:read",[20,246,247],{},"knowledge:read",[20,249,250],{},"webhooks:manage",[20,252,212],{},[20,254,215],{},".",[257,258,261],"callout",{"title":259,"type":260},"Tier-2-only-Scopes schlagen bereits bei der Erzeugung fail-closed fehl","info",[16,262,263,264,267],{},"Ein ausschließlich für Tier 2 gültiger Scope hat für einen eigenständigen Key keine Bedeutung. Die Key-Erstellung lehnt ihn ab, sofern der Key nicht an ein Plugin gebunden ist — er kann also nur innerhalb des Modells aus Manifest-Obergrenze plus Betreiber-Grant existieren. Alte Keys ohne ",[20,265,266],{},"scopes","-Spalte sind bei der Durchsetzung deny-all.",[62,269,271],{"id":270},"wann-durchgesetzt-wird","Wann durchgesetzt wird",[16,273,274,275,278],{},"Jede gehostete Operation validiert die gesamte Kette ",[25,276,277],{},"unmittelbar bevor"," sie läuft — nicht einmalig beim Start:",[280,281,282,286,289,292,295,298],"ol",{},[283,284,285],"li",{},"Singleton-Organisations-Scope,",[283,287,288],{},"das Plugin ist registrierter Bestandteil der Build-Komposition,",[283,290,291],{},"das Feature-Flag ist in der aufgelösten Flag-Map aktiv,",[283,293,294],{},"das Manifest deklariert die Capability,",[283,296,297],{},"die Betreiber-Grant für genau diese Capability existiert,",[283,299,300,301,304],{},"jeder Eintrag aus ",[20,302,303],{},"flag.requiredEnvVars"," ist vorhanden.",[16,306,307,308,311,312,225,315,225,318,225,321,324],{},"Jeder Fehlschlag löst einen ",[20,309,310],{},"PluginHostError"," aus (",[20,313,314],{},"capability_not_declared",[20,316,317],{},"capability_not_granted",[20,319,320],{},"plugin_disabled",[20,322,323],{},"required_environment_missing",", …), und der deklarierte sichere Fallback der Contribution greift. Eine Verweigerung ruft niemals Plugin-Code auf. Das Deaktivieren eines Plugins oder das Widerrufen einer Grant wirkt deshalb schon bei der nächsten Operation — kein Redeploy, kein Cache, den man abwarten müsste.",[11,326,328],{"id":327},"services-statt-framework-kontexte","Services statt Framework-Kontexte",[16,330,331,332,335],{},"Gehosteter Plugin-Code erhält einen ",[20,333,334],{},"PluginContext",", der ausschließlich aus host-vermittelten Services besteht:",[67,337,338,348],{},[70,339,340],{},[73,341,342,345],{},[76,343,344],{},"Service",[76,346,347],{},"Hinweise",[83,349,350,365,379,389,399],{},[73,351,352,357],{},[88,353,354],{},[20,355,356],{},"permissions",[88,358,359,133,362],{},[20,360,361],{},"has(capability)",[20,363,364],{},"require(capability)",[73,366,367,372],{},[88,368,369],{},[20,370,371],{},"storage",[88,373,374,375,378],{},"Namensraum-gebundener JSON-KV-Store. Methoden nehmen ",[25,376,377],{},"kein"," Organisations- oder Plugin-Argument entgegen",[73,380,381,386],{},[88,382,383],{},[20,384,385],{},"llm",[88,387,388],{},"Attribuierter, budgetierter Dispatch",[73,390,391,396],{},[88,392,393],{},[20,394,395],{},"logger",[88,397,398],{},"Strukturiertes Logging",[73,400,401,406],{},[88,402,403],{},[20,404,405],{},"scheduler",[88,407,408],{},"Scheduling benannter Tasks",[16,410,411,412,415],{},"Er legt niemals einen Convex-",[20,413,414],{},"ctx",", ein Datenbank-Handle, Umgebungswerte, rohe Modellobjekte oder beliebige Scheduler-Funktionsreferenzen offen.",[62,417,419],{"id":418},"storage-isolation-und-limits","Storage-Isolation und Limits",[16,421,422,423,426,427,133,429,431],{},"Der Host bindet den Storage-Service an die authentifizierte Organisation und das validierte Plugin und prüft dann bei ",[25,424,425],{},"jeder"," Operation erneut das Flag und die exakte ",[20,428,212],{},[20,430,215],{},"-Grant. Einträge sind nach Organisation, Plugin und Key indiziert; List-Cursor sind authentifiziert verschlüsselt und scope-gebunden.",[67,433,434,444],{},[70,435,436],{},[73,437,438,441],{},[76,439,440],{},"Limit",[76,442,443],{},"Wert",[83,445,446,454,461,469,477,485],{},[73,447,448,451],{},[88,449,450],{},"Key",[88,452,453],{},"256 Bytes",[73,455,456,458],{},[88,457,443],{},[88,459,460],{},"64 KiB",[73,462,463,466],{},[88,464,465],{},"Einträge pro (Org, Plugin)",[88,467,468],{},"1 000",[73,470,471,474],{},[88,472,473],{},"Gesamtbytes pro (Org, Plugin)",[88,475,476],{},"10 MiB",[73,478,479,482],{},[88,480,481],{},"Seitengröße einer Liste",[88,483,484],{},"100",[73,486,487,490],{},[88,488,489],{},"JSON-Tiefe \u002F -Knoten \u002F -Array-Elemente \u002F -Objektfelder",[88,491,492],{},"32 \u002F 4 096 \u002F 1 024 \u002F 1 024",[16,494,495],{},"Quota-Zähler werden in derselben Convex-Transaktion wie der jeweilige Schreibvorgang aktualisiert, die Obergrenze lässt sich also nicht durch eine Race Condition umgehen.",[62,497,499],{"id":498},"llm-budgets","LLM-Budgets",[16,501,502,504,505,508,509,512],{},[20,503,202],{}," erfordert ein explizites Flag ",[25,506,507],{},"und"," ein validiertes ",[20,510,511],{},"llmBudget.dailyUsd",". Der Host autorisiert, bevor er die Provider-Konfiguration des Mandanten auflöst, und prüft Registrierung, Flag, Deklaration, Grant und Budget in derselben Transaktion erneut, in der er unmittelbar vor dem Dispatch die Ausgabe reserviert.",[16,514,515],{},"Anfragen sind auf 64 KiB UTF-8-Eingabe über höchstens 32 Nachrichten mit je 32 KiB sowie auf 2 048 Output-Tokens begrenzt. Akzeptiert werden nur exakte Modellidentitäten aus einem providerspezifischen Zulassungskatalog, und Preisangaben gelten nur für den eingebauten Endpunkt eines Providers als vertrauenswürdig — eine explizite Base-URL, ein Azure-Deployment, ein kompatibler\u002Flokaler Server oder ein unbekannter Provider schlagen fail-closed fehl.",[16,517,518,519,522],{},"Die Abrechnung nutzt ganzzahlige Mikro-USD. Eine Reservierung deckt jeden Retry ab, den die gemeinsame Dispatch-Policy zulässt; bei Erfolg wird ungenutzter Spielraum freigegeben, für jeden fehlgeschlagenen Versuch bleibt jedoch ein Maximum einbehalten. Fehlende oder fehlerhafte Verbrauchsdaten, ein Provider-Fehler, ein Absturz der Action, ein Abrechnungsfehler oder ein Provider, der ein anderes als das zugelassene Modell meldet, führen alle dazu, dass die konservative Reservierung für diesen UTC-Tag ",[25,520,521],{},"einbehalten"," wird. Dieser Kompromiss zulasten der Verfügbarkeit gibt niemals Budget wieder frei, das der Provider möglicherweise berechnet hat.",[62,524,526],{"id":525},"nicht-vertrauenswürdiger-text","Nicht vertrauenswürdiger Text",[16,528,529,530,533],{},"Von Plugins erzeugter Text ist an jeder Grenze nicht vertrauenswürdig. An den ausgelieferten Convex-seitigen Grenzen — Begründungen von Automation-Schritten und Begründungen von Autonomy-Gates — beschneidet der Host den Text auf ein Code-Point-Maximum und führt eine Injection-Bereinigung durch, bevor er einen Prompt oder ein gespeichertes Feld erreichen kann. Es gibt bewusst keine permissive Standard-Policy: Jeder Host-Adapter benennt die Policy für seine Laufzeit, und ein Nicht-String-Wert, ein Scrubber, der wirft, oder ein Scrubber, der keinen String zurückgibt, werden rundweg abgelehnt (",[20,531,532],{},"untrusted_output_rejected",").",[16,535,536,537,540,541,546,547,550],{},"Diese beiden sind die gesamte Liste. Der Assistent fehlt bewusst: Heute kann kein Plugin ein Assistenten-Tool beitragen — ",[20,538,539],{},"assistantTools"," ist ein reservierter Bucket (siehe ",[542,543,545],"a",{"href":544},"\u002Fdeveloper\u002Fplugin-contributions","Contribution-Referenz",") —, und die Ausgabe der eingebauten Tools wird vom ",[20,548,549],{},"scrubForInjection"," des Assistenten selbst injection-bereinigt, einer Kernkontrolle ohne Bezug zu dieser Policy.",[16,552,553,554,558],{},"Browser-gebundener Plugin-Text ist eine andere, engere Kontrolle: Navigations- und Einstellungslabels werden auf 64 UTF-16-Code-Units beschnitten (ein astrales Zeichen zählt doppelt — dieselbe Einheit, mit der der Manifest-Validator den Namen begrenzt), wobei Steuer- und Bidi-Formatzeichen beim Ableiten des Eintrags entfernt werden. Das ist Spoofing-Abwehr — gegen Markup schützt Vues HTML-Escaping — und die Injection-Bereinigungs-Policy wird auf diesem Pfad ",[555,556,557],"em",{},"nicht"," angewendet.",[16,560,561,562,565,566,569,570,573],{},"Gehostete Mail-Projektionen werden nach Unicode-Code-Points gekürzt: ",[20,563,564],{},"from"," 512, ",[20,567,568],{},"to"," 2 048, ",[20,571,572],{},"subject"," 1 024, jeder entschlüsselte Body oder Entwurf 65 536 und die Klassifikation, die ein Autonomy-Gate sieht, 128.",[62,575,577],{"id":576},"audit-attribution","Audit-Attribution",[16,579,580,581,584,585,588],{},"Jede erfolgreiche Host-Service-Operation schreibt eine mandantenbezogene Audit-Zeile, die sowohl ",[20,582,583],{},"organizationId"," als auch ",[20,586,587],{},"pluginId"," trägt. Audit-Metadaten sind ein Allowlist-basierter Skalar-Snapshot: Storage-Keys\u002F-Werte\u002F-Präfixe\u002F-Cursor, LLM-Prompts\u002F-Nachrichten\u002F-Ergebnisse, Provider-Fehler, Credentials, Mail-Inhalte und aufruferdefinierte Metadaten gelangen nie über die Audit-Grenze. Eine erfolgreiche gehostete Mutation schreibt ihre Audit-Zeile in derselben Transaktion wie die Zustandsänderung — ein Rollback verwirft also beides.",[11,590,592],{"id":591},"die-drei-vertrauensstufen","Die drei Vertrauensstufen",[62,594,596],{"id":595},"tier-1-gebündelte-plugins","Tier 1 — gebündelte Plugins",[16,598,599,600,603],{},"Vom Betreiber installierte Pakete, die zur Build-Zeit komponiert werden. Sie dürfen Backend- und Frontend-Module beitragen und eine isolierte Convex-Komponente unter einem injektiven ",[20,601,602],{},"plugin_\u003Cid>","-Namensraum ausliefern. Laufzeit-Flags deaktivieren sie sofort; das Installieren oder Entfernen erfordert einen Rebuild.",[16,605,606,609,610,613],{},[25,607,608],{},"Vertrauen:"," dasselbe wie beim eigenen deployten Code des Betreibers. Capabilities, Grants, Flags und host-vermittelte Services reduzieren die Autorität und machen Aktionen attribuierbar. Sie sind ",[25,611,612],{},"keine"," Sandbox.",[62,615,617],{"id":616},"tier-2-connected-apps","Tier 2 — Connected Apps",[16,619,620,621,255],{},"Externe HTTPS-Dienste, die über gescopte API-Keys und Webhooks erreicht werden, mit einem spezifizierten Protokoll für signierte synchrone Hooks. Sie führen niemals Code innerhalb von Convex oder Nuxt aus. Die API-Key- und die Webhook-Hälfte sind aktiv; der Hook-Laufzeitadapter wird nicht ausgeliefert. Siehe ",[542,622,624],{"href":623},"\u002Fdeveloper\u002Fplugin-connected-apps","Connected Apps",[16,626,627,629],{},[25,628,608],{}," nicht vertrauenswürdiger Netzwerk-Peer. Antworten werden strikt strukturvalidiert, bereinigt, beschnitten, größenbegrenzt, deadline-begrenzt und gegen Replay geschützt.",[62,631,633],{"id":632},"tier-3-gesandboxte-worker-jobs","Tier 3 — gesandboxte Worker-Jobs",[16,635,636,637,640,641,255],{},"Das workerseitige Protokoll für nicht vertrauenswürdige oder ressourcenintensive Berechnungen bleibt hinter der OS-Grenze des ",[20,638,639],{},"code-worker",", aber es wird kein Host-Enqueue-Adapter ausgeliefert. Siehe ",[542,642,644],{"href":643},"\u002Fdeveloper\u002Fplugin-sandboxed-jobs","Gesandboxte Jobs",[16,646,647,649],{},[25,648,608],{}," nicht vertrauenswürdiger Prozess. Keine ambienten Credentials, harte Ressourcen- und Zeitobergrenzen, host-kontrollierter Befehl, host-autoritative Abbrüche und Retries.",[16,651,652],{},"Dasselbe Capability-Vokabular und dieselben Host-Service-Prinzipien gelten für alle drei Tiers.",[11,654,656],{"id":655},"invarianten-die-ein-plugin-niemals-aufweichen-kann","Invarianten, die ein Plugin niemals aufweichen kann",[16,658,659],{},"Diese gelten für jedes Tier und jeden Contribution-Punkt. Bräche eine Änderung eine davon, ist sie kein Plugin-Feature — sie ist ein Bug.",[280,661,662,671,677,683,689,695,701,707],{},[283,663,664,670],{},[25,665,666,667,669],{},"Capabilities werden bei der Codegen ",[555,668,507],{}," zur Laufzeit geprüft."," Eine Contribution, deren Capability nicht deklariert ist, wird nie komponiert; eine Operation, deren Capability nicht gewährt ist, läuft nie.",[283,672,673,676],{},[25,674,675],{},"Betreiber-Grants können das Manifest nur einschränken."," Nichts weitet sie aus.",[283,678,679,682],{},[25,680,681],{},"Ein Plugin darf Arbeit oder Vorsicht hinzufügen, nie entfernen."," Es kann den Sicherheitsscan nicht umgehen, kein Sicherheits-Gate entfernen, keine Freigabe erzwingen und keinen Versand erzwingen. Die Ergebnistypen von Gates und Hooks sind strukturell nicht in der Lage, eine Freigabe auszudrücken.",[283,684,685,688],{},[25,686,687],{},"Gate-Fehler und -Timeouts schlagen fail-closed fehl."," Fehlende, deaktivierte, widerrufene, veraltete, abgelaufene, fehlgeschlagene oder fehlerhafte Gates leiten in die menschliche Prüfung.",[283,690,691,694],{},[25,692,693],{},"Von Plugins erzeugter Text ist nicht vertrauenswürdig"," — an jeder Grenze beschnitten und an jeder Convex-seitigen Grenze injection-bereinigt.",[283,696,697,700],{},[25,698,699],{},"Der LLM-Zugriff von Plugins läuft über den Dispatch",", mit Plugin-Attribution und einem harten Tagesbudget; Unsicherheit in der Abrechnung schlägt fail-closed fehl.",[283,702,703,706],{},[25,704,705],{},"Mandanten- und Plugin-Storage sind isoliert",", wobei der Scope vom Host gebunden und pro Operation erneut geprüft wird.",[283,708,709,712],{},[25,710,711],{},"Es wird kein beliebiges Laufzeit-JavaScript"," in Convex oder den Browser geladen. Sofortige Installation gibt es nur für Connected Apps und gesandboxte Jobs.",{"title":40,"searchDepth":714,"depth":714,"links":715},2,[716,721,727,732],{"id":13,"depth":714,"text":14,"children":717},[718,720],{"id":64,"depth":719,"text":65},3,{"id":270,"depth":719,"text":271},{"id":327,"depth":714,"text":328,"children":722},[723,724,725,726],{"id":418,"depth":719,"text":419},{"id":498,"depth":719,"text":499},{"id":525,"depth":719,"text":526},{"id":576,"depth":719,"text":577},{"id":591,"depth":714,"text":592,"children":728},[729,730,731],{"id":595,"depth":719,"text":596},{"id":616,"depth":719,"text":617},{"id":632,"depth":719,"text":633},{"id":655,"depth":714,"text":656},"Das Berechtigungsmodell für Plugins, die drei Vertrauensstufen und die Sicherheitsinvarianten, die kein Plugin aufweichen kann.","md",{},true,"\u002Fdeveloper\u002Fplugin-capabilities",{"title":6,"description":733},"3.developer\u002F43.plugin-capabilities","JfSfI5l8XIy2PPWnwxV4EoRnP5l31OOmDmi0IZUL2YM",[742,744],{"title":545,"path":544,"stem":743,"children":-1},"3.developer\u002F42.plugin-contributions",{"title":745,"path":746,"stem":747,"children":-1},"Plugins installieren & betreiben","\u002Fdeveloper\u002Fplugin-operations","3.developer\u002F44.plugin-operations",1786915109338]