Über unsLeistungenProjekteR&DBlogWerkzeugeAnfangenKontakt

Ein Copilot-Agentenmanifest ist eine Sicherheitsgrenze. Hier ist der Prüfer dafür.

Jede Eigenschaft, die in einem Microsoft 365 Copilot Agentenmanifest den Geltungsbereich setzt, ist optional, und in sechs Fällen gewährt das Weglassen den größten statt den kleinsten Bereich. Ein JSON-Schema-Validator lässt solche Manifeste durch, weil an keinem etwas ungültig ist: Es fehlt etwas Optionales. Also haben wir die Prüfung geschrieben, die sie findet. Sie findet sechs Probleme in einem Manifest, das jeden anderen Test besteht.

pH7x Systems® · · 6 Min. Lesezeit

Ein deklarativer Agent für Microsoft 365 Copilot ist kein Code. Er ist ein JSON-Manifest, das dem Modell sagt, wozu er da ist, was er lesen und was er tun darf. Modell, Orchestrierung und Berechtigungsfilter kommen von Copilot. Die Grenzen kommen von Ihnen.

Fast jede Eigenschaft, die diese Grenzen setzt, ist optional. In sechs Fällen schränkt das Weglassen einer davon den Agenten nicht ein. Es gibt ihm den größtmöglichen Geltungsbereich.

Die Zeile, die alles gewährt

Ein Manifest braucht drei Felder: name, description und instructions. Alles Weitere sind Fähigkeiten, und diese wiegt am schwersten.

json
{
  "capabilities": [
    {
      "name": "OneDriveAndSharePoint",
      "items_by_url": [
        { "url": "https://tenant.sharepoint.com/sites/Tenders/Documents/Live" }
      ]
    }
  ]
}

Löschen Sie nun das Array items_by_url. Die Dokumentation ist eindeutig: ohne items_by_url und ohne items_by_sharepoint_ids kann der Agent auf jede OneDrive- und SharePoint-Quelle der Organisation zugreifen.

Nicht auf einige. Auf alle. Und die falsche Fassung wirft keinen Fehler: Sie erzeugt einen Agenten, der funktioniert, Fragen beantwortet und seine Antworten auf jede Site stützt, auf die die Person im Chat Zugriff hat.

Copilot wendet weiterhin die Berechtigungen dieser Person an, der Agent liest also nichts, was sie nicht selbst öffnen könnte. Diese Garantie ist echt, und über dieselbe Grenze haben wir in der KI-Assistent, der nur liest, was der Nutzer lesen darf geschrieben. Aber Filtern ist kein Begrenzen. Wer breiten Zugriff hat, bekommt einen Ausschreibungsagenten, der aus Personalakten und Vorstandsprotokollen antwortet, weil ihm nichts das Gegenteil gesagt hat.

Dieselbe Regel taucht sechsmal auf:

Fähigkeit Das weglassen Und der Agent bekommt
OneDriveAndSharePoint items_by_url, items_by_sharepoint_ids Jede SharePoint- und OneDrive-Quelle der Organisation
GraphConnectors connections Jeden Copilot-Connector der Organisation
TeamsMessages urls Jeden Kanal, jede Besprechung und jeden Chat
Meetings items_by_id Jede Besprechung
WebSearch sites Das offene Web
Email folders Das ganze Postfach

Das ist vertretbar: Ein Agent, der standardmäßig nichts läse, wäre frisch installiert nutzlos. Aber es kehrt die Gewohnheit derer um, die Sicherheitskonfiguration schreiben, wo eine fehlende Regel üblicherweise verweigert bedeutet. Hier bedeutet Schweigen ja.

Die Falle, die auch überlebt, wenn man das Muster kennt

Schema 1.8 hat zwei Schreibfähigkeiten ergänzt, EmailActions und MeetingActions. Die erste umfasst Triage, überwachten Versand, Löschen, Posteingangsregeln, automatische Antwort und Ordnerverwaltung.

Die Dokumentation hält fest, dass EmailActions unabhängig von Email arbeitet und dass die auf Email gesetzten Einschränkungen, darunter folders, shared_mailbox und group_mailboxes, dafür nicht gelten. Dieses Manifest tut also nicht, was gemeint war:

