Databases

Secure Weaviate with cnspec

Scan Weaviate vector databases and their role-based access control against security best practices with cnspec.

Scan your Weaviate vector databases to find security risks before they become incidents. cnspec evaluates anonymous access, OIDC configuration, role-based access control and the permissions each role grants, users and their assignments, collection multi-tenancy and replication, enabled modules, and cluster node health.

cnspec inventories the server through read-only requests to the REST API. It never reads your vectors.

Weaviate has no published CIS benchmark. The resources target the security-relevant configuration surface: anonymous access, authentication and OIDC, RBAC least-privilege, multi-tenancy isolation, and replication.

If you're new to cnspec, start with the Quickstart. For an overview of every database cnspec can scan, see the database scanning overview.

Prerequisites

To scan Weaviate with cnspec, you must have:

Authenticate

cnspec authenticates with a Weaviate API key, sent as a bearer token:

cnspec shell weaviate weaviate.contoso.com --api-key API_KEY

Use --ask-api-key to be prompted rather than passing the key as a flag. For a server behind a private CA:

cnspec shell weaviate weaviate.contoso.com --scheme https --api-key API_KEY --tls-ca ca.pem

Prefer a least-privileged API key for auditing. The built-in viewer role reads everything below. A more restricted key still resolves the server metadata, and the roles, users, and node collections it cannot read come back empty rather than failing the scan.

Where the server allows anonymous access, the API key can be omitted entirely, which is itself the first thing worth checking.

Connection options

OptionDescription
--hostServer hostname or IP address (also accepted as the positional argument)
--portREST API port (default 8080)
--schemehttp (default) or https
--api-keyAPI key to authenticate with, or --ask-api-key to be prompted
--tls-caPath to a CA certificate to verify an https server with a private CA
--tls-insecureSkip TLS certificate verification (testing only)
--discoverauto (default), all, collections, instance, or none

Verify with a quick Weaviate check

cnspec shell weaviate weaviate.contoso.com --api-key API_KEY
cnspec> weaviate.instance { version rbacEnabled anonymousAccessEnabled oidcEnabled }
weaviate.instance: {
  version: "1.38.9"
  rbacEnabled: true
  anonymousAccessEnabled: false
  oidcEnabled: false
}

If cnspec connects and shows the version, you're ready to scan.

Scan Weaviate

By default cnspec discovers each collection as its own weaviate-collection asset alongside the server asset:

cnspec scan weaviate weaviate.contoso.com --api-key API_KEY

To scan the server only:

cnspec scan weaviate weaviate.contoso.com --api-key API_KEY --discover none

When a scan completes, cnspec prints a summary of all the checks it ran, grouped by policy, along with a risk score from 0 (no risk) to 100 (highest risk). Failed checks include remediation guidance to help you fix issues. To learn more about reading scan results, read Understand cnspec Results.

Mondoo doesn't yet ship an out-of-the-box Weaviate policy, so use the checks below as a starting point and create your own policies to meet your specific requirements.

Explore and test checks interactively

cnspec shell weaviate weaviate.contoso.com --api-key API_KEY

List collections

cnspec> weaviate.instance.collections { name vectorizer vectorIndexType replicationFactor multiTenancyEnabled }

List custom roles

cnspec> weaviate.instance.roles.where(isBuiltin == false) { name assignedUsers }

Inspect what a role permits

cnspec> weaviate.instance.roles.where(name == "articleReader").first { permissions { action collection } assignedUsers }
weaviate.instance.roles.where.first: {
  permissions: [
    0: { action: "read_data"        collection: "Article" }
    1: { action: "read_collections" collection: "Article" }
  ]
  assignedUsers: [
    0: "viewer-user"
  ]
}

List users

cnspec> weaviate.instance.users { userId userType active roles { name } }

List enabled modules and nodes

cnspec> weaviate.instance { modules nodes { name status shardCount objectCount } }

Example security checks

Ensure anonymous access is disabled

Anonymous access means anyone who can reach the port can query the vectors:

cnspec> weaviate.instance.anonymousAccessEnabled == false
[ok] value: true

Ensure role-based access control is enabled

Without RBAC, every authenticated caller holds the same access:

cnspec> weaviate.instance.rbacEnabled == true
[ok] value: true

Ensure OIDC is configured

OIDC moves authentication to your identity provider, so accounts follow joiners and leavers:

cnspec> weaviate.instance.oidcEnabled == true
[ok] value: true

Ensure no custom role reaches every collection

A * collection scope grants the action across everything, including collections created later:

cnspec> weaviate.instance.roles.where(isBuiltin == false).all(permissions.none(collection == "*"))
[ok] value: true

Ensure no custom role can manage roles

manage_roles lets the holder grant itself anything else:

cnspec> weaviate.instance.roles.where(isBuiltin == false).all(permissions.none(action == "manage_roles"))
[ok] value: true

Ensure the root role is held narrowly

cnspec> weaviate.instance.roles.where(name == "root") { assignedUsers }

Ensure multi-tenant collections do not create tenants on demand

autoTenantCreation materializes a tenant on first use, so a caller naming an unknown tenant gets a working one rather than an error:

cnspec> weaviate.instance.collections.where(multiTenancyEnabled).none(autoTenantCreation == true)
[ok] value: true

Ensure collections are replicated

A replicationFactor of 1 means a single node loss takes the collection with it:

cnspec> weaviate.instance.collections.all(replicationFactor > 1)
[ok] value: true

Ensure every user is accounted for

cnspec> weaviate.instance.users.where(active == false) { userId userType }

Ensure all nodes are healthy

cnspec> weaviate.instance.nodes.all(status == "HEALTHY")
[ok] value: true

Review collections that send data to an external vectorizer

A vectorizer module other than none sends object text to whatever service backs it, which may be outside your boundary:

cnspec> weaviate.instance.collections.where(vectorizer != "none") { name vectorizer modules }

Learn more

On this page