> ## Documentation Index
> Fetch the complete documentation index at: https://docs.localmind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentifizierung und Rollen

> Wie Sie sich gegenüber der Localmind API authentifizieren und welche Rechte ein API-Key hat — für Entwickler und Admins.

Die Localmind API kennt zwei Authentifizierungsmethoden auf denselben Endpunkten. Diese Seite erklärt beide, grenzt sie vom separaten Automate-API-Key ab und beschreibt das zentrale Sicherheitsprinzip, das Admins kennen müssen: **Ein API-Key kann Zugriff nur verengen, niemals erweitern.**

<Info>
  Diese Seite ist für **Entwickler** (die programmatisch auf Localmind zugreifen) und für **Admins** (die verstehen wollen, welche Rechte ein ausgestellter Key hat) gleichermaßen relevant.
</Info>

## Die zwei Authentifizierungsmethoden

Beide Methoden senden ein Bearer-Token im `Authorization`-Header. Sie wirken auf denselben Endpunkten, unterscheiden sich aber in der Token-Quelle:

| Methode          | Header                        | Quelle                                                          | Typischer Einsatz                                                                         |
| ---------------- | ----------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **User-API-Key** | `Authorization: Bearer sk-…`  | In der Web-App erstellt (Benutzereinstellungen → API-Schlüssel) | Programmatischer Zugriff: eigene Apps, n8n, OpenAI-SDK-Umstieg, RAG über eigene Dokumente |
| **Keycloak-JWT** | `Authorization: Bearer <jwt>` | Frontend-Session der Web-App                                    | Die Localmind-Web-App selbst                                                              |

```bash theme={null}
curl -X GET "https://<deine-instanz>-api.localmind.ai/v1/models" \
  -H "Authorization: Bearer sk-…"
```

<Note>
  Der **User-API-Key** ist die kanonische Methode für die programmatische Nutzung. Er wirkt nur in der **Heimat-Org** des Users, der ihn erstellt hat — der Key eines Users aus einer **anderen** Organisation funktioniert nicht (die Web-App warnt bereits beim Erstellen davor). Den Scope wählen Sie beim Anlegen: **alle Spaces** oder **ausgewählte Spaces**. Wie Sie einen Key in der Web-App anlegen und widerrufen, beschreibt die Plattform-Seite [Persönliche API-Schlüssel](/navigation/Persönliche-API-Schlüssel).
</Note>

### Abgrenzung: Automate

<Warning>
  Der hier dokumentierte User-API-Key gilt für die `/v1`-Endpunkte der Localmind-API. Für das programmatische **Verwalten von Automate-Workflows** gilt er **nicht** — wie Sie Ihre Workflows verwalten, beschreibt [Automate und API-Zugriff](/administration/api).
</Warning>

## Kernprinzip: Ein Key verengt, er erweitert nie

Ein User-API-Key hat **exakt die Berechtigungen seines Besitzers** — nicht mehr und nicht weniger. Er kann den Zugriff gegenüber dem Besitzer nur **verengen** (per Scope), niemals über dessen Rolle hinaus **erweitern**. Bei jeder Anfrage mit einem Key greifen drei Gates. Bei Keycloak-JWT sind diese Gates No-Ops, das Frontend-Verhalten bleibt unverändert.

| Gate                 | Wirkung                                                                                                                                     |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| **User-Permissions** | Es gilt dieselbe Space- und Rollen-Prüfung wie im Frontend. Der Key sieht und darf genau das, was der Besitzer sieht und darf.              |
| **Org-Binding**      | Der Key ist an **eine** Organisation gebunden (die Heim-Org des Besitzers). Fremde Organisationen sind unerreichbar.                        |
| **Space-Scope**      | Ein *scoped* Key erreicht nur die beim Anlegen gewählten Spaces. Ein *org-weiter* Key erreicht alles, was der Besitzer in seiner Org sieht. |

<Tip>
  Das Prinzip ist für Admins die wichtigste Aussage: Sie müssen einem ausgestellten Key keine eigenen Rechte zuweisen. Der Key kann strukturell nie mehr, als die Rolle des Besitzers erlaubt. Wer einem Key weniger Reichweite geben will, schränkt den Scope auf ausgewählte Spaces ein.
</Tip>

## Rolle bestimmt die erlaubten Aktionen

Da der Key die Rolle des Besitzers 1:1 erbt, entscheidet die **Space-Rolle**, welche Aktionen erlaubt sind. Lesen, Suchen und Chatten funktionieren mit jeder Rolle. Schreibende Aktionen (Anlegen, Hochladen, Löschen) erfordern Schreibrechte im jeweiligen Space.

| Rolle im Space                                    | Lesen / Suchen / Chatten | Anlegen / Upload / Löschen |
| ------------------------------------------------- | ------------------------ | -------------------------- |
| **Owner / Editor** (z. B. eigener Privater Space) | erlaubt                  | erlaubt — voller CRUD      |
| **Viewer**                                        | erlaubt                  | abgelehnt mit **403**      |

Ein Viewer-Key kann lesen und suchen, aber **nicht** schreiben. Eine Schreibanfrage wird mit einem `403` und einer sprechenden Meldung abgelehnt:

