SCRAM-SHA-256 Authentication Guide
Complete guide to SCRAM-SHA-256 authentication on the HeliosDB-Lite PostgreSQL port.
Overview
SCRAM-SHA-256 (Salted Challenge Response Authentication Mechanism) is a modern, secure authentication protocol that provides:
- No plaintext passwords: Passwords are never transmitted or stored in plaintext
- Mutual authentication: Both client and server prove knowledge of the password
- Replay attack protection: Each authentication uses unique nonces
- Timing attack resistance: Constant-time comparison prevents timing-based attacks
- RFC compliance: Compliant with RFC 5802 (SCRAM) and RFC 7677 (SCRAM-SHA-256)
Quick Start
Basic Setup
export HELIOSDB_JWT_SECRET="$(openssl rand -hex 32)"export HELIOSDB_ADMIN_PASSWORD='secure_password'
heliosdb-lite start --data-dir ./mydb \ --auth scram-sha-256 --password "$HELIOSDB_ADMIN_PASSWORD"--password becomes the password of the built-in administrator accounts postgres
and helios. Every --auth method except trust requires it.
Connecting with psql
# Interactive password promptpsql "host=127.0.0.1 port=5432 user=postgres dbname=heliosdb"
# Password from the environmentPGPASSWORD="$HELIOSDB_ADMIN_PASSWORD" psql "host=127.0.0.1 port=5432 user=postgres dbname=heliosdb"
# With SSL/TLS (server started with --tls-cert and --tls-key)psql "sslmode=require host=127.0.0.1 port=5432 user=postgres"User Management
Create login roles with SQL; their passwords are stored as SCRAM verifiers:
-- Add a userCREATE ROLE alice LOGIN PASSWORD 'a-long-random-password';
-- Update a passwordALTER ROLE alice PASSWORD 'another-long-password';
-- Disable password loginALTER ROLE alice PASSWORD NULL;
-- Remove a userDROP ROLE alice;The built-in postgres and helios accounts are resolved first, so a SQL role can never
shadow them. A role without LOGIN, or without a password, cannot authenticate.
Authentication Flow
Client Server | | |--- Startup (user=alice) --------------->| | | |<-- AuthenticationSASL (SCRAM-SHA-256)---| | | |--- client-first-message ---------------->| | (n=alice,r=client_nonce) | | | |<-- server-first-message -----------------| | (r=client_nonce+server_nonce, | | s=salt_b64,i=iterations) | | | |--- client-final-message ---------------->| | (c=channel_binding, | | r=combined_nonce, | | p=client_proof) | | | [Verify proof] | | |<-- server-final-message -----------------| | (v=server_signature) | | | |<-- AuthenticationOk --------------------| | | |<-- ReadyForQuery -----------------------|Security Features
Password Derivation
SCRAM-SHA-256 uses PBKDF2-HMAC-SHA-256 for key derivation:
SaltedPassword = Hi(password, salt, iterations)ClientKey = HMAC(SaltedPassword, "Client Key")StoredKey = H(ClientKey)ServerKey = HMAC(SaltedPassword, "Server Key")HeliosDB-Lite uses 100,000 PBKDF2 iterations (the NIST SP 800-132 recommendation) and a random salt per user.
Stored Credentials
Only the salt, the iteration count, StoredKey and ServerKey are stored; the
plaintext password is never kept.
Timing Attack Resistance
All secret comparisons use constant-time algorithms.
Best Practices
Production Deployment
- Use strong passwords: Minimum 12 characters, mixed case, numbers, symbols
- Combine with SSL/TLS: Start with
--tls-cert/--tls-keyand usesslmode=require - Rotate passwords:
ALTER ROLE ... PASSWORDon a schedule - Monitor failed attempts: Alert on repeated authentication failures in the server log
- Least privilege: Connect applications as non-superuser roles
Troubleshooting
Common Issues
Authentication fails with “User not found”
- Cause: The role does not exist, has no
LOGIN, or has no password - Solution:
CREATE ROLE ... LOGIN PASSWORD ..., or connect aspostgres
Authentication fails with “Invalid password”
- Cause: Incorrect password
- Solution: Reset it with
ALTER ROLE ... PASSWORD ...
Client shows “SCRAM not supported”
- Cause: Client doesn’t support SCRAM-SHA-256
- Solution: Use a modern PostgreSQL client (psql 10+, libpq 10+)
Debug Logging
export HELIOSDB_JWT_SECRET="$(openssl rand -hex 32)"RUST_LOG=debug heliosdb-lite start --data-dir ./mydb \ --auth scram-sha-256 --password "$HELIOSDB_ADMIN_PASSWORD"Performance Considerations
Benchmarks
The server uses 100,000 iterations and has no setting to change it; these timings were measured at the lower iteration counts shown and understate the default cost proportionally.
Figures from internal tests (HeliosDB Lite SCRAM path, representative fixtures); reproduce on your own hardware.
At 4,096 iterations:
- Credential creation: ~5ms
- Password verification: ~5ms
- Full authentication: ~10-15ms
At 16,384 iterations:
- Credential creation: ~20ms
- Password verification: ~20ms
- Full authentication: ~40-50ms
Optimization Tips
- Connection pooling: Authenticate once, reuse connections (client-side pools or HeliosProxy)
- Async operations: Authentication is fully async and does not block other sessions
RFC Compliance
HeliosDB-Lite SCRAM implementation is compliant with:
- RFC 5802: Salted Challenge Response Authentication Mechanism (SCRAM)
- RFC 7677: SCRAM-SHA-256
- PostgreSQL Protocol: SASL authentication messages
Supported Features
- SCRAM-SHA-256
- PBKDF2-HMAC-SHA-256 key derivation
- Salted password hashing
- Client and server nonce
- Channel binding placeholder (n,,)
- Server signature verification
- Constant-time comparisons
Migration Guide
From Trust to SCRAM
export HELIOSDB_JWT_SECRET="$(openssl rand -hex 32)"# Before (trust: no passwords)heliosdb-lite start --data-dir ./mydb
# After (SCRAM)heliosdb-lite start --data-dir ./mydb --auth scram-sha-256 --password "$HELIOSDB_ADMIN_PASSWORD"Then create one login role per application with CREATE ROLE ... LOGIN PASSWORD ....
From Cleartext or MD5 to SCRAM
Restart the server with --auth scram-sha-256. Passwords set with CREATE ROLE or
ALTER ROLE are already stored as SCRAM verifiers, so no password reset is needed.
References
- RFC 5802 - SCRAM SASL Mechanism
- RFC 7677 - SCRAM-SHA-256
- PostgreSQL SCRAM Documentation
- PBKDF2 Specification
Support
For issues or questions: support@heliosdb.com