Skip to content

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

  1. Rust-Specific Security
  2. API Server Hardening
  3. Database Hardening
  4. Payment Provider Security
  5. Cryptographic Security
  6. Best Practices
  7. 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:

// Track webhook event IDs to prevent duplicates
// Idempotent webhook handlers ensure safe replay

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

  1. Use HTTPS: Always use TLS/SSL in production (enforce with HSTS)
  2. Environment Variables: Store secrets in environment variables or Vault
  3. Regular Updates: Keep Rust dependencies up to date with cargo audit
  4. Monitoring: Implement security monitoring and alerting
  5. Audit Logs: Enable and review audit logs regularly
  6. Least Privilege: Run services with minimal required permissions

API Server Security

  1. Rate Limiting: Configure appropriate rate limits per endpoint
  2. CORS: Use restrictive CORS policies
  3. Security Headers: Enable all security headers (X-Content-Type-Options, X-Frame-Options, etc.)
  4. Request Validation: Validate all inputs using Serde and Actix-web extractors
  5. Error Handling: Don't expose sensitive information in error messages

License Security

  1. Key Rotation: Rotate API keys periodically
  2. Least Privilege: Grant minimum necessary permissions
  3. Expiration: Set expiration dates on licenses
  4. Validation: Always validate licenses server-side
  5. Rate Limiting: Implement rate limiting on validation endpoints
  6. Geometric Proof: Use cryptographic proof validation

Payment Provider Security

  1. API Key Encryption: Encrypt payment provider API keys at rest
  2. Webhook Verification: Always verify webhook signatures
  3. Webhook Deduplication: Prevent duplicate webhook processing
  4. Provider Health: Monitor payment provider connectivity
  5. Secrets Management: Use Vault or AWS Secrets Manager for production

Database Security

  1. Encryption: Encrypt sensitive data at rest (AES-256-GCM)
  2. Backups: Regular encrypted backups with secure storage
  3. Access Control: Restrict database access with least privilege
  4. Connection Security: Use SSL/TLS for database connections
  5. Query Safety: Use SQLx compile-time checked queries

Security Checklist

Pre-Production

Rust & Dependencies

  • [ ] Run cargo audit and fix all vulnerabilities
  • [ ] Run cargo clippy -- -D warnings and fix all warnings
  • [ ] Enable all compiler warnings with RUSTFLAGS="-D warnings"
  • [ ] Review all unsafe code 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 audit monthly
  • [ ] 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


Last Updated: 2026-01-28 Architecture: Single-Tenant Rust (Actix-web, SQLx, PostgreSQL)