# Connect via CQL

This page explains how to connect to a ScyllaDB cluster running on Kubernetes using CQL (Cassandra Query Language).

## Authentication setup

For security, always enable authentication and authorization. Create a ConfigMap with the ScyllaDB configuration before deploying your cluster:

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: scylladb-config
data:
  scylla.yaml: |
    authenticator: PasswordAuthenticator
    authorizer: CassandraAuthorizer
```

Reference this ConfigMap from your ScyllaCluster via `scyllaConfig` on each rack:

```yaml
apiVersion: scylla.scylladb.com/v1
kind: ScyllaCluster
metadata:
  name: scylladb
spec:
  datacenter:
    racks:
    - name: us-east-1a
      scyllaConfig: scylladb-config
      # ...
```

After deployment, follow the [Creating a Custom Superuser](https://docs.scylladb.com/manual/stable/operating-scylla/security/create-superuser.html) guide in the ScyllaDB documentation to replace the default `cassandra` superuser with a dedicated role.

## Embedded cqlsh

Every ScyllaDB Pod includes a built-in `cqlsh`. This is the simplest way to run queries:

Any node (via Service)

```shell
kubectl exec -it service/<cluster-name>-client -c scylla -- cqlsh -u <user>
```

Specific node

```shell
kubectl exec -it pod/<cluster-name>-<datacenter>-<rack>-<ordinal> -c scylla -- cqlsh -u <user>
```

```default
Password:
Connected to scylla at 0.0.0.0:9042
[cqlsh 6.0.32 | Scylla 2026.1.0-0.20260309.9190d42863d4 | CQL spec 3.3.1 | Native protocol v4]
Use HELP for help.
<user>@cqlsh>
```

## Remote cqlsh with TLS

ScyllaDB Operator configures TLS certificates automatically. The encrypted CQL port `9142` works by default.

### Prepare credentials and certificates

The Operator automatically creates TLS resources for each ScyllaCluster. For programmatic access using the Go driver with clusters that have `dnsDomains` configured, use the pre-built connection bundle from `secret/<cluster-name>-local-cql-connection-configs-admin` directly (see [Security](https://operator.docs.scylladb.com/stable/understand/security.md) for details).

For `cqlsh`, extract the certificates and create a `cqlshrc` file:

**Step 1: Extract certificates**

```bash
kubectl -n scylla get configmap <cluster-name>-local-serving-ca \
  --template='{{ index .data "ca-bundle.crt" }}' > ca.crt
kubectl -n scylla get secret <cluster-name>-local-user-admin \
  -o jsonpath='{.data.tls\.crt}' | base64 -d > client.crt
kubectl -n scylla get secret <cluster-name>-local-user-admin \
  -o jsonpath='{.data.tls\.key}' | base64 -d > client.key
```

#### NOTE
`ca.crt` is a copy of the serving CA bundle. When the operator reissues the serving CA, `cqlsh` rejects the new serving
certificate until you extract the bundle again. See [Certificate rotation](https://operator.docs.scylladb.com/stable/understand/security.md#certificate-rotation).

**Step 2: Create a cqlshrc file**

```bash
export SCYLLADB_CONFIG=/path/to/scylladb-config
mkdir -p "${SCYLLADB_CONFIG}"
cp ca.crt client.crt client.key "${SCYLLADB_CONFIG}/"
cat > "${SCYLLADB_CONFIG}/cqlshrc" <<EOF
[connection]
hostname = <cluster-name>-client.<namespace>.svc
port = 9142
ssl = true

[ssl]
certfile = ${SCYLLADB_CONFIG}/ca.crt
usercert = ${SCYLLADB_CONFIG}/client.crt
userkey = ${SCYLLADB_CONFIG}/client.key
validate = true

[authentication]
username = cassandra
password = <password>
EOF
```

### Connect

Native

```shell
cqlsh --cqlshrc="${SCYLLADB_CONFIG}/cqlshrc"
```

Podman

```shell
podman run -it --rm --entrypoint=cqlsh \
  -v="${SCYLLADB_CONFIG}:${SCYLLADB_CONFIG}:ro,Z" \
  -v="${SCYLLADB_CONFIG}/cqlshrc:/root/.cassandra/cqlshrc:ro,Z" \
  docker.io/scylladb/scylla:2026.3.4
```

Docker

```shell
docker run -it --rm --entrypoint=cqlsh \
  -v="${SCYLLADB_CONFIG}:${SCYLLADB_CONFIG}:ro" \
  -v="${SCYLLADB_CONFIG}/cqlshrc:/root/.cassandra/cqlshrc:ro" \
  docker.io/scylladb/scylla:2026.3.4
```

## Driver configuration tips

When using a ScyllaDB or Cassandra driver in your application:

| Setting          | Recommended value                                                      | Why                                                                                                                                                                                                                                                                                                     |
|------------------|------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Contact points   | `<cluster-name>-client.<namespace>.svc` (DNS) or the Service ClusterIP | Use the discovery Service, not individual Pod IPs. The driver discovers all nodes automatically.                                                                                                                                                                                                        |
| Local datacenter | Your `datacenter.name` value (e.g., `us-east-1`)                       | Required for `DCAwareRoundRobinPolicy`. Prevents cross-DC queries.                                                                                                                                                                                                                                      |
| Load balancing   | Token-aware + DC-aware round robin                                     | Sends queries directly to the replica owning the partition.                                                                                                                                                                                                                                             |
| TLS              | Enabled, with CA verification                                          | Use the serving CA bundle from `configmap/<cluster-name>-local-serving-ca`. In Kubernetes, [mount it into your application Pods](); otherwise, keep your copy up to date as described in [Certificate rotation](https://operator.docs.scylladb.com/stable/understand/security.md#certificate-rotation). |
| Reconnection     | Exponential backoff                                                    | Handles node restarts during rolling updates.                                                                                                                                                                                                                                                           |

## Mount TLS files in application Pods

Mount the serving CA bundle ConfigMap into your application Pods instead of copying it, so that they pick up a reissued
serving CA. Kubernetes updates the mounted file when the ConfigMap changes.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  # ...
  template:
    spec:
      containers:
      - name: app
        image: <your-app-image>
        volumeMounts:
        - name: scylladb-serving-ca
          mountPath: /etc/scylladb/serving-ca
          readOnly: true
        - name: scylladb-client-certificate
          mountPath: /etc/scylladb/client-certificate
          readOnly: true
      volumes:
      - name: scylladb-serving-ca
        configMap:
          name: <cluster-name>-local-serving-ca
      - name: scylladb-client-certificate
        secret:
          secretName: <client-certificate-secret-name>
```

Configure your driver to use `/etc/scylladb/serving-ca/ca-bundle.crt` as the CA, and `/etc/scylladb/client-certificate/tls.crt`
and `/etc/scylladb/client-certificate/tls.key` as the client certificate and key. The client certificate Secret has to
hold a certificate signed by the cluster’s client CA, such as the `<cluster-name>-local-user-admin` Secret.

Keep in mind:

- Don’t mount the files with `subPath`. Kubernetes doesn’t update files mounted with `subPath`.
- Kubernetes updates mounted files with a delay, so new connections can fail for a short time after the serving CA is reissued.
- Your application has to read the files again when it opens new connections. If it reads them only at startup, restart it after the serving CA is reissued.
- A Pod can only mount ConfigMaps and Secrets from its own namespace. For applications in other namespaces, keep a copy of the bundle up to date instead.

## Related pages

- [Discovery endpoint](https://operator.docs.scylladb.com/stable/connect-your-app/discovery.md) — how the client Service works and how to expose it.
- [Alternator (DynamoDB API)](https://operator.docs.scylladb.com/stable/connect-your-app/alternator.md) — connecting via the DynamoDB-compatible API.
- [Configure external access](https://operator.docs.scylladb.com/stable/deploy-scylladb/set-up-networking/configure-external-access.md) — connecting from outside the Kubernetes cluster.
- [Security](https://operator.docs.scylladb.com/stable/understand/security.md) — TLS certificate management.
