Skip to content

Latest commit

 

History

History
253 lines (191 loc) · 9.88 KB

File metadata and controls

253 lines (191 loc) · 9.88 KB
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
last_verified min_server_version handoff
2026-05
5.0
condition skill
user asks about cluster topology or failover
cluster-ops
condition skill
user asks about Capella cluster setup or credentials
capella
condition skill
user asks about field-level encryption or client-side encryption
fle
condition skill
user asks about Couchbase fundamentals or core concepts
getting-started

Couchbase Security

RBAC Model

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.

Key Roles

Data access

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)

Query (SQL++)

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

Search / Analytics / Eventing

Role Internal name
Search Reader fts_searcher
Search Admin fts_admin
Analytics Reader analytics_reader
Eventing Manage Functions eventing_manage_functions

Admin (use sparingly)

admin (full), bucket_admin (one bucket), ro_admin (read-only)


Creating Users

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"

User Groups

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"

LDAP Integration (Enterprise)

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 / SSO (Enterprise)

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.


Encryption at Rest (Enterprise)

Couchbase Server encrypts data on disk at the node level. Two mechanisms:

Node-to-node encryption

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 all

Levels: control (management traffic only), all (data + management). Requires TLS certificates on all nodes.

Disk-level encryption (Secret Management Service)

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).

Bucket-level encryption (Magma storage engine)

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>"

Compliance checklist

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)

TLS Configuration

# 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"))

Field-Level Encryption

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.


Troubleshooting

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