Overview
The ScyllaDB Rust Driver supports multiple authentication methods to secure connections to your database cluster. You can use the built-in plain text authenticator for username/password authentication, or implement a custom authenticator for more advanced authentication schemes.
Plain Text Authentication
The simplest and most common authentication method is plain text authentication using a username and password.
Using the user() Method
The easiest way to set up authentication is using the user() method on SessionBuilder:
use scylla :: client :: session_builder :: SessionBuilder ;
use scylla :: client :: session :: Session ;
#[tokio :: main]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let session : Session = SessionBuilder :: new ()
. known_node ( "127.0.0.1:9042" )
. user ( "cassandra" , "cassandra" )
. build ()
. await ? ;
// Now you can use the authenticated session
Ok (())
}
PlainTextAuthenticator
Under the hood, the user() method creates a PlainTextAuthenticator. You can also create one explicitly:
use scylla :: authentication :: PlainTextAuthenticator ;
use std :: sync :: Arc ;
let session : Session = SessionBuilder :: new ()
. known_node ( "127.0.0.1:9042" )
. authenticator_provider ( Arc :: new ( PlainTextAuthenticator :: new (
"cassandra" . to_string (),
"cassandra" . to_string (),
)))
. build ()
. await ? ;
Default Credentials
ScyllaDB and Cassandra come with default credentials:
Username : cassandra
Password : cassandra
Always change default credentials in production environments. Using default credentials is a significant security risk.
Custom Authentication
For advanced authentication scenarios, you can implement custom authenticators by implementing the AuthenticatorProvider and AuthenticatorSession traits.
AuthenticatorProvider Trait
The AuthenticatorProvider trait is a factory for creating authenticator sessions:
use async_trait :: async_trait;
use scylla :: authentication :: { AuthenticatorProvider , AuthenticatorSession , AuthError };
#[async_trait]
pub trait AuthenticatorProvider : Sync + Send {
/// Returns initial response and an AuthenticatorSession
/// if authentication is required by the server.
async fn start_authentication_session (
& self ,
authenticator_name : & str ,
) -> Result <( Option < Vec < u8 >>, Box < dyn AuthenticatorSession >), AuthError >;
}
AuthenticatorSession Trait
The AuthenticatorSession trait handles the authentication protocol:
use async_trait :: async_trait;
#[async_trait]
pub trait AuthenticatorSession : Send + Sync {
/// Handle an authentication challenge initiated by the server.
/// The token parameter contains authentication protocol-specific information.
async fn evaluate_challenge (
& mut self ,
token : Option < & [ u8 ]>,
) -> Result < Option < Vec < u8 >>, AuthError >;
/// Handle the success phase of the authentication exchange.
/// The token parameter may contain finalization information.
async fn success ( & mut self , token : Option < & [ u8 ]>) -> Result <(), AuthError >;
}
Complete Custom Authenticator Example
Here’s a complete example of implementing a custom authenticator:
use std :: sync :: Arc ;
use scylla :: client :: session_builder :: SessionBuilder ;
use scylla :: client :: session :: Session ;
use async_trait :: async_trait;
use scylla :: authentication :: { AuthenticatorProvider , AuthenticatorSession , AuthError };
// Define the authenticator session
struct CustomAuthenticator {
// Add any state needed for authentication
}
#[async_trait]
impl AuthenticatorSession for CustomAuthenticator {
async fn evaluate_challenge (
& mut self ,
token : Option < & [ u8 ]>,
) -> Result < Option < Vec < u8 >>, AuthError > {
// Implement your challenge-response logic here
// Return None if no response is needed
// Return Some(response) to send a response to the server
Ok ( None )
}
async fn success ( & mut self , token : Option < & [ u8 ]>) -> Result <(), AuthError > {
// Handle successful authentication
// You can validate the success token here
Ok (())
}
}
// Define the authenticator provider
struct CustomAuthenticatorProvider {
// Add configuration needed to create authenticators
}
#[async_trait]
impl AuthenticatorProvider for CustomAuthenticatorProvider {
async fn start_authentication_session (
& self ,
authenticator_name : & str ,
) -> Result <( Option < Vec < u8 >>, Box < dyn AuthenticatorSession >), AuthError > {
// Check the authenticator name if needed
// Return initial response and the session
Ok (( None , Box :: new ( CustomAuthenticator {})))
}
}
#[tokio :: main]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let session : Session = SessionBuilder :: new ()
. known_node ( "127.0.0.1:9042" )
. authenticator_provider ( Arc :: new ( CustomAuthenticatorProvider {}))
. build ()
. await ? ;
Ok (())
}
Authentication Error Handling
Authentication errors are represented as String values:
pub type AuthError = String ;
When authentication fails, you should return a descriptive error message:
#[async_trait]
impl AuthenticatorSession for MyAuthenticator {
async fn evaluate_challenge (
& mut self ,
token : Option < & [ u8 ]>,
) -> Result < Option < Vec < u8 >>, AuthError > {
if token . is_none () {
return Err ( "Expected authentication token from server" . to_string ());
}
// Process the token...
Ok ( Some ( response ))
}
}
Supported Authenticators
ScyllaDB and Cassandra support several authenticator types:
pub enum Authenticator {
AllowAllAuthenticator ,
PasswordAuthenticator ,
CassandraPasswordAuthenticator ,
CassandraAllowAllAuthenticator ,
ScyllaTransitionalAuthenticator ,
}
AllowAllAuthenticator : No authentication required (default for development)
PasswordAuthenticator : ScyllaDB’s password authenticator
CassandraPasswordAuthenticator : Cassandra’s password authenticator
ScyllaTransitionalAuthenticator : ScyllaDB’s transitional authenticator for gradual migration
Complete Example with Keyspace
Here’s a complete example combining authentication with other session configuration:
use scylla :: client :: session_builder :: SessionBuilder ;
use scylla :: client :: session :: Session ;
#[tokio :: main]
async fn main () -> Result <(), Box < dyn std :: error :: Error >> {
let session : Session = SessionBuilder :: new ()
. known_node ( "127.0.0.1:9042" )
. user ( "cassandra" , "cassandra" )
. use_keyspace ( "my_keyspace" , false )
. build ()
. await ? ;
// Create a table in the authenticated session
session . query_unpaged (
"CREATE TABLE IF NOT EXISTS users (id int PRIMARY KEY, name text)" ,
& [],
) . await ? ;
// Insert data
session . query_unpaged (
"INSERT INTO users (id, name) VALUES (?, ?)" ,
( 1 , "Alice" ),
) . await ? ;
println! ( "Successfully connected and executed queries with authentication" );
Ok (())
}
Security Best Practices
Important Security Considerations:
Never commit credentials to source control - Use environment variables or secure configuration management
Use TLS/SSL in production - Plain text authentication sends credentials over the network
Change default passwords - Always change default credentials in any environment
Use strong passwords - Follow your organization’s password policy
Rotate credentials regularly - Implement a credential rotation strategy
Using Environment Variables
use std :: env;
let username = env :: var ( "SCYLLA_USERNAME" )
. expect ( "SCYLLA_USERNAME not set" );
let password = env :: var ( "SCYLLA_PASSWORD" )
. expect ( "SCYLLA_PASSWORD not set" );
let session : Session = SessionBuilder :: new ()
. known_node ( "127.0.0.1:9042" )
. user ( username , password )
. build ()
. await ? ;
See Also
TLS/SSL Secure your connections with TLS encryption
Connection Overview Learn about basic connection configuration