Skip to main content
Glama
Shrey-Parikh31

rbac-rag-assistant

rbac-rag-assistant

Verwandt: drivescore-cloud, ein Go-Dienst auf Kubernetes mit Terraform und einem Incident-Log.

Ein interner Wissensassistent für eine Universität: Mitarbeitende und Studierende stellen Fragen in einfacher Sprache und erhalten Antworten, die auf Richtliniendokumenten basieren, deren Lektüre ihnen freigegeben ist. Retrieval-gestützt, Tool-Calling, rollenbewusst und über MCP verfügbar, sodass jeder Client dieselben Tools unter denselben Regeln verwenden kann.

Dies ist Layer 0 eines Fünf-Layer-Systems. Die darüberliegenden Layer ergänzen die Delivery-Pipeline, Reliability Engineering, Evaluation, Sicherheitstests und Observability, jeweils auf dieser Anwendung aufbauend und nicht daneben.

Ausführen

Python 3.13. Beachte, dass python auf dieser Maschine auf den msys2-Build verweist, der keines dieser Pakete enthält; rufe daher den venv-Interpreter direkt auf.

py -3.13 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe test_rag.py
.\.venv\Scripts\python.exe test_tools.py

Beide geben ok aus und benötigen keinen API-Schlüssel. Retrieval und die Zugriffsregeln sind offline testbar – genau das ist der Sinn, sie aus dem Modell herauszuhalten.

Frag ihn etwas (benötigt GEMINI_API_KEY):

.\.venv\Scripts\python.exe agent.py student "I have a 1.8 GPA, what happens?"
.\.venv\Scripts\python.exe agent.py staff "the wifi is down in the east wing, log it"

Retrieval allein, ohne Schlüssel:

.\.venv\Scripts\python.exe rag.py admin "adjunct pay per credit hour"

Related MCP server: mcp-business-bot

Wie es zusammenpasst

Datei

Wofür sie zuständig ist

rag.py

Parsing, Chunking, der TF-IDF-Index und der Freigabefilter

tools.py

Die drei Tools, ihre Zugriffsregeln und die Argumentvalidierung

agent.py

Die Tool-Calling-Schleife und die einzige Datei, die weiß, welcher Modellanbieter verwendet wird

mcp_server.py

Dieselben Tools über MCP. Keine eigene Implementierung

docs/

Das Korpus. Frontmatter enthält die role jedes Dokuments

Drei Entscheidungen, die eine Verteidigung wert sind

Die Rolle des Aufrufers ist kein Tool-Parameter. Sie wird out-of-band gebunden, bevor der Turn beginnt. Hätte search_docs(query, role) existiert, hätte das Modell seine eigene Freigabe in der Hand, und ein Satz in einem abgerufenen Dokument, der ihm sagt, es solle „role=admin verwenden“, wäre ein Eskalationspfad. Es gibt nichts zu übergeben, also gibt es auch nichts, wozu man es überreden könnte.

Der Freigabefilter läuft auf der Kandidatenmenge, nicht auf den Ergebnissen. Ein Chunk, den der Aufrufer nicht sehen darf, gelangt nie in das Ranking, sodass seine Existenz weder aus einer Lücke in den Ergebnissen noch aus einem veränderten Score abgeleitet werden kann.

TF-IDF, keine Embeddings. Das ist die Baseline, die zu schlagen Layer 3 existiert. Einen semantischen Retriever einzubauen, bevor es einen Goldstandard gibt, wäre eine Vermutung; es danach zu tun, erzeugt eine Zahl, die die Änderung rechtfertigt. Der Austauschpunkt ist Index.

MCP

mcp_server.py registriert die Funktionen aus tools.py und fügt nichts weiter hinzu – das ist das Argument für MCP in einer Datei: eine Implementierung, ein Satz von Zugriffsregeln, viele Clients. Füge das zur Konfiguration eines Clients hinzu:

{
  "mcpServers": {
    "rbac-rag-assistant": {
      "command": "C:\\Users\\Shrey\\Documents\\CLAUDE CODE\\rbac-rag-assistant\\.venv\\Scripts\\python.exe",
      "args": ["C:\\Users\\Shrey\\Documents\\CLAUDE CODE\\rbac-rag-assistant\\mcp_server.py"],
      "env": { "KB_ROLE": "staff" }
    }
  }
}

