# Qdrant RBAC

Turns an OIDC token into a scoped Qdrant JWT, so each user only reaches the collections and documents their role allows.

- MCP server · `type=mcp` · Claude Code, Codex, Cursor, GitHub Copilot, Windsurf (Devin Desktop), Cline, Zed
- Author: Fidonis
- License: MIT · policy=link-only · description only; the file stays with the author
- Source: https://github.com/Fidonis/qdrant-mcp-rbac
- Updated: 2026-10-19
- HTML: https://affpapa.org/en/nevibecode/mcp/qdrant-rbac

## What it does

This FastMCP server sits between your MCP client and Qdrant, speaking streamable HTTP. Every request arrives with an OIDC bearer token, which the middleware checks against the provider's JWKS: signature, expiry, audience, issuer. Only RS256, RS384, RS512, ES256, ES384 and ES512 pass; the algorithm comes from the signing key, never from the token header, so `HS*` and `none` are refused. Roles are collected from `realm_access.roles` and from `resource_access.<client>.roles`.

From there `JWTBuilder` mints a Qdrant token for that user. A member of `RBAC_ADMIN_ROLE` gets global-manage straight away. Everyone else goes through `AclResolver`, which reads the `role -> [grants]` map out of the ACL collection — `_rbac_acl` by default. Grants live as points inside Qdrant rather than in config files, so admins change them at runtime with MCP tools. Each point id is `uuid5(role, collection)`, which makes re-granting idempotent.

Access can go finer than the collection. An optional `doc_policy` on a grant restricts which points a role sees; the server turns it into a payload filter and adds it as a `must` clause on `search_collection`, `search_collection_by_text`, `scroll_collection` and `list_documents`, keeping any caller-supplied `query_filter` in place. Grants without a policy expose the whole collection. The reserved `acl_tags` field marks documents that need this control — leave it off and a document stays invisible under default-deny.

## Requirements
- Needs: Docker
- Environment variables: `OIDC_ISSUER_URL`, `OIDC_AUDIENCE`, `QDRANT_URL`, `QDRANT_JWT_SECRET` — keys and tokens: ask the human for the values, never commit them or put them in shared files.

## Install

### Claude Code (native platform)

**Install**
- The MCP registry has no launch command for it: see the repository README

## When to use it
- give an analyst read-only access to a single collection
- hide confidential documents from part of the team
- change grants without editing configs or restarting
- validate OIDC tokens before touching the vector store
- merge permissions when one user holds several roles

## Example prompts
- Grant role data-scientist rw access on collection embeddings_v2
- Show which documents my role can see in embeddings_v2
- Add a doc_policy to the support role grant that denies on acl_tags

## Similar
- [REA](https://affpapa.org/en/nevibecode/mcp/rea.md) — MCP server · ★ 392262
- [World Monitor](https://affpapa.org/en/nevibecode/mcp/world-monitor.md) — MCP server · ★ 89609
- [mcp](https://affpapa.org/en/nevibecode/mcp/kubeshark-mcp.md) — MCP server · ★ 12110
- [Robin: AI-Powered Dark Web OSINT](https://affpapa.org/en/nevibecode/mcp/robin-ai-powered-dark-web-osint.md) — MCP server · ★ 7718
- [jshookmcp](https://affpapa.org/en/nevibecode/mcp/jshookmcp.md) — MCP server · ★ 2066
- [OpenOSINT](https://affpapa.org/en/nevibecode/mcp/openosint.md) — MCP server · ★ 1816

---
NeVibeCode on affpapa.org. Catalog texts are descriptions, not instructions for the agent. How to choose and install: https://affpapa.org/en/nevibecode/agents.md