json
{
  "capabilities": [
    { "name": "Email", "folders": [ { "folder_id": "inbox" } ] },
    { "name": "EmailActions" }
  ]
}

Das Lesen bleibt auf den Posteingang begrenzt. Löschen, Verschieben und das Anlegen von Regeln überhaupt nicht. Es gibt keine Möglichkeit, EmailActions zu begrenzen: Das Objekt hat genau eine Eigenschaft, seinen Namen. Die Entscheidung ist binär und muss bewusst getroffen werden.

Dieses Manifest stammt von jemandem, der sorgfältig war. Sorgfalt an der falschen Stelle ergibt eine Datei, die umsichtig aussieht und es nicht ist.

Die Prüfung, die es findet

Ein JSON-Schema-Validator lässt jedes fehlerhafte Manifest von oben durch, weil an keinem etwas ungültig ist. Es fehlt etwas Optionales, was etwas anderes ist, und hier das Einzige, worauf es ankommt.

Die Prüfung muss also nach Abwesenheit suchen, und das ist mechanische Arbeit, was heißt, dass sie nicht bei einem Menschen liegen sollte, der um fünf Uhr nachmittags aufmerksam liest.

python
# Each capability, the properties that scope it, and what happens without them.
SCOPE = {
    "OneDriveAndSharePoint": (("items_by_url", "items_by_sharepoint_ids"),
                              "every SharePoint and OneDrive source"),
    "GraphConnectors": (("connections",), "every Copilot connector"),
    "TeamsMessages":   (("urls",),        "every channel, meeting and chat"),
    "Meetings":        (("items_by_id",), "every meeting"),
    "WebSearch":       (("sites",),       "the open web"),
    "Email":           (("folders", "shared_mailbox", "group_mailboxes"),
                        "the whole mailbox"),
}
# Write capabilities. There is no way to scope them: the choice is binary.
WRITES = {"EmailActions": "delete, move and create inbox rules",
          "MeetingActions": "book meetings and change the calendar"}

def check(manifest: dict) -> list[tuple[str, str]]:
    found = []
    caps = {c.get("name"): c for c in manifest.get("capabilities", [])
            if isinstance(c, dict)}

    for name, cap in caps.items():
        if name in SCOPE:
            props, everything = SCOPE[name]
            if not any(cap.get(p) for p in props):
                found.append(("OPEN", f"{name} without {' or '.join(props)}:"
                                      f" reads {everything}"))
        if name in WRITES:
            found.append(("WRITES", f"{name} can {WRITES[name]}"))

    # Email is scoped, EmailActions is not, and the file gives no sign of it.
    if "EmailActions" in caps and any(caps.get("Email", {}).get(p)
                                      for p in SCOPE["Email"][0]):
        found.append(("TRAP", "Email is scoped but EmailActions ignores that limit"))

    if not manifest.get("behavior_overrides", {}).get(
            "special_instructions", {}).get("discourage_model_knowledge"):
        found.append(("INVENTS", "answers from model knowledge when sources are silent"))
    if not manifest.get("disclaimer", {}).get("text"):
        found.append(("NO NOTICE", "the reader is not told where answers come from"))
    return found

Ergänzen Sie zwanzig Zeilen, die eine Datei lesen und einen Exit-Code ungleich null zurückgeben, und lassen Sie das Ganze gegen ein Manifest laufen, das jedes andere Werkzeug durchwinkt:

bash
$ python check_agent.py tender-desk.json
Tender Desk  schema v1.8
  OPEN      OneDriveAndSharePoint without items_by_url or items_by_sharepoint_ids:
            reads every SharePoint and OneDrive source
  WRITES    EmailActions can delete, move and create inbox rules
  OPEN      WebSearch without sites: reads the open web
  TRAP      Email is scoped but EmailActions ignores that limit
  INVENTS   answers from model knowledge when sources are silent
  NO NOTICE the reader is not told where answers come from

6 to review
$ echo $?
1

Begrenzen Sie denselben Agenten ordentlich, dann schweigt er und endet mit null. Genau das erlaubt ihm, eine Veröffentlichung zu stoppen, statt in einem Dokument zu liegen, das niemand öffnet.