Ein MCP-Client hat keinen Begriff von einer Universitätsrolle, daher wird KB_ROLE einmal beim Start gelesen und gilt für die gesamte Verbindung. Die Rolle gehört zum Serverprozess und nicht zum Gespräch – genau das verhindert, dass das Modell sie wählen kann.

Verhalten bei Zugriffsverweigerung

Ein Student, der nach Material fragt, das nur für Mitarbeitende bestimmt ist, bekommt gesagt, dass das Material existiert und dass er nicht dafür freigegeben ist, statt dass ihm gesagt wird, es existiere nichts (ADR-7). Live verifiziert:

Hinweise dazu, was zu tun ist, wenn du vermutest, dass dein Konto kompromittiert wurde, finden sich in der Richtliniendokumentation der Universität, aber der Zugriff darauf erfordert eine Freigabe für Mitarbeitende. Bitte wende dich an das Büro, dem diese Richtlinie gehört.

Was die Grenze überschreitet, ist ein Klassifikationslabel und sonst nichts. Keine Passage, kein Titel, kein Dateiname. Eine Frage, die kein Dokument abdeckt, erhält eine andere Antwort – genau darum geht es bei der Unterscheidung.

Was mich überrascht hat

Eins. faculty compensation bands lieferte für einen Administrator nichts, während professor salary dasselbe Dokument mit 0,29 zurückgab. Diese drei Wörter kommen nur im Titel des Dokuments vor, und parse() hebt den Titel vor der Indizierung aus dem Textkörper in die Metadaten. Nutzer suchen weitaus häufiger mit dem Titel eines Dokuments als mit dessen Wortlaut, daher war die natürlichste Abfrage für das sensibelste Dokument genau die, die garantiert scheitern musste. Eine Zeile zum Beheben: title + text indizieren, text speichern.

Es ist wegen des Ortes, an dem es gefunden wurde, eine Aufzeichnung wert. Die Zugriffskontrolltests bestanden durchgehend, einschließlich des Tests, der besagt, dass ein Student niemals vertrauliche Inhalte sieht – was trivialerweise wahr war, als niemand das Dokument überhaupt abrufen konnte. Ein Test, der besteht, weil nichts zurückgegeben wurde, sieht identisch aus mit einem Test, der besteht, weil die Regel funktioniert.

Zwei, gefunden bei der Implementierung von ADR-7. Die Meldung „eingeschränktes Material ist vorhanden“ wird bei harmlosen Fragen ausgelöst. „Wer ist hier ordentlicher Professor“ erzielt 0,28 gegenüber den Vergütungsbändern, was höher ist als ein legitimer Treffer für Mitarbeitende mit 0,19. Kein Schwellenwert trennt sie, daher ist das nicht justierbar; es ist lexikalisches Matching, das ein gemeinsames Wort nicht von einer gemeinsamen Bedeutung unterscheiden kann. Nichts leakt, und die Antwort ist trotzdem falsch. Das Erste, was Layer 3 messen muss.

Drei. Das Modell füllt kleine Lücken, die die Dokumente nicht abdecken. Auf die Frage nach einem kompromittierten Konto schlug es vor, sich an „den IT-Service-Desk oder das IT-Security-Team“ zu wenden, obwohl das Tool nur „das Büro, dem die Richtlinie gehört“ gesagt hatte. Plausibel, hier harmlos und nicht in abgerufenen Inhalten begründet. Genau das ist das Verhalten, das ein Groundedness-Scorer erkennen soll, und es trat innerhalb der ersten fünf Live-Fragen auf.

Umgebung

Variable

Default

GEMINI_API_KEY

Nur von agent.py benötigt

KB_MODEL

gemini-3.6-flash

Gepinnt, kein Alias. ADR-8

KB_ROLE

student

Nur MCP-Server

KB_DOCS

docs

Korpusverzeichnis

KB_TICKETS

tickets.jsonl

Ticket-Log

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

0Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

View all related MCP servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Shrey-Parikh31/rbac-rag-assistant'

If you have feedback or need assistance with the MCP directory API, please join our Discord server