```json theme={null}
{ "detail": "Permission denied: documents:create" }
```

<Note>
  Schreiben funktioniert nur in Spaces, in denen der Besitzer Schreibrechte hat. Der natürliche Ort dafür ist der eigene **Private Space** — jeder User ist dessen Owner und kann dort per Key alles verwalten. Die Rollenstruktur (Instanz → Org → Space) ist im [Berechtigungsmodell](/settings/instance/Role-Templates) und für die Org-Mitgliederverwaltung unter [Mitglieder](/settings/organization/Mitglieder) beschrieben.
</Note>

## Opt-in pro Endpunkt

Nicht jeder Endpunkt akzeptiert einen API-Key. Endpunkte, die nicht für den Key-Zugriff freigeschaltet sind, antworten bewusst mit `401` und verweisen auf die Frontend-Session:

```json theme={null}
{ "detail": "API key not accepted on this endpoint. Use a Keycloak access token." }
```

Ein Beispiel ist `GET /v1/me` (Ihr eigenes Benutzerprofil): Mit einem User-API-Key liefert dieser Endpunkt absichtlich `401`. Solche Endpunkte sind ausschließlich über eine Keycloak-Session erreichbar.

## Narrowing ist wasserdicht

Das Scope-Modell verhindert Datenlecks über Filter. Ein Filter auf einen Space, den der Key nicht erreicht (fremder oder nicht-gescopter Space), liefert keinen Fehler, der Existenz verraten würde — er liefert **0 Treffer**:

```bash theme={null}
curl -X POST "https://<deine-instanz>-api.localmind.ai/v1/data/hybrid-search" \
  -H "Authorization: Bearer sk-…" \
  -H "Content-Type: application/json" \
  -d '{"query": "Vertrag", "space_id": "<fremder-space>"}'
# -> 200 { "total_results": 0, "results": [] }
```

Fremde Spaces tauchen in `POST /v1/spaces/search` gar nicht erst auf. Der vom Aufrufer gesetzte Filter wird mit der für den Key erreichbaren Menge **geschnitten**, nie erweitert.

### Suche/Filter vs. direkter ID-Zugriff: das stille 404

Außerhalb des Key-Scopes verhält sich die API je nach Zugriffsart unterschiedlich — beide Varianten sind bewusst so gestaltet, dass die **Existenz** fremder Ressourcen nicht verraten wird:

| Zugriffsart                                                                                    | Verhalten außerhalb des Key-Scopes                                                          |
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| **Suche/Filter** (z. B. `POST /v1/data/hybrid-search`, `POST /v1/spaces/search`)               | `200` mit **0 Treffern** — kein Fehler, leeres Ergebnis                                     |
| **Direkter ID-Zugriff** (z. B. `GET /v1/data/{document_id}` mit einer ID außerhalb des Scopes) | bewusst **`404`** statt `403` — die Ressource erscheint als nicht vorhanden („stilles 404") |

Das stille 404 ist Absicht: Ein `403` würde bestätigen, dass die Ressource existiert. Erhalten Sie bei einer bekannten, korrekten ID ein `404`, prüfen Sie deshalb zuerst den **Space-Scope Ihres Keys** — nicht die ID. Eine Übersicht der Fehlercodes mit Lösungswegen bietet [HTTP-Fehlercodes](/troubleshooting/HTTP-Fehlercodes).

## Nachvollziehbarkeit: Audit und last\_used\_at

Jede Key-Nutzung ist nachvollziehbar:

* **`last_used_at`** wird bei jeder Anfrage aktualisiert.
* Key-Aktionen werden im **Audit-Log** mit `auth_method=api_key` und der Key-ID attribuiert.

<Warning>
  Diese Informationen sind in der Web-App einsehbar, aber **nicht** über den Key selbst auslesbar. Behandeln Sie API-Keys wie Passwörter: niemals in öffentlichen Repositories, Client-seitigem Code oder Logs ablegen. Bei Verdacht auf Kompromittierung widerrufen Sie den betroffenen Key gezielt, statt alle zu rotieren.
</Warning>

## Verwandte Seiten

<CardGroup cols={2}>
  <Card title="Konventionen und Fehler" icon="list-checks" href="/api-reference/Konventionen-und-Fehler">
    Base-URL, Pagination, Filter-DSL, Fehlermodell und Statuscodes.
  </Card>

  <Card title="OpenAI-kompatibel" icon="plug" href="/api-reference/OpenAI-Kompatibel">
    `GET /v1/models` und `POST /v1/chat/completions` als Drop-in für OpenAI-SDKs.
  </Card>

  <Card title="Persönliche API-Schlüssel" icon="key" href="/navigation/Persönliche-API-Schlüssel">
    Plattform-Sicht: Keys in der Web-App anlegen, scopen und widerrufen.
  </Card>

  <Card title="Org-Mitglieder verwalten" icon="users" href="/settings/organization/Mitglieder">
    Admin-Sicht auf Mitglieder, deren Rollen und damit die Reichweite ihrer Keys.
  </Card>
</CardGroup>
