| name | security | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| summary | Couchbase Server security — RBAC users, roles, least-privilege application credentials, TLS configuration, and encryption at rest | ||||||||||||||||||||||||||
| description | Couchbase Server security — RBAC users, roles, least-privilege application credentials, TLS configuration, and encryption at rest | ||||||||||||||||||||||||||
| allowed-tools | Bash | ||||||||||||||||||||||||||
| compatibility | Requires Couchbase Server 5.0+ (RBAC). TLS requires certificates configured on the cluster. | ||||||||||||||||||||||||||
| metadata |
|
User → Roles → Privileges → Resources
Resources can be scoped to cluster, bucket, scope, or collection. Always grant the minimum scope needed — prefer collection-level roles for application users.
| Role | Internal name | Grants |
|---|---|---|
| Data Reader | data_reader |
KV GET |
| Data Writer | data_writer |
KV SET, DELETE |
| Data DCP Reader | data_dcp_reader |
DCP stream (Eventing, Analytics, XDCR) |
| Role | Internal name |
|---|---|
| Query Select | query_select |
| Query Insert | query_insert |
| Query Update | query_update |
| Query Delete | query_delete |
| Query Manage Index | query_manage_index |
| Role | Internal name |
|---|---|
| Search Reader | fts_searcher |
| Search Admin | fts_admin |
| Analytics Reader | analytics_reader |
| Eventing Manage Functions | eventing_manage_functions |
admin (full), bucket_admin (one bucket), ro_admin (read-only)
Role format: role_name[bucket:scope:collection] — use * for wildcard.
# OLTP application user
curl -X PUT http://localhost:8091/settings/rbac/users/local/myapp-service \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "password=AppSecret123!&roles=data_reader[myapp:_default:users],data_writer[myapp:_default:users],query_select[myapp:_default:users],query_insert[myapp:_default:users],query_update[myapp:_default:users]"
# Read-only reporting user
curl -X PUT http://localhost:8091/settings/rbac/users/local/reporting \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "password=Report123!&roles=query_select[myapp:*:*],data_reader[myapp:*:*]"
# Microservice scoped to its own scope
curl -X PUT http://localhost:8091/settings/rbac/users/local/auth-service \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "password=AuthSecret!&roles=data_reader[platform:auth-service:*],data_writer[platform:auth-service:*],query_select[platform:auth-service:*],query_insert[platform:auth-service:*],query_update[platform:auth-service:*],query_delete[platform:auth-service:*]"
# Eventing function user
curl -X PUT http://localhost:8091/settings/rbac/users/local/eventing-enricher \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "password=EventSecret!&roles=data_dcp_reader[myapp:_default:orders],data_reader[myapp:_default:products],data_writer[myapp:_default:orders],eventing_manage_functions"curl -X PUT http://localhost:8091/settings/rbac/groups/app-developers \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "roles=query_select[myapp:*:*],data_reader[myapp:*:*],query_manage_index[myapp:*:*]"
curl -X PUT http://localhost:8091/settings/rbac/users/local/alice \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "password=Alice123!&groups=app-developers"Authenticate users against OpenLDAP or Active Directory. Use local users for application service accounts — LDAP adds latency and a dependency on the LDAP server.
# Enable LDAP with DN template
curl -X POST http://localhost:8091/settings/ldap -u Administrator:"$CB_ADMIN_PASSWORD" \
-d "authenticationEnabled=true&userDNMapping=template" \
-d "userDNMappingTemplate=uid=%u,ou=users,dc=example,dc=com" \
-d "hosts=ldap.example.com&port=389&encryption=StartTLS"
# Enable group support
curl -X POST http://localhost:8091/settings/ldap -u Administrator:"$CB_ADMIN_PASSWORD" \
-d "authorizationEnabled=true" \
-d "groupsQuery=ou=groups,dc=example,dc=com?cn?sub?(member=uid=%u,ou=users,dc=example,dc=com)"
# Map LDAP group to Couchbase group
curl -X PUT http://localhost:8091/settings/rbac/groups/ldap-developers \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "roles=query_select[myapp:*:*],data_reader[myapp:*:*]" \
-d "ldap_group_ref=cn=developers,ou=groups,dc=example,dc=com"
# External user (no password — LDAP authenticates)
curl -X PUT http://localhost:8091/settings/rbac/users/external/alice \
-u Administrator:"$CB_ADMIN_PASSWORD" -d "roles=query_select[myapp:*:*]"SAML 2.0 for Web Console login only — not for SDK connections.
curl -X POST http://localhost:8091/settings/saml -u Administrator:"$CB_ADMIN_PASSWORD" \
-d "enabled=true" \
-d "idpMetadataURL=https://myidp.example.com/sso/saml/metadata" \
-d "spBaseURLScheme=https&spBaseURLType=node" \
-d "groupsAttribute=memberOf&usernameAttribute=email" \
--data-urlencode "spCertificate@/path/to/sp-cert.pem" \
--data-urlencode "spKey@/path/to/sp-key.pem"Response includes spMetadataURL — register this with your IdP. Map IdP groups to Couchbase groups via ldap_group_ref (same mechanism as LDAP). spSignRequests and spVerifyAssertionSig are enabled by default — do not disable in production.
Couchbase Server encrypts data on disk at the node level. Two mechanisms:
Encrypts replication traffic between cluster nodes (DCP streams, XDCR within the cluster):
# Enable node-to-node encryption (all, control, or off)
couchbase-cli node-to-node-encryption \
--cluster localhost --username Administrator --password password \
--enable --encryption allLevels: control (management traffic only), all (data + management). Requires TLS certificates on all nodes.
Encrypts data files, indexes, and logs on disk using AES-256. Requires an external Key Management Service (KMS) or a local keystore.
# Configure AWS KMS as the key store
curl -X POST http://localhost:8091/settings/secretMgmt \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-H "Content-Type: application/json" \
-d '{
"keyStorageType": "awskms",
"awsRegion": "us-east-1",
"awsKeyId": "arn:aws:kms:us-east-1:123456789:key/my-key-id"
}'
# Enable encryption for data files
curl -X POST http://localhost:8091/settings/security \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "encryptionAtRestEnabled=true"Supported KMS backends: AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault, local keystore (dev/test only).
When using the Magma storage engine (recommended for buckets >10 GB), encryption is configured per bucket:
curl -X POST http://localhost:8091/pools/default/buckets \
-u Administrator:"$CB_ADMIN_PASSWORD" \
-d "name=myapp&ramQuota=1024&storageBackend=magma&encryptionAtRestSecretId=<secret-id>"| Requirement | Mechanism |
|---|---|
| Data encrypted in transit (client↔cluster) | TLS (couchbases://) |
| Data encrypted in transit (node↔node) | Node-to-node encryption |
| Data encrypted at rest | Secret Management Service + disk encryption |
| Key rotation | KMS key rotation (external KMS handles this) |
| Audit trail | Audit Service (see below) |
# Capella / production — couchbases:// enables TLS
cluster = Cluster("couchbases://cb.xxxxx.cloud.couchbase.com",
ClusterOptions(PasswordAuthenticator(
os.environ["CB_USERNAME"], os.environ["CB_PASSWORD"])))
# Self-managed with custom CA
cluster = Cluster("couchbases://my-cluster.example.com",
ClusterOptions(PasswordAuthenticator(
os.environ["CB_USERNAME"], os.environ["CB_PASSWORD"]),
tls_verify=TLSVerifyMode.PEER,
trust_store_path="/path/to/ca.pem"))TLS protects data in transit; encryption-at-rest protects data on disk. Field-Level Encryption (FLE) is a third layer: individual field values are encrypted on the client before the document reaches the server, so the server never sees plaintext for those fields.
Use FLE when:
- Regulatory requirements mandate that specific fields (PII, PAN, SSN) are never stored in plaintext
- You need column-level access control beyond what RBAC provides
- You want end-to-end encryption independent of server-side controls
FLE is supported in Python, Java, Go, .NET, Node.js, and PHP SDKs. Rust and Scala SDKs do not support FLE.
→ For concept overview and key management, see the fle skill.
→ For SDK-specific implementation, see fle-python, fle-java, fle-go, fle-dotnet, fle-nodejs, or fle-php.
| Error | Cause | Fix |
|---|---|---|
| 401 Unauthorized | Wrong credentials or user doesn't exist | Verify username/password; check GET /settings/rbac/users/local/<user> |
| 403 Forbidden | User lacks required role | Grant the role at the correct resource scope |
Query returns nothing with data_reader |
SQL++ needs query_select too |
Add query_select — KV and Query are separate paths |
query_select but "keyspace not found" |
Role scoped to wrong collection | Check role's resource scope matches the collection |
| Eventing permission error | Missing data_dcp_reader on source or data_writer on destination |
Add both roles |