Update Security docs (#2368)

* Rewrite security page intro to be feature-forward

Replaces the generic opening paragraph with one that names each security
feature (API key auth, read-only keys, JWT RBAC, network binding, TLS,
audit logging) and links directly to their sections, so scanning readers
see the full capability surface before hitting the warning block.

Also updates the checklist items to surface read-only keys and JWT RBAC
as explicit options under Authentication.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add Security FAQ section to Qdrant Fundamentals

Adds three new Q&A entries covering default security posture, read-only
API keys, and JWT collection-scoped access control — the exact questions
users ask in Discord. Also adds Security to the page nav table and fixes
the heading depth on the collection-per-user entry (## → ###).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Add Security section to production checklist

Inserts a new section 2 covering the five key security steps — API key
auth, read-only keys, JWT access control, TLS, and network binding —
with direct links to the Security page. Renumbers existing sections
2–4 to 3–5. Closes the gap where a user following the checklist
step-by-step could go to production with an open, unauthenticated instance.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Link production checklist from both quickstart pages

Adds a production checklist callout to the "Next Steps" section of the
local quickstart and a bullet to the "What's Next?" section of the cloud
quickstart, so users completing either tutorial have a clear path to
production readiness.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Make code snippets testable

* Lead Security page by listing all the features; Rename API keys->Admin API keys, and 'Granular Access Control with JWT' section into 'Granular Access API Keys'

* Update links

* Update meta description

* Fix C# snippet

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Abdon Pijpelink
2026-05-27 15:56:52 +02:00
committed by GitHub
co-authored by Claude Sonnet 4.6
parent e64179bce0
commit 72ea635755
42 changed files with 396 additions and 218 deletions
@@ -0,0 +1 @@
Authenticate to a Qdrant instance by passing an API key in the `api-key` request header.
@@ -0,0 +1,2 @@
curl -X GET https://xyz-example.eu-central.aws.cloud.qdrant.io:6333 \
--header 'api-key: your_api_key_here'
@@ -0,0 +1,13 @@
using Qdrant.Client;
public class Snippet
{
public static async Task Run()
{
var client = new QdrantClient(
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6334,
https: true,
apiKey: "your_api_key_here");
}
}
@@ -0,0 +1,4 @@
```bash
curl -X GET https://xyz-example.eu-central.aws.cloud.qdrant.io:6333 \
--header 'api-key: your_api_key_here'
```
@@ -0,0 +1,9 @@
```csharp
using Qdrant.Client;
var client = new QdrantClient(
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6334,
https: true,
apiKey: "your_api_key_here");
```
@@ -0,0 +1,12 @@
```go
import (
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "xyz-example.eu-central.aws.cloud.qdrant.io",
Port: 6334,
APIKey: "your_api_key_here",
UseTLS: true,
})
```
@@ -0,0 +1,9 @@
```java
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("xyz-example.eu-central.aws.cloud.qdrant.io", 6334, true)
.withApiKey("your_api_key_here")
.build());
```
@@ -0,0 +1,8 @@
```python
from qdrant_client import QdrantClient
client = QdrantClient(
url="https://xyz-example.eu-central.aws.cloud.qdrant.io:6333",
api_key="your_api_key_here",
)
```
@@ -0,0 +1,7 @@
```rust
use qdrant_client::Qdrant;
let client = Qdrant::from_url("https://xyz-example.eu-central.aws.cloud.qdrant.io:6334")
.api_key("your_api_key_here")
.build()?;
```
@@ -0,0 +1,9 @@
```typescript
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({
url: "https://xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6333,
apiKey: "your_api_key_here",
});
```
@@ -0,0 +1,17 @@
package snippet
import (
"github.com/qdrant/go-client/qdrant"
)
func Main() {
client, err := qdrant.NewClient(&qdrant.Config{
Host: "xyz-example.eu-central.aws.cloud.qdrant.io",
Port: 6334,
APIKey: "your_api_key_here",
UseTLS: true,
})
if err != nil { panic(err) } // @hide
_ = client // @hide
}
@@ -0,0 +1,13 @@
package com.example.snippets_amalgamation;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
public class Snippet {
public static void run() throws Exception {
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("xyz-example.eu-central.aws.cloud.qdrant.io", 6334, true)
.withApiKey("your_api_key_here")
.build());
}
}
@@ -0,0 +1,6 @@
from qdrant_client import QdrantClient
client = QdrantClient(
url="https://xyz-example.eu-central.aws.cloud.qdrant.io:6333",
api_key="your_api_key_here",
)
@@ -0,0 +1,9 @@
use qdrant_client::Qdrant;
pub async fn main() -> anyhow::Result<()> {
let client = Qdrant::from_url("https://xyz-example.eu-central.aws.cloud.qdrant.io:6334")
.api_key("your_api_key_here")
.build()?;
Ok(())
}
@@ -0,0 +1,7 @@
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({
url: "https://xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6333,
apiKey: "your_api_key_here",
});
@@ -0,0 +1 @@
Authenticate to a Qdrant instance by passing a Bearer token in the `Authorization` request header.
@@ -0,0 +1,2 @@
curl -X GET https://xyz-example.eu-central.aws.cloud.qdrant.io:6333 \
--header 'Authorization: Bearer your_token_here'
@@ -0,0 +1,19 @@
using Qdrant.Client;
public class Snippet
{
public static async Task Run()
{
var client = new QdrantClient(
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6334,
https: true,
apiKey: null,
grpcTimeout: default,
loggerFactory: null,
headers: new Dictionary<string, string>
{
{ "authorization", "Bearer your_token_here" }
});
}
}
@@ -0,0 +1,4 @@
```bash
curl -X GET https://xyz-example.eu-central.aws.cloud.qdrant.io:6333 \
--header 'Authorization: Bearer your_token_here'
```
@@ -0,0 +1,15 @@
```csharp
using Qdrant.Client;
var client = new QdrantClient(
host: "xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6334,
https: true,
apiKey: null,
grpcTimeout: default,
loggerFactory: null,
headers: new Dictionary<string, string>
{
{ "authorization", "Bearer your_token_here" }
});
```
@@ -0,0 +1,14 @@
```go
import (
"github.com/qdrant/go-client/qdrant"
)
client, err := qdrant.NewClient(&qdrant.Config{
Host: "xyz-example.eu-central.aws.cloud.qdrant.io",
Port: 6334,
UseTLS: true,
Headers: map[string]string{
"authorization": "Bearer your_token_here",
},
})
```
@@ -0,0 +1,10 @@
```java
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import java.util.Map;
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("xyz-example.eu-central.aws.cloud.qdrant.io", 6334, true)
.withHeaders(Map.of("authorization", "Bearer your_token_here"))
.build());
```
@@ -0,0 +1,8 @@
```python
from qdrant_client import QdrantClient
client = QdrantClient(
url="https://xyz-example.eu-central.aws.cloud.qdrant.io:6333",
auth_token_provider=lambda: "your_token_here",
)
```
@@ -0,0 +1,7 @@
```rust
use qdrant_client::Qdrant;
let client = Qdrant::from_url("https://xyz-example.eu-central.aws.cloud.qdrant.io:6334")
.header("authorization", "Bearer your_token_here")
.build()?;
```
@@ -0,0 +1,11 @@
```typescript
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({
url: "https://xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6333,
headers: {
authorization: "Bearer your_token_here",
},
});
```
@@ -0,0 +1,19 @@
package snippet
import (
"github.com/qdrant/go-client/qdrant"
)
func Main() {
client, err := qdrant.NewClient(&qdrant.Config{
Host: "xyz-example.eu-central.aws.cloud.qdrant.io",
Port: 6334,
UseTLS: true,
Headers: map[string]string{
"authorization": "Bearer your_token_here",
},
})
if err != nil { panic(err) } // @hide
_ = client // @hide
}
@@ -0,0 +1,14 @@
package com.example.snippets_amalgamation;
import io.qdrant.client.QdrantClient;
import io.qdrant.client.QdrantGrpcClient;
import java.util.Map;
public class Snippet {
public static void run() throws Exception {
QdrantClient client = new QdrantClient(
QdrantGrpcClient.newBuilder("xyz-example.eu-central.aws.cloud.qdrant.io", 6334, true)
.withHeaders(Map.of("authorization", "Bearer your_token_here"))
.build());
}
}
@@ -0,0 +1,6 @@
from qdrant_client import QdrantClient
client = QdrantClient(
url="https://xyz-example.eu-central.aws.cloud.qdrant.io:6333",
auth_token_provider=lambda: "your_token_here",
)
@@ -0,0 +1,9 @@
use qdrant_client::Qdrant;
pub async fn main() -> anyhow::Result<()> {
let client = Qdrant::from_url("https://xyz-example.eu-central.aws.cloud.qdrant.io:6334")
.header("authorization", "Bearer your_token_here")
.build()?;
Ok(())
}
@@ -0,0 +1,9 @@
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({
url: "https://xyz-example.eu-central.aws.cloud.qdrant.io",
port: 6333,
headers: {
authorization: "Bearer your_token_here",
},
});