Security Hardening Guide¶
Version: 2.0 Last Updated: 2026-01-28 Architecture: Single-Tenant Rust (Actix-web, SQLx, PostgreSQL)
This document describes the security hardening features implemented in Sawabona and best practices for secure deployment.
Table of Contents¶
- Rust-Specific Security
- API Server Hardening
- Database Hardening
- Payment Provider Security
- Cryptographic Security
- Best Practices
- Security Checklist
Rust-Specific Security¶
Memory Safety¶
Rust's ownership system provides compile-time memory safety guarantees:
- No buffer overflows: Bounds checking on all array access
- No use-after-free: Ownership system prevents dangling pointers
- No data races: Type system prevents concurrent data mutations
- No null pointer dereferences: Option
and Result types
Hardening Steps:
# Enable all compiler warnings
RUSTFLAGS="-D warnings" cargo build
# Use clippy for additional linting
cargo clippy -- -D warnings
# Check for unsafe code
cargo audit
Type Safety¶
Rust's type system prevents many classes of bugs at compile time:
- SQL Injection Prevention: SQLx compile-time query checking
- Type Mismatches: Compile-time type checking
- Invalid State Transitions: Enum-based state machines
Hardening Steps:
# Verify all queries are compile-time checked
cargo check --all
# Run tests to verify type safety
cargo test --all
Dependency Security¶
Manage dependencies securely:
# Audit dependencies for known vulnerabilities
cargo audit
# Update dependencies safely
cargo update
# Check for outdated dependencies
cargo outdated
API Server Hardening¶
Actix-web Configuration¶
Harden the Actix-web server with security middleware:
// src/routes.rs
use actix_web::{web, App, HttpServer, middleware};
HttpServer::new(|| {
App::new()
// Security headers
.wrap(middleware::DefaultHeaders::new()
.add(("X-Content-Type-Options", "nosniff"))
.add(("X-Frame-Options", "DENY"))
.add(("X-XSS-Protection", "1; mode=block"))
.add(("Strict-Transport-Security", "max-age=31536000; includeSubDomains")))
// Compression
.wrap(middleware::Compress::default())
// CORS (restrictive)
.wrap(middleware::NormalizePath::trim())
// Rate limiting
.wrap(RateLimitMiddleware::new())
// Request logging
.wrap(middleware::Logger::default())
})
HTTPS/TLS Configuration¶
Enforce HTTPS in production:
# Generate self-signed certificate (development only)
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
# Use Let's Encrypt in production
certbot certonly --standalone -d yourdomain.com
Rate Limiting¶
Configure rate limiting per endpoint:
// Default: 100 req/sec per IP
// Configurable via environment variables
SAWABONA_RATE_LIMIT_PER_SEC=100
Authentication¶
Implement strong authentication:
- Admin Endpoints: X-API-Key header with HMAC verification
- License Validation: JWT token with HS256 signature
- Webhook Verification: HMAC-SHA256 signature verification
Database Hardening¶
PostgreSQL Configuration¶
Harden PostgreSQL for production:
-- Enable SSL
ssl = on
-- Restrict connections
max_connections = 100
max_prepared_transactions = 100
-- Enable logging
log_connections = on
log_disconnections = on
log_statement = 'all'
log_duration = on
-- Set password encryption
password_encryption = scram-sha-256
SQLx Security¶
Use SQLx compile-time checked queries:
// ✅ SAFE: Compile-time checked
let license = sqlx::query_as::<_, License>(
"SELECT * FROM licenses WHERE key = ?"
)
.bind(license_key)
.fetch_one(&pool)
.await?;
// ❌ UNSAFE: Runtime checked (avoid)
let query = format!("SELECT * FROM licenses WHERE key = '{}'", license_key);
Connection Security¶
Configure secure database connections:
# Use SSL for database connections
DATABASE_URL=postgresql://user:password@host/db?sslmode=require
# Use connection pooling
SQLX_POOL_SIZE=10
SQLX_POOL_TIMEOUT=30
Backup Security¶
Implement secure backups:
# Encrypted backups
pg_dump -Fc sawabona | gpg --encrypt > backup.sql.gpg
# Automated backups with retention
0 2 * * * pg_dump -Fc sawabona | gpg --encrypt > /backups/sawabona-$(date +\%Y\%m\%d).sql.gpg
Payment Provider Security¶
API Key Management¶
Secure payment provider API keys:
// Encrypt API keys at rest using AES-256-GCM
use sawabona_core::encryption::encrypt_api_key;
let encrypted_key = encrypt_api_key(
"sk_live_abc123xyz789",
&encryption_key
)?;
// Store encrypted_key in database
// Never log or expose the plaintext key
Environment Variables¶
Store payment provider credentials in environment variables:
# .env (development only, never commit)
SAWABONA_STRIPE_SECRET_KEY=sk_test_abc123xyz789
SAWABONA_STRIPE_WEBHOOK_SECRET=whsec_...
SAWABONA_FLUTTERWAVE_SECRET_KEY=your-flutterwave-key
# Production: Use AWS Secrets Manager or HashiCorp Vault
Webhook Verification¶
Verify webhook signatures to prevent spoofing:
// All webhooks are verified with HMAC-SHA256
use sawabona_core::webhooks::verify_webhook_signature;
let is_valid = verify_webhook_signature(
&webhook_body,
&webhook_signature,
&provider_webhook_secret
)?;
if !is_valid {
return Err("Invalid webhook signature");
}
Provider Health Checks¶
Monitor payment provider connectivity:
# Check provider health
cargo run --bin sawabona-cli -- provider health stripe
# Output:
# ✓ Provider health check passed
# Provider: stripe
# Status: healthy
# Last checked: 2026-01-28T10:30:00Z
Webhook Event Deduplication¶
Prevent duplicate webhook processing:
Cryptographic Security¶
Geometric Proof System¶
The Geometric Proof system provides cryptographic challenge-response validation:
// License validation uses cryptographic proofs
// Prevents reverse engineering and key sharing
use sawabona_core::proof::{build_tile, compute_gpv, verify_proof};
use sawabona_core::targets::resolve_collection;
// Server side: rebuild the tile deterministically and extract the
// Geometric Proof Vector, then verify the client's HMAC proof against
// it in constant time.
let target_set = derive_target_set(&bootstrap_secret, &challenge.id);
let collection = resolve_collection(target_set)
.ok_or_else(|| anyhow::anyhow!("unknown target set"))?;
let tile = build_tile(challenge.seed, collection.as_ref(), &challenge.operations)?;
let gpv = compute_gpv(&tile);
let is_valid = verify_proof(&gpv, &challenge.id, &client_secret, &client_proof)?;
End-to-end request handling lives in
sawabona-api/src/handlers/geometric_proof.rs::verify_proof.
Password Hashing¶
Use Argon2 for password hashing:
// Admin passwords are hashed with Argon2
use argon2::{Argon2, PasswordHasher};
let hashed = Argon2::default()
.hash_password(password.as_bytes(), &salt)?
.to_string();
JWT Signing¶
Sign JWT tokens with HS256:
// License validation tokens are signed with HS256
use jsonwebtoken::{encode, Header, EncodingKey};
let token = encode(
&Header::default(),
&claims,
&EncodingKey::from_secret(jwt_secret.as_ref())
)?;
HMAC-SHA256¶
Use HMAC-SHA256 for webhook verification:
// Webhook signatures are verified with HMAC-SHA256
use hmac::{Hmac, Mac};
use sha2::Sha256;
type HmacSha256 = Hmac<Sha256>;
let mut mac = HmacSha256::new_from_slice(secret.as_bytes())?;
mac.update(body.as_bytes());
mac.verify_slice(signature.as_bytes())?;
Best Practices¶
General Security¶
- Use HTTPS: Always use TLS/SSL in production (enforce with HSTS)
- Environment Variables: Store secrets in environment variables or Vault
- Regular Updates: Keep Rust dependencies up to date with
cargo audit - Monitoring: Implement security monitoring and alerting
- Audit Logs: Enable and review audit logs regularly
- Least Privilege: Run services with minimal required permissions
API Server Security¶
- Rate Limiting: Configure appropriate rate limits per endpoint
- CORS: Use restrictive CORS policies
- Security Headers: Enable all security headers (X-Content-Type-Options, X-Frame-Options, etc.)
- Request Validation: Validate all inputs using Serde and Actix-web extractors
- Error Handling: Don't expose sensitive information in error messages
License Security¶
- Key Rotation: Rotate API keys periodically
- Least Privilege: Grant minimum necessary permissions
- Expiration: Set expiration dates on licenses
- Validation: Always validate licenses server-side
- Rate Limiting: Implement rate limiting on validation endpoints
- Geometric Proof: Use cryptographic proof validation
Payment Provider Security¶
- API Key Encryption: Encrypt payment provider API keys at rest
- Webhook Verification: Always verify webhook signatures
- Webhook Deduplication: Prevent duplicate webhook processing
- Provider Health: Monitor payment provider connectivity
- Secrets Management: Use Vault or AWS Secrets Manager for production
Database Security¶
- Encryption: Encrypt sensitive data at rest (AES-256-GCM)
- Backups: Regular encrypted backups with secure storage
- Access Control: Restrict database access with least privilege
- Connection Security: Use SSL/TLS for database connections
- Query Safety: Use SQLx compile-time checked queries
Security Checklist¶
Pre-Production¶
Rust & Dependencies
- [ ] Run
cargo auditand fix all vulnerabilities - [ ] Run
cargo clippy -- -D warningsand fix all warnings - [ ] Enable all compiler warnings with
RUSTFLAGS="-D warnings" - [ ] Review all
unsafecode blocks - [ ] Update all dependencies to latest versions
API Server
- [ ] Enable HTTPS with valid SSL certificate
- [ ] Configure security headers (HSTS, X-Content-Type-Options, etc.)
- [ ] Set up rate limiting (100 req/sec default)
- [ ] Configure CORS policies (restrictive)
- [ ] Enable request logging and monitoring
- [ ] Test all error handling paths
Database
- [ ] Enable PostgreSQL SSL/TLS
- [ ] Configure PostgreSQL logging
- [ ] Set up automated encrypted backups
- [ ] Test backup and recovery procedures
- [ ] Verify least privilege database user
Payment Providers
- [ ] Register all payment providers
- [ ] Verify webhook signatures work correctly
- [ ] Test webhook event deduplication
- [ ] Encrypt all API keys at rest
- [ ] Store secrets in environment variables or Vault
Monitoring & Logging
- [ ] Set up security monitoring and alerting
- [ ] Enable audit logging for all admin actions
- [ ] Configure log retention policies
- [ ] Test log aggregation and analysis
Documentation
- [ ] Review security documentation
- [ ] Document all security configurations
- [ ] Create incident response procedures
- [ ] Perform security audit
Production¶
Ongoing Monitoring
- [ ] Monitor security alerts daily
- [ ] Review audit logs weekly
- [ ] Monitor payment provider health
- [ ] Monitor webhook delivery status
- [ ] Check for unusual access patterns
Maintenance
- [ ] Run
cargo auditmonthly - [ ] Update dependencies monthly
- [ ] Rotate API keys quarterly
- [ ] Review security configurations quarterly
- [ ] Perform penetration testing annually
Incident Response
- [ ] Have incident response plan in place
- [ ] Test incident response procedures
- [ ] Document all security incidents
- [ ] Perform post-incident reviews
Additional Resources¶
- OWASP Top 10
- CWE Top 25
- NIST Cybersecurity Framework
- Rust Security Guidelines
- Actix-web Security
- SQLx Documentation
Last Updated: 2026-01-28 Architecture: Single-Tenant Rust (Actix-web, SQLx, PostgreSQL)