04 / 10

How would you scope access so that a client application can only query a specific collection and cannot list or modify others?

Use granular access API keys (JWT RBAC) with per-collection permissions

The static read-only and read-write API keys do not provide per-collection scoping - a read-only key can read all collections, and a read-write key can modify all of them. To scope access to a specific collection, you need granular access API keys, which use JWT (JSON Web Token) and are supported in Qdrant 1.9 and later. To enable them, you set jwt_rbac: true in the service configuration and provide an api_key that serves as the JWT signing secret. You then generate JWT tokens with an access claim that specifies which collections the token can access and at what level (read, read-write, or point read-write). The client presents the JWT as its API key, and Qdrant validates the signature and enforces the permissions at the server level[reference:19][reference:20]. This is the mechanism for least-privilege access in multi-application deployments where different services need different scopes.

The JWT access claim has evolved across versions, and this is a critical version-dependent detail. The older format supported a payload filter within the access claim, which allowed row-level scoping inside a shared collection. Qdrant deprecated that capability in version 1.15 and removed it in 1.16 because it could not provide safe semantics for write operations[reference:21]. The current granular JWT supports collection-level scoping: you specify a list of collections and the access level for each. The access levels are r (read), rw (read-write), and prw (point read-write, which permits point reads and writes but not collection-level operations like snapshot creation or payload index management)[reference:22]. If you need tenant-level isolation within a shared collection, you cannot rely on the JWT to enforce it - you must either give each tenant its own collection and issue a collection-scoped JWT, or place a trusted service in front of Qdrant that injects the tenant filter on every operation[reference:23]. The JWT RBAC boundary is the collection, not the payload field.

  1. 1

    Enable JWT RBAC: set jwt_rbac: true and an api_key that serves as the signing secret.

  2. 2

    Generate tokens with an access claim listing collections and permission levels: r, rw, or prw.

  3. 3

    Read-only for a specific collection: access: [{collection: 'docs', access: 'r'}].

  4. 4

    Read-write for a specific collection: access: [{collection: 'docs', access: 'rw'}].

  5. 5

    Point read-write: access: [{collection: 'docs', access: 'prw'}] - points only, no collection-level ops.

  6. 6

    JWT payload is not encrypted (base64-encoded); never put secrets in claims.

  7. 7

    JWT validation requires the server to be configured with the matching signing secret; otherwise claims are ignored and the client gets full access.

  8. 8

    Payload-level (row-level) scoping within a shared collection is not supported in current versions; use separate collections or a trusted filter-injecting service.

The trade-off is complexity and version sensitivity against granular control. JWT RBAC adds a token generation and distribution layer to the architecture, and the token payload is not encrypted - anyone who can read the token can see its claims. The security benefit is significant: a client application can be given a token that can only read a specific collection, so a compromise of that application cannot list other collections, modify data, or create snapshots. The common mistake is assuming the JWT payload filter still works - it was deprecated in 1.15 and removed in 1.16, and a legacy example copied into a current deployment will produce a token that either fails validation or does not enforce the intended restriction[reference:24]. The second mistake is using a JWT signing key that is also used for other purposes or is weak; anyone who can read the signing key can mint administrative tokens, so tenant-facing services must never receive it[reference:25]. The third mistake is forgetting to configure the server-side jwt_rbac and signing secret - if the server is not configured to validate JWTs, it ignores the claims entirely and treats the token as an API key with full access[reference:26]. The alternative to JWT RBAC is a proxy layer that authenticates and authorizes requests before they reach Qdrant, which gives more flexibility but adds a component and a latency hop. Version note: JWT RBAC requires Qdrant 1.9 or later, and the access claim format has changed - specifically, the payload filter capability was deprecated in 1.15 and removed in 1.16.

javascript
javascript

Version-dependent: JWT RBAC requires Qdrant 1.9 or later. The access claim format has changed across versions: the payload filter capability was deprecated in 1.15 and removed in 1.16, and the prw access level was added in a recent release. Qdrant Cloud clusters created before January 27, 2025 may require granular access to be enabled from the Cloud console[reference:27]. If you are on an older version and need payload-level scoping, the only safe pattern is separate collections per tenant or a trusted service that injects and filters tenant_id on every operation.

Difficulty: 8/10
Topics: JWT RBAC, API Keys, Least Privilege

Scenario Questions

0-2 years experience
  1. 1

    You need to give a client application read access to one collection. Explain why the static read-only key is insufficient and what you would use instead.

  2. 2

    A teammate copies a JWT example from an old blog post that uses a payload filter. Explain why it will not work on a current Qdrant version.

2-5 years experience
  1. 1

    You have three applications that each need access to a different collection. Describe how you would generate and distribute JWTs for each and how you would rotate them.

  2. 2

    A service reports 401 errors after you enable JWT RBAC. Walk through the likely causes and how you would diagnose them.

5-8 years experience
  1. 1

    Design an access control scheme for a multi-tenant SaaS platform where each tenant has its own collection and a per-tenant query service. Specify the token generation, distribution, and rotation strategy.

  2. 2

    You are migrating from static API keys to JWT RBAC. Describe the migration plan, including how you validate that no service is broken and how you handle the transition period.

8+ years experience
  1. 1

    You need to enforce tenant isolation within a shared collection, but JWT RBAC no longer supports payload filters. Describe the architecture you would build to achieve this securely, including how you prevent a direct client from bypassing the filter.

  2. 2

    You are designing a token service for a platform with thousands of tenants and collections. Describe the token generation, caching, rotation, and revocation strategy, and how you handle the failure modes.

Follow-up Questions

  • How would you rotate JWT signing keys across a fleet of clients without invalidating all existing tokens at once?
  • If a client needs read access to one collection and write access to a different collection, how would you encode that in a single token?