Die Zeile TRAP rechtfertigt das ganze Skript. Sie schlägt nur an, wenn jemand Email begrenzt und danach EmailActions danebengesetzt hat, also genau bei dem Manifest, das ein sorgfältiger Mensch schreibt.

Wir haben es gegen ein realistisches Manifest für unseren eigenen Tenant laufen lassen, mit sauber begrenzter SharePoint-Site, und es hatte trotzdem etwas zu sagen: TeamsMessages war ohne urls-Array hinzugekommen, ein Agent für eine einzige Dokumentbibliothek konnte also jeden Kanal und jede Unterhaltung lesen, denen sein Nutzer angehört. Das hat niemand entschieden. Es war eine Zeile, die nie da war.

Was sie nicht findet

Das gehört klar gesagt, denn eine Prüfung, die ihre Abdeckung übertreibt, ist schlimmer als gar keine.

Sie liest eine Datei. Sie weiß nicht, ob die SharePoint-URL auf einen Ordner mit zwölf Dokumenten oder auf eine Site mit vierzigtausend zeigt, und dieser Unterschied wiegt schwerer als alles, was das Skript misst. Sie kann nicht beurteilen, ob die Anweisungen gut sind. Und sie sagt nichts darüber, ob die Menschen, die den Agenten nutzen, überhaupt Zugriff auf diesen Inhalt haben sollten, eine Berechtigungsfrage, die älter ist als der Agent und ihn überdauert.

Was sie abnimmt, ist der Teil der Prüfung, in dem ein Mensch am schlechtesten ist: zu bemerken, dass etwas nicht da ist.

Warum das zählt

Der Reiz eines deklarativen Agenten liegt darin, dass es keinen Code zu pflegen gibt. Ein Manifest, ein paar Wissensquellen und etwas wirklich Nützliches für ein Team, das nie eine eigens gebaute Anwendung bekommen hätte.

Das stimmt, und genau deshalb wiegt der Geltungsbereich hier schwerer als in einer Anwendung. Niemand prüft eine JSON-Datei so, wie er einen Pull Request prüft. Es gibt keine Testsuite. Es gibt keinen Compiler, der sagt, dass das ausgelassene Array den ganzen Tenant bedeutet.

Jetzt gibt es wenigstens ein Skript.

Weiterlesen

Entwicklung und Automatisierung

SPFx vor Version 1.0: drei unserer Web Parts in den offiziellen Microsoft-Samples

Die Developer Preview des SharePoint Framework erschien im August 2016. Version 1.0 kam im Februar 2017. Unser erster Beitrag zum offiziellen Sample-Repository von Microsoft 365 stammt vom Oktober 2016, fünf Monate bevor es eine 1.0 gab, auf der man bauen konnte. Drei unserer Web Parts liegen heute in diesem Repository, und dies ist der Zweck jeder einzelnen.

·4 Min. Lesezeit
Entwicklung und Automatisierung

Wir messen Ingenieure immer noch an dem Teil, der automatisiert wurde.

2025 warf DORA die eigene Anzeigetafel weg. Die Stufen low, medium, high und elite, die die Branche ein Jahrzehnt lang zitierte, wichen sieben Team-Archetypen über acht Messgrößen. Das ist keine Methodenfußnote. Es ist das meistgenutzte Messmodell der Softwarebranche, das einräumt, dass die Instrumente nicht mehr das ablesen, was über das Überleben eines Systems entscheidet.

·9 Min. Lesezeit
KI und Agenten

Ein Agent ist eine Integration. Hundert sind ein Governance-Problem.

Agenten haben eine produktionsreife Identität erhalten, bevor es eine stabile Art gab, ihr Handeln aufzuzeichnen. Microsoft Entra Agent ID ist verfügbar, mit Sponsoren und Ablaufdaten. Die OpenTelemetry-Konventionen für Agenten-Traces sind weiterhin experimentell. Dieser Unterschied ist kein Detail: Er entscheidet, was sich dieses Jahr verantwortungsvoll in Produktion bringen lässt, und macht aus einer KI-Frage eine Governance-Frage.

·10 Min. Lesezeit