Skip to content

Authentication ​

The driver supports the password authenticator that ScyllaDB and Cassandra ship with (PasswordAuthenticator). Supply the credentials on the builder.

php
$cluster = Cassandra::cluster()
    ->withContactPoints('10.0.0.1')
    ->withCredentials('app_user', getenv('SCYLLA_PASSWORD'))
    ->build();

The password parameter carries the #[\SensitiveParameter] attribute. PHP redacts it in stack traces, so a leaked exception log does not expose the password.

Where credentials go ​

Never write the password into source code. Read it from the environment or from a secret store:

php
$password = getenv('SCYLLA_PASSWORD');

if ($password === false || $password === '') {
    throw new RuntimeException('SCYLLA_PASSWORD is not set');
}

$builder->withCredentials(getenv('SCYLLA_USER') ?: 'app_user', $password);

Credentials travel in clear text ​

The CQL password authenticator sends the user name and the password in a plain protocol frame. Anyone on the network path can read them.

Always pair credentials with TLS

Turn on TLS whenever the connection leaves a trusted network segment. See TLS and SSL.

php
$cluster = Cassandra::cluster()
    ->withContactPoints('db.internal.example.com')
    ->withCredentials('app_user', getenv('SCYLLA_PASSWORD'))
    ->withSSL(
        Cassandra::ssl()
            ->withTrustedCerts('/etc/ssl/certs/scylla-ca.pem')
            ->withVerifyFlags(Cassandra::VERIFY_PEER_CERT | Cassandra::VERIFY_PEER_IDENTITY)
            ->build()
    )
    ->build();

Failures ​

A wrong user name or password produces Cassandra\Exception\AuthenticationException from connect(). The exception message comes from the server.

php
use Cassandra\Exception\AuthenticationException;

try {
    $session = $cluster->connect('shop');
} catch (AuthenticationException $e) {
    // Do not log the password. Log the user name and the server message only.
    error_log(sprintf('auth failed for %s: %s', $user, $e->getMessage()));
    throw $e;
}

The exception arrives at connect() time, not at build() time. build() performs no network work.

A node with no authenticator ​

When the cluster runs AllowAllAuthenticator, credentials are ignored. Sending them is harmless. The default ScyllaDB Docker image works this way, so local development needs no credentials:

php
$session = Cassandra::cluster()
    ->withContactPoints('127.0.0.1')
    ->build()
    ->connect();

Per-user sessions ​

The driver has no per-request user switch. Authentication belongs to the cluster configuration, so a second identity needs a second cluster and a second session.

php
$readOnly  = makeCluster('reporting_user', $reportingPassword)->connect('shop');
$readWrite = makeCluster('app_user', $appPassword)->connect('shop');

Each session opens its own connection pool. Two identities cost twice the sockets. Prefer one application identity plus CQL permissions on the server side.

Role permissions ​

Authorization stays on the server. Grant the smallest useful set:

sql
CREATE ROLE app_user WITH PASSWORD = '...' AND LOGIN = true;

GRANT SELECT ON KEYSPACE shop TO app_user;
GRANT MODIFY ON KEYSPACE shop TO app_user;

A denied operation raises Cassandra\Exception\UnauthorizedException at query time.

Version 1.5. Released under the Apache License 2.0.