SCRAM-SHA-256 Quick Reference
SCRAM-SHA-256 Quick Reference
Fast reference for SCRAM-SHA-256 authentication in HeliosDB Nano.
Quick Setup
use heliosdb_nano::protocol::postgres::{ PgServerBuilder, AuthMethod, AuthManager, InMemoryPasswordStore, SharedPasswordStore};use std::sync::Arc;
// 1. Create password store and add userslet mut store = InMemoryPasswordStore::new();store.add_user("postgres", "password")?;
// 2. Wrap in shared storelet shared = SharedPasswordStore::new(store);
// 3. Create auth managerlet auth = Arc::new( AuthManager::with_password_store(AuthMethod::ScramSha256, shared));
// 4. Build serverlet server = PgServerBuilder::new() .address("127.0.0.1:5432".parse()?) .auth_manager(auth) .build(db)?;Connect with psql
# Direct passwordpsql "host=127.0.0.1 port=5432 user=postgres password=password"
# Interactive promptpsql "host=127.0.0.1 port=5432 user=postgres"
# With SSLpsql "sslmode=require host=127.0.0.1 port=5432 user=postgres password=password"User Management
let mut store = InMemoryPasswordStore::new();
// Add userstore.add_user("alice", "secret")?;
// Update passwordstore.update_password("alice", "new_secret")?;
// Remove userstore.remove_user("alice")?;
// Check existenceif store.user_exists("alice") { ... }
// List userslet users = store.list_users();Custom Iterations
// Higher security (slower)let store = InMemoryPasswordStore::with_iterations(8192);
// Development (faster)let store = InMemoryPasswordStore::with_iterations(4096);Authentication Methods
// SCRAM-SHA-256 (recommended)AuthMethod::ScramSha256
// Trust (development only)AuthMethod::Trust
// Cleartext (not recommended)AuthMethod::CleartextPassword
// MD5 (legacy)AuthMethod::Md5File Locations
| Component | File Path |
|---|---|
| Core Implementation | src/protocol/postgres/auth.rs |
| Password Store | src/protocol/postgres/password_store.rs |
| Protocol Handler | src/protocol/postgres/handler.rs |
| Tests | tests/postgres_scram_auth_tests.rs |
| Example | examples/postgres_server_ssl.rs |
| Documentation | docs/SCRAM_SHA256_AUTHENTICATION.md |
Key Functions
// Credential preparationlet (stored_key, server_key) = prepare_scram_credentials(password, salt, iterations);
// Password verificationlet creds = ScramCredentials::from_password("user".to_string(), "password", 4096);assert!(creds.verify_password("password"));
// SCRAM auth statelet mut state = ScramAuthState::new("username".to_string());state.set_client_nonce(nonce);let server_first = state.build_server_first_message()?;Testing
# Run SCRAM testscargo test postgres_scram_auth_tests
# Run all protocol testscargo test --test '*protocol*'
# Run examplecargo run --example postgres_server_sslTroubleshooting
| Issue | Solution |
|---|---|
| ”User not found” | Add user with store.add_user(username, password) |
| ”Invalid password” | Update with store.update_password(username, new_password) |
| Slow auth | Reduce iterations (4096 is good for development) |
| Client errors | Ensure client supports SCRAM-SHA-256 (psql 10+) |
Security Checklist
- ✅ Use SCRAM-SHA-256 in production
- ✅ Combine with SSL/TLS
- ✅ Use strong passwords (12+ chars)
- ✅ High iterations (8192+) for production
- ✅ Implement password rotation
- ✅ Log authentication events
- ✅ Use persistent password store
Performance
| Configuration | Auth Time | Recommended For |
|---|---|---|
| 4096 iterations | ~10ms | Development |
| 8192 iterations | ~20ms | Production |
| 16384 iterations | ~40ms | High Security |
Common Patterns
Development Setup
let auth = AuthManager::with_scram_store(AuthMethod::ScramSha256) .with_default_users();Production Setup with SSL
let server = PgServerBuilder::new() .address("0.0.0.0:5432".parse()?) .auth_manager(scram_auth_manager) .ssl_config(ssl_config) .build(db)?;Custom Password Store
struct MyPasswordStore { /* ... */ }
impl PasswordStore for MyPasswordStore { fn get_credentials(&self, username: &str) -> Option<ScramCredentials> { ... } fn add_user(&mut self, username: &str, password: &str) -> Result<()> { ... } fn remove_user(&mut self, username: &str) -> Result<bool> { ... } fn update_password(&mut self, username: &str, new_password: &str) -> Result<()> { ... } fn user_exists(&self, username: &str) -> bool { ... } fn list_users(&self) -> Vec<String> { ... }}