# Koffer und Freigaben: Rechte für eine Aufgabe, von einem Menschen signiert

> Ein Koffer (kit) bündelt die Tools einer Aufgabe, befristet. Der Agent fragt mit request_grant, ein Mensch gibt auf der Freigabeseite mit BIP-322-Signatur oder über die Approver-API frei, und der Audit-Trail behält das signierte Statement.

Canonical: https://www.toolmesh.io/de/kits/

[Grants](/de/authorization/) decken die tägliche Arbeit ab: Ein Benutzer, eine Rolle oder ein Plan darf diese Tools aufrufen, immer. Manche Aufgaben brauchen für eine Stunde oder einen Nachmittag mehr, und niemand will diese Rechte dauerhaft vergeben oder Tool für Tool freigeben. Dafür gibt es den **Koffer** (englisch *kit*, in der Konfiguration `kits:`): ein benanntes Bündel von Tools, das du einmal definierst, das ein Agent in einem Schritt anfragt und das ein Mensch befristet freigibt. Die Freigabe gehört diesem Menschen: Auf der Freigabeseite ist sie eine Signatur mit einem Schlüssel, den nur er hat, und ToolMesh behält das signierte Statement im Audit-Trail. Ein Grant endet von selbst.

Diese Seite beschreibt den ganzen Weg: wie ein Koffer definiert wird, wie ein Agent erfährt, was ihm fehlt, und danach fragt, wie ein Mensch freigibt, was gilt, solange der Grant läuft, und was der Audit-Trail behält. Koffer gibt es im Standard-[Autorisierungsmodus](/de/authorization/#modi) `embedded`.

## Der Weg im Überblick

1. **Definieren:** Koffer und Approver in `config/authz.yaml`, neben Grants und Denies.
2. **Der Agent fragt, was er darf,** mit `tell_me_my_rights` über die Tools einer Aufgabe. Die Antwort nennt die Tools, die er nicht aufrufen darf, und die kleinste Menge Koffer, die sie abdecken würde.
3. **Der Agent fragt nach einem Koffer** mit `request_grant` (Koffer, Begründung, Dauer). Er bekommt eine Anfrage-ID, einen Fingerprint und, wenn ein Approver mit Signieradresse konfiguriert ist, einen Link zur Freigabeseite. Link und Fingerprint gibt er dem Menschen weiter, für den er arbeitet.
4. **Ein Mensch entscheidet.** Auf der Freigabeseite sieht er, was der Koffer erlaubt, behält, was die Aufgabe braucht, wählt eine Dauer bis zum Maximum des Koffers und signiert ein Statement mit genau diesem Inhalt. Oder ein Approver ruft die Approver-API mit einem eigenen Schlüssel auf.
5. **Der Grant gilt** für den anfragenden Benutzer auf der Verbindung, von der er gefragt hat, bis er abläuft oder widerrufen wird. Aufrufe, die der Koffer abdeckt, passieren die Autorisierung und, mit den Ausnahmen unten, das Pre-Execution-Gate.
6. **Alles wird auditiert:** die Anfrage, die Entscheidung mit Adresse, Signatur und Statement, und jeder Aufruf unter dem Koffer.

## Koffer definieren

Koffer stehen in der Grants-Datei `config/authz.yaml` (die Datei erklärt [Grants](/de/authorization/#grants-configauthzyaml)):

```yaml
kits:
  net-diag-read:
    description: "Network diagnosis (read-only)"
    warning: "Production systems."
    grants: [graylog:read, unifi:read, netbox:read, checkmk:read]
    tools: [netbox_get_device]
    ttl_default: 4h
    ttl_max: 24h
```

| Feld | Bedeutung |
|------|-----------|
| `description` | Pflicht. Wofür der Koffer ist, in klaren Worten. Aufrufer sehen es, und der Approver liest es. |
| `warning` | Wird mit der Beschreibung angezeigt. |
| `grants` | Scopes, die der Koffer abdeckt: `"*"` jedes Tool, `<backend>` jedes Tool eines Backends, `<backend>:<access>` die Tools eines Backends mit dieser [DADL-Access-Klassifizierung](/de/authorization/#dadl-access-klassen), `"*:<access>"` die Tools mit dieser Klassifizierung auf jedem Backend. Scopes, die mit `*` beginnen, in Anführungszeichen setzen. |
| `tools` | Einzelne Tools mit vollem Namen `<backend>_<tool>`. |
| `ttl_default`, `ttl_max` | Wie lange ein Grant des Koffers standardmäßig und höchstens gilt (`10m`, `4h`); das Maximum gilt für das, was der Agent anfragt, und für das, was ein Approver freigibt. Ein Koffer ohne `ttl_max` wird für höchstens 24 Stunden vergeben, sein `ttl_default` muss darunter bleiben. |

Koffernamen sind Slugs: Buchstaben, Ziffern, `.`, `_` und `-`, höchstens 64 Zeichen. `<backend>:<access>` deckt genau die Tools dieses Backends mit dieser Klassifizierung ab: Ein Koffer für `graylog:read` und einer für `unifi:write` ergeben zusammen kein `graylog:write`. Änderungen an der Datei gelten innerhalb von Sekunden, wie bei Grants; ein ungültiger Koffer wird wie ein ungültiger Grant gemeldet.

Ein Koffer erlaubt für sich nichts. Er ändert aber, was Aufrufer erfahren:

- Discovery (`discover_tools`, `toolmesh.discover`, `toolmesh.describe`) listet die Tools eines Koffers neben denen, die der Aufrufer aufrufen darf, markiert mit `grant_required: kit <name>`. Ein Tool, das kein Koffer abdeckt, bleibt für einen Aufrufer ohne Recht verborgen. Definiere Koffer deshalb nur für Tools, deren Namen gesehen werden dürfen.
- Ein abgelehnter Aufruf nennt die Koffer, die ihn erlauben würden, und der Audit-Eintrag der Ablehnung hält sie fest (`remedy_kits`).
- `tell_me_my_rights` nennt die Koffer je Tool und die kleinste Menge, die eine Aufgabe abdeckt.

## Was der Agent sieht und fragt

### `tell_me_my_rights`

Das Meta-Tool `tell_me_my_rights` steht neben `discover_tools` und `execute_code` in der Liste. Es sagt dem Aufrufer, was er darf, und entscheidet nichts; jeder Aufruf wird beim Ausführen erneut geprüft.

- Ohne Argumente: je Backend, wie viele Tools der Aufrufer aufrufen darf, wie viele ein Koffer hinzufügen würde, und welche Koffer.
- `backend: "<name>"`: das Urteil für jedes Tool dieses Backends.
- `tools: [...]`, der Preflight (höchstens 500 Tools): ein Urteil je Tool, `allowed`, `escalatable` mit den Koffern, die es erlauben würden, oder `denied`, dazu die kleinste gefundene Menge Koffer, die jedes eskalierbare Tool abdeckt. Ein Agent, der zuerst die Tools seiner Aufgabe prüft, kann dann einmal nach dem fragen, was ihm fehlt, statt Ablehnung für Ablehnung einzusammeln.

Jede Antwort listet außerdem die Koffer, die der Aufrufer hält (`grants`, mit ID, Ablauf und Restzeit), und seine offenen Anfragen (`requests`, jede mit Freigabelink und Fingerprint, damit sich ein Link später weitergeben lässt), und beschreibt diese Koffer mit ihren Warnungen. Die Antwort zeigt nur Tools, die der Aufrufer aufrufen darf oder über einen Koffer bekommen kann; für jedes andere Tool sagt sie `denied`, ohne zu verraten, ob es das Tool gibt. Jeder Aufruf landet im Audit-Trail (Tool `tell_me_my_rights`, Backend `toolmesh`): Es ist das Erste, was ein übernommener Agent nachschlagen würde.

### `request_grant`

`request_grant({kit, reason, ttl})` fragt nach einem Koffer.

| Argument | Bedeutung |
|----------|-----------|
| `kit` | Der Name des Koffers, wie `tell_me_my_rights` ihn nennt. |
| `reason` | Pflicht, höchstens 500 Zeichen: die Aufgabe und, falls vorhanden, das Ticket. Approver sehen die Begründung als Aussage des Anforderers markiert. Zeilenumbrüche werden zu Leerzeichen; Steuer- und Formatzeichen (bidirektionale Umschaltungen, Zero-Width-Zeichen) werden entfernt. |
| `ttl` | Optional, etwa `30m` oder `4h`: wie lange der Aufrufer den Koffer braucht. Ohne Angabe gilt das `ttl_default` des Koffers, sonst eine Stunde. Mehr als sein `ttl_max` wird nicht vergeben, oder 24 Stunden, wenn keins gesetzt ist; es zählt das Maximum zum Zeitpunkt der Freigabe. Der Approver kann den Koffer kürzer oder länger als angefragt freigeben, bis zu diesem Maximum. |

Die Antwort enthält eine Anfrage-ID aus zehn Zeichen und einen Fingerprint wie `0873-D5E5-9D1B-2DB7`. Wenn ein Approver eine Signieradresse hat und `TOOLMESH_ISSUER` auf die Adresse zeigt, unter der ToolMesh erreichbar ist, enthält sie außerdem `approval_url`, den Link zur [Freigabeseite](#die-freigabeseite). Die `note` der Antwort wiederholt Link und Fingerprint wörtlich, damit ein Agent, der die Notiz weitergibt, auch den Link weitergibt. Eine Anfrage wartet 30 Minuten auf eine Entscheidung, dann verfällt sie. Wer erneut nach einem Koffer fragt, dessen Anfrage noch offen ist, bekommt die offene Anfrage zurück; ein Aufrufer darf höchstens fünf Anfragen gleichzeitig offen haben. Mit der Anfrage hält ToolMesh für jeden Eintrag des Koffers fest, wie viele Tools er abdeckt und wie viele davon der Aufrufer noch nicht aufrufen darf; Approver sehen diese Zahlen.

ToolMesh listet `request_grant` nur als MCP-Tool, solange Koffer definiert sind, und viele Clients behalten die Tool-Liste, die sie beim Verbinden bekommen haben. Im [Code Mode](/de/code-mode/) sind dieselben Aufrufe immer da:

```javascript
const rights = await toolmesh.tell_me_my_rights({
  tools: ["graylog_search", "unifi_list_clients", "netbox_get_device"]
});
if (rights.kits && rights.kits.length) {
  const req = await toolmesh.request_grant({
    kit: rights.kits[0].name,
    reason: "Trace the VLAN mismatch from ticket 4711",
    ttl: "2h"
  });
  return req.note;   // link and fingerprint, to hand to the person
}
```

## Approver

Approver stehen in der Grants-Datei. Jeder hat einen Namen und einen eigenen Schlüssel: den SHA-256 eines Bearer-Keys für die [Approver-API](#die-approver-api), eine Signieradresse für die [Freigabeseite](#die-freigabeseite), oder beides.

```yaml
approvers:
  - name: alice@example.com
    key_sha256: "<SHA-256 of the key, 64 hex characters>"
  - name: bob@example.com
    address: bc1q0xcqpzrky6eff2g52qdye53xkk9jxkvrh6yhyw
    kits: [net-diag-read]
```

```bash
key=$(openssl rand -hex 32)   # the approver's key; hand it over securely
printf %s "$key" | sha256sum  # the key_sha256 for the grants file
```

- **`address`** ist eine Native-Segwit-Adresse (P2WPKH, `bc1q…`; `tb1q…` und `bcrt1q…` gehen ebenfalls). Der Approver signiert mit seinem privaten Schlüssel; ToolMesh speichert nur die Adresse und sieht den Schlüssel nie. Coins oder eine Blockchain sind nicht im Spiel: Der Schlüssel signiert nur Statements. Erzeuge einen auf der Freigabeseite unter „Set up a signing key“ (`https://<toolmesh>/approve/`), oder nimm die Adresse eines Native-Segwit-Kontos einer Wallet, die BIP-322-Nachrichten signiert. Taproot (`bc1p…`) und Script-Adressen werden abgelehnt.
- **`kits`** beschränkt einen Approver auf die genannten Koffer, die in der Datei definiert sein müssen; ohne die Angabe darf ein Approver jeden Koffer freigeben. Die Freigabe eines anderen Koffers wird abgelehnt (`403` auf der Approver-API, ein Fehler auf der Freigabeseite) und im Audit-Trail als fehlgeschlagenes `grant_approve` festgehalten. Die Freigabeseite bietet nur Approver an, die den Koffer der Anfrage freigeben dürfen. Ablehnen und Widerrufen stehen jedem Approver offen, denn sie nehmen nur Rechte weg.
- **Approver-Schlüssel sind keine MCP-Credentials.** Sie funktionieren nur auf der Approver-API, und die Credentials, mit denen sich MCP-Aufrufer verbinden, funktionieren dort nicht; ein Agent kann seine eigene Anfrage also nicht freigeben. Gib einem Agenten weder einen Approver-Schlüssel noch einen Signierschlüssel. Ein Approver, dessen Schlüssel zugleich ein MCP-Credential ist (`TOOLMESH_API_KEY`, `TOOLMESH_AUTH_PASSWORD`, ein Eintrag in `apikeys.yaml` mit `key_sha256`), wird abgelehnt. Ein Eintrag in `apikeys.yaml`, der nur einen bcrypt-`key_hash` hat, lässt sich nicht vergleichen; verwende auch so einen Schlüssel nie doppelt.
- Namen sind Slugs oder E-Mail-Adressen; weder Namen noch Schlüssel noch Adressen dürfen sich wiederholen. Ohne Approver sagt `request_grant` Aufrufern, dass kein Koffer vergeben werden kann, und ToolMesh loggt eine Warnung, wenn die Datei Koffer definiert.

Änderungen an `approvers:` gelten innerhalb von Sekunden. Eine Änderung, die sich nicht übernehmen lässt, weil die Datei nicht parst oder ein Approver abgelehnt wird, stoppt den Server beim Start; später wird sie geloggt, und die bisherigen Approver bleiben in Kraft. Nach dem Entfernen eines Approver-Schlüssels, der durchgesickert sein könnte, prüfe, dass das Log die Zeile `authorization policy applied` für diese Änderung mit der neuen Zahl `approvers` zeigt; bis dahin gibt der alte Schlüssel weiter frei.

## Wie ein Mensch freigibt

### Die Freigabeseite

`https://<toolmesh>/approve/<id>` zeigt eine offene Anfrage jedem, der den Link hat, und lässt einen Approver mit Signieradresse sie freigeben. Die Seite braucht kein Login: Zum Freigeben braucht es die Signatur mit dem Schlüssel einer Approver-Adresse, und weniger reicht nicht.

Im Browser ausprobieren: Die [Demo der Freigabeseite](/demo/approval/?lang=de) führt eine Anfrage mit Beispieldaten von der Prüfung bis zur Freigabe, auf Deutsch, Englisch, Französisch, Spanisch und Japanisch. Sie signiert nichts.

- **Was sie zeigt,** kommt von ToolMesh, die einfachen Antworten zuerst: für wen der Grant ist (Benutzer und Verbindung), das Risiko dessen, was der Koffer erlaubt (hoch, erhöht, mittel oder niedrig, nach der weitestreichenden Access-Klasse unter den behaltenen Einträgen), wie viele Aktionen für den Aufrufer neu wären, die Dauer und der Fingerprint. Vergleiche den Fingerprint mit dem, den der Agent gemeldet hat, über den Kanal, in dem du mit ihm arbeitest; so weißt du, dass der Link seine Anfrage zeigt. Danach kommen Beschreibung und Warnung des Koffers sowie Begründung und Client-Name, gekennzeichnet als Aussagen des Anforderers. Unter „Technische Details“ stehen ID und Zeiten der Anfrage und die Einträge des Koffers, gruppiert nach dem, was sie erlauben (jede Access-Klasse zuerst, dann `dangerous`, `admin`, sonstige, `write`, `read`), mit den Tools, die jeder abdeckt, und wie viele davon für den Aufrufer neu sind.
- **Einschränken.** Übernimm den Koffer wie angefragt, nimm ihn ohne seine gefährlichen Einträge, oder schalte unter „Technische Details“ einzelne Einträge ab. Der Grant deckt dann nur die Einträge ab, die eingeschaltet bleiben.
- **Dauer.** Die Seite bietet die angefragte Dauer und Stufen von 5 Minuten bis 24 Stunden an, bis zum `ttl_max` des Koffers (24 Stunden, wenn keins gesetzt ist). Unter „Andere“ lassen sich ganze Minuten oder Stunden eintippen, und ein Hinweis nennt das Maximum. Ein Grant darf kürzer oder länger als angefragt sein, nie länger als das Maximum.
- **Das Statement.** Für diese Auswahl schreibt ToolMesh ein Statement: Klartext, der dieses ToolMesh nennt, die Anfrage und ihre Nonce, Approver und Adresse, den Koffer, die freigegebenen und die weggelassenen Einträge, die Dauer, für wen der Grant ist, und die Begründung. Die Seite zeigt es, wie es ist, unter „Genauen Wortlaut anzeigen, den Sie unterschreiben (Englisch)“, und genau das wird signiert. ToolMesh schreibt es zum Prüfen der Signatur aus der gespeicherten Anfrage erneut; nichts, was Seite oder Anforderer hinzufügen, kann es ändern.
- **Signieren.** Füge den privaten Schlüssel ein (WIF oder 64 Hex-Zeichen) und halte den Knopf gedrückt, um in der Seite zu signieren; der Schlüssel bleibt im Browser, nur die Signatur wird gesendet. Oder kopiere das Statement in eine Wallet, die BIP-322-Nachrichten signiert, und füge die Signatur ein (mit oder ohne das Präfix `smp`). Auf einer Seite über reines HTTP (außer localhost) ist das Schlüsselfeld gesperrt: Nimm HTTPS.
- **Sprachen.** Die Seite spricht Deutsch, Englisch, Französisch, Spanisch und Japanisch. Sie folgt der Sprache des Browsers; `?lang=de` wählt eine, und die Sprachauswahl merkt sich die Wahl im Browser. Das Statement bleibt englisch: Es ist das, was ToolMesh prüft und festhält. In den anderen Sprachen zeigt die Seite daneben eine Lesehilfe, Zeile für Zeile, die nicht zum Signierten gehört. Beschreibung und Warnung des Koffers erscheinen so, wie die Grants-Datei sie enthält, und die Begründung des Anforderers wird nie übersetzt.
- **Einmal.** Eine Signatur gibt ihre Anfrage einmal frei: Das Freigeben nimmt die Anfrage aus dem Speicher, und ein Statement nennt eine Anfrage und ihre Nonce.
- **Grenzen.** Abgelehnte Freigaben (eine Signatur, die nicht passt, oder eine Auswahl, die nicht zur Anfrage passt) sind innerhalb von 15 Minuten auf 5 je Anfrage und Absenderadresse, 10 je Anfrage und 20 je Absenderadresse begrenzt; darüber antwortet die Seite mit `429` und `Retry-After`. Eine erfolgreiche Freigabe setzt die Zähler der Anfrage zurück. Die Zähler arbeiten wie die der [Login-Drosselung](/de/authentication/#login-drosselung), mit derselben Absenderadresse und in Redis, wenn es verbunden ist, aber getrennt davon: Abgelehnte Signaturen verbrauchen nie die Login-Limits.

Die Seite lädt nur ihr eigenes Stylesheet und ihre eigenen Scripts, die Teil des ToolMesh-Binarys sind (Content Security Policy `default-src 'none'`, kein anderer Origin, kein Framing). Messenger mit Link-Vorschau bekommen von ToolMesh eine Zusammenfassung (Koffer, Benutzer, Dauer, Tool-Zahlen, Fingerprint), nie die Begründung. `/approve/` ohne ID bietet nur das Einrichten eines Schlüssels.

Setze `TOOLMESH_ISSUER` auf die Adresse, unter der Approver ToolMesh erreichen. Sie ist die Basis der Links in `request_grant` und das ToolMesh, das ein Statement nennt. Ohne sie gibt `request_grant` keinen Link, und Statements nennen die Adresse, von der die Seite geladen wurde.

### Was ist BIP-322?

BIP-322 ist ein Standard, um Nachrichten mit dem Schlüssel hinter einer Bitcoin-Adresse zu signieren und die Signatur zu prüfen. ToolMesh nutzt den Signierteil und sonst nichts: Der Schlüssel eines Approvers signiert das Statement, und ToolMesh prüft die Signatur gegen die Adresse in `config/authz.yaml`. Coins, Blockchain oder ein Konto sind nicht im Spiel. Das Format wurde gewählt, weil es spezifiziert ist, weil die Prüfung mit nichts als Adresse und Statement auskommt, und weil der Schlüssel in einem Browser oder in einer Wallet liegen kann, die solche Nachrichten schon signiert.

Was du davon hast: Der Beleg einer Freigabe ist eine Signatur, die nur der Schlüssel des Approvers erzeugen konnte, über einen Text, der genau sagt, was freigegeben wurde. Niemand muss dem Gateway glauben, dass ein Mensch freigegeben hat: Der Audit-Eintrag trägt Adresse, Signatur und Statement, und jeder mit dem Eintrag kann das später prüfen. Ein Gateway, das „freigegeben von alice“ aus eigener Autorität festhält, kann das nicht bieten.

### Die Approver-API

Auf dem ToolMesh-Port, mit dem Approver-Schlüssel als Bearer-Credential:

| Anfrage | Wirkung |
|---------|---------|
| `GET /grants` | Offene Anfragen und aktive Grants |
| `GET /grants/<id>` | Eine Anfrage oder ein Grant |
| `POST /grants/<id>/approve` | Den Koffer vergeben. Optionaler Body: `{"ttl": "1h"}` für eine andere Dauer als angefragt, kürzer oder länger, bis zum `ttl_max` des Koffers (24 Stunden, wenn keins gesetzt ist; darüber wird die Freigabe mit `400` abgelehnt); `{"grants": ["graylog:read"], "tools": [...]}` für nur diese Einträge des Koffers, genau wie der Koffer sie listet |
| `POST /grants/<id>/deny` | Eine offene Anfrage ablehnen |
| `POST /grants/<id>/revoke` | Einen aktiven Grant jetzt beenden |

```bash
curl -s -H "Authorization: Bearer $APPROVER_KEY" https://toolmesh.example.com/grants/k3m9x2p7qa
curl -s -X POST -H "Authorization: Bearer $APPROVER_KEY" https://toolmesh.example.com/grants/k3m9x2p7qa/approve
```

Jede Anfrage und jeder Grant zeigt Beschreibung, Warnung und Umfang des Koffers neben dem, wer gefragt hat, warum und für wie lange; eine offene Anfrage zudem Fingerprint, Tool-Zahlen und Freigabelink. Wie die Begründung ist `caller_name` eine Aussage des Anforderers: Ein OAuth-Client wählt seinen Namen selbst. Die Freigabe eines Koffers, den der Aufrufer schon hält, ersetzt diesen Grant. Ein Grant behält seine Anfrage-ID, dieselbe ID widerruft ihn also, egal ob er hier oder auf der Freigabeseite freigegeben wurde.

## Solange ein Grant gilt

**Wer ihn hält.** Der anfragende Benutzer, als der Aufrufer, als der er sich verbunden hat: die `caller_id` eines API-Keys oder der OAuth-Client. Ein API-Key ohne `caller_id` bindet den Grant an diesen Key selbst (angezeigt als `grant_key`); zwei solche Keys eines Benutzers teilen sich also keine Grants. Der Grant überlebt einen Token-Refresh; andere Verbindungen desselben Benutzers halten ihn nicht.

**Was er abdeckt.** Ein Grant des ganzen Koffers per Approver-Schlüssel gibt den Koffer so, wie er zum Zeitpunkt jedes Aufrufs definiert ist: Ein aus der Datei entfernter Koffer erlaubt nichts mehr, ein geänderter gilt mit seinem neuen Inhalt. Ein Grant über **einen Teil des Koffers** (einige seiner `grants`-Scopes und `tools`), und jeder auf der Freigabeseite freigegebene Grant, deckt die Einträge ab, die die Freigabe genannt hat, und keine anderen: Später aus dem Koffer entfernte Einträge erlauben nichts, später hinzugefügte gehören nicht dazu. Ein [Deny](/de/authorization/#denies) gewinnt gegen einen Koffer wie gegen jeden Grant; er entscheidet im Autorisierungsschritt, bevor der Koffer angesehen wird.

**Ein Koffer ersetzt das Pre-Execution-Gate.** Ein Aufruf, den ein gehaltener Koffer abdeckt, passiert das [Gate](/de/output-gate/) auf das Wort des Approvers: Jede Pre-Execution-Policy ohne die Direktive `// toolmesh: enforce-with-kit` in ihrem Kopfkommentar wird für ihn übersprungen. Policies mit der Direktive, gedacht für Parameterfilter und für Bedingungen, die einschränken, was ein Scope erlaubt (kein Force-Push auf `main`, kein Abschalten eines Geräts), laufen weiter: Ein Koffer gibt die Tools frei, nicht jedes Argument. Das Post-Execution-Gate (Maskieren, Feldfilter) läuft für jeden Aufruf. Der Aufruf wird als `kit replaces the pre-execution gate` geloggt, und sein Audit-Eintrag trägt `kit_applied` und `gate_skipped`. Ob die dauerhaften Grants den Aufruf ebenfalls erlaubt hätten, spielt keine Rolle: Der Koffer gilt, sobald er das Tool abdeckt. Direktive und `ctx`-Felder stehen unter [Policies und Koffer](/de/output-gate/#policies-und-koffer).

**Wo Grants liegen.** In Redis, wenn ToolMesh mit einem verbunden ist (`REDIS_URL`): Anfragen und Grants überleben einen Neustart und werden zwischen Instanzen geteilt. Sonst im Prozessspeicher: Ein Neustart beendet alle Anfragen und Grants, und jeder Aufrufer ist zurück bei seinen dauerhaften Rechten. Ein Speicher, der ausfällt, wird geloggt und trägt keine Koffer bei.

**Beenden.** Ein Grant läuft von selbst ab. `POST /grants/<id>/revoke` beendet ihn sofort, und der nächste Aufruf hält den Koffer nicht mehr.

## Im Audit-Trail

Jeder Schritt wird mit Backend `toolmesh` festgehalten:

| Tool | Wann | Was der Eintrag trägt |
|------|------|-----------------------|
| `request_grant` | Der Agent fragt | Benutzer und Aufrufer, für die der Grant ist; in den Metadaten Anfrage-ID, Koffer, Begründung und angefragte Dauer (`ttl_requested`) |
| `grant_approve` | Ein Approver gibt frei | Approver, `approved_with` (`key` oder `signature`), Koffer, Dauer und Ablauf; bei einem Teil des Koffers die freigegebenen Einträge (`part_grants`, `part_tools`); auf der Freigabeseite außerdem Adresse, Signatur, Statement und dessen SHA-256 (`statement_sha256`). Eine abgelehnte Signatur wird als Fehler festgehalten |
| `grant_deny`, `grant_revoke` | Ein Approver lehnt ab oder widerruft | Approver, Grant-ID und Koffer |
| `tell_me_my_rights` | Der Agent fragt, was er darf | Jeder Aufruf |
| jedes Tool | Ein Aufruf, während der Aufrufer Koffer hält | `held_kits` (ein teilweise gehaltener Koffer mit `(part)` markiert); deckt einer das Tool ab, nennt `kit_applied` ihn und `gate_skipped` die ersetzten Pre-Execution-Policies |
| jedes Tool | Ein abgelehnter Aufruf | `remedy_kits`, die Koffer, die ihn erlaubt hätten |

Mit `AUDIT_STORE=log` stehen die Metadaten als Objekt `metadata` in der Audit-Zeile; der `sqlite`-Store hält sie im Eintrag. Um eine Freigabe später zu prüfen, nimm `address`, `statement` und `signature` aus ihrem Eintrag und prüfe die Signatur mit einem beliebigen BIP-322-Verifier.

## Betrieb

- **`TOOLMESH_ISSUER`** muss die öffentliche Adresse von ToolMesh sein: Sie bildet die Freigabelinks und benennt das ToolMesh in jedem Statement.
- **HTTPS** für die Freigabeseite; über reines HTTP ist das Schlüsselfeld außerhalb von localhost gesperrt.
- **Redis**, wenn Grants einen Neustart überleben oder mehrere Instanzen sie teilen sollen.
- **Approver- und Signierschlüssel** bleiben bei Menschen. Lege nie einen in die Konfiguration eines Agenten, und verwende nie ein MCP-Credential als einen solchen.
- **Koffer gibt es nur im Embedded Mode.** Im [External Mode](/de/authorization/#external-mode) antwortet `tell_me_my_rights` nur mit `allowed` und `denied`, und `request_grant` wird nicht gelistet.
