From df796be23c7f03bc20c00bbb696fc22d0170d261 Mon Sep 17 00:00:00 2001 From: Mac Chaffee Date: Tue, 16 Jul 2024 14:18:13 -0400 Subject: [PATCH] Add info about network hardening for Qdrant --- .../content/documentation/guides/security.md | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/qdrant-landing/content/documentation/guides/security.md b/qdrant-landing/content/documentation/guides/security.md index 58ae371b6..3f49c3b71 100644 --- a/qdrant-landing/content/documentation/guides/security.md +++ b/qdrant-landing/content/documentation/guides/security.md @@ -134,7 +134,7 @@ Both API keys can be used simultaneously. *Available as of v1.9.0* -For more complex cases, Qdrant supports granular access control with [JSON Web Tokens (JWT)](https://jwt.io/). +For more complex cases, Qdrant supports granular access control with [JSON Web Tokens (JWT)](https://jwt.io/). This allows you to have tokens, which allow restricited access to a specific parts of the stored data and build [Role-based access control (RBAC)](https://en.wikipedia.org/wiki/Role-based_access_control) on top of that. In this way, you can define permissions for users and restrict access to sensitive endpoints. @@ -149,7 +149,7 @@ service: Or with the environment variables: ```bash -export QDRANT__SERVICE__API_KEY=your_secret_api_key_here +export QDRANT__SERVICE__API_KEY=your_secret_api_key_here export QDRANT__SERVICE__JWT_RBAC=true ``` @@ -266,7 +266,7 @@ These are the available options, or **claims** in the JWT lingo. You can use the ``` - **`value_exists`** - This is a claim that can be used to validate the token against the data stored in a collection. Structure of this claim is as follows: - + ```json { "value_exists": { @@ -279,7 +279,7 @@ These are the available options, or **claims** in the JWT lingo. You can use the ``` If this claim is present, Qdrant will check if there is a point in the collection with the specified key-values. If it does, the token is valid. - + This claim is especially useful if you want to have an ability to revoke tokens without changing the `api_key`. Consider a case where you have a collection of users, and you want to revoke access to a specific user. @@ -336,10 +336,10 @@ These are the available options, or **claims** in the JWT lingo. You can use the } ``` - This `payload` claim will be used to implicitly filter the points in the collection. It will be equivalent to appending this filter to each request: + This `payload` claim will be used to implicitly filter the points in the collection. It will be equivalent to appending this filter to each request: - ```json - { "filter": { "must": [{ "key": "user_id", "match": { "value": "user_123456" } }] } } + ```json + { "filter": { "must": [{ "key": "user_id", "match": { "value": "user_123456" } }] } } ``` ### Table of access @@ -352,7 +352,7 @@ This is also applicable to using api keys instead of tokens. In that case, `api_ | Action | manage | read-only | collection read-write | collection read-only | collection with payload claim (r / rw) | |--------|--------|-----------|----------------------|-----------------------|------------------------------------| -| list collections | ✅ | ✅ | 🟡 | 🟡 | 🟡 | +| list collections | ✅ | ✅ | 🟡 | 🟡 | 🟡 | | get collection info | ✅ | ✅ | ✅ | ✅ | ❌ | | create collection | ✅ | ❌ | ❌ | ❌ | ❌ | | delete collection | ✅ | ❌ | ❌ | ❌ | ❌ | @@ -523,4 +523,9 @@ We recommend reducing the amount of permissions granted to Qdrant containers so - You can set [`read_only: true`](https://docs.docker.com/compose/compose-file/05-services/#read_only) when using Docker Compose. - You can set [`readOnlyRootFilesystem: true`](https://kubernetes.io/docs/tasks/configure-pod-container/security-context) when running in Kubernetes (our [Helm chart](https://github.com/qdrant/qdrant-helm) does this by default). -There are other techniques for reducing the permissions such as dropping [Linux capabilities](https://www.man7.org/linux/man-pages/man7/capabilities.7.html) depending on your deployment method, but running as a non-root user with a read-only root file system are the two most important. +* Block Qdrant's external network access. This can help mitigate [server side request forgery attacks](https://owasp.org/www-community/attacks/Server_Side_Request_Forgery), like via the [snapshot recovery API](https://api.qdrant.tech/api-reference/snapshots/recover-from-snapshot). Single-node Qdrant clusters do not require any outbound network access. Multi-node Qdrant clusters only need the ability to connect to other Qdrant nodes via TCP ports 6333, 6334, and 6335. + - You can use [`docker network create --internal `](https://docs.docker.com/reference/cli/docker/network/create/#internal) and use that network when running [`docker run --network `](https://docs.docker.com/reference/cli/docker/container/run/#network). + - You can create an [internal network](https://docs.docker.com/compose/compose-file/06-networks/#internal) when using Docker Compose. + - You can create a [NetworkPolicy](https://kubernetes.io/docs/concepts/services-networking/network-policies/) when using Kubernetes. Note that multi-node Qdrant clusters [will also need access to cluster DNS in Kubernetes](https://github.com/ahmetb/kubernetes-network-policy-recipes/blob/master/11-deny-egress-traffic-from-an-application.md#allowing-dns-traffic). + +There are other techniques for reducing the permissions such as dropping [Linux capabilities](https://www.man7.org/linux/man-pages/man7/capabilities.7.html) depending on your deployment method, but the methods mentioned above are the most important.