10 KiB
TLS/SSL Setup Guide
Complete guide to configuring SSL/TLS certificates with Hyperdrive.
Overview
Hyperdrive requires TLS/SSL for all database connections.
Supported Configurations:
- Basic TLS (
requiremode) - Default, validates certificates via WebPKI - Server Certificates (
verify-ca,verify-full) - Verify server's CA certificate - Client Certificates (mTLS) - Authenticate Hyperdrive to database
SSL Modes
1. require (Default)
What it does:
- Enforces TLS encryption
- Validates server certificate using WebPKI (standard browser certificate authorities)
- No additional certificate configuration needed
When to use:
- Most cloud databases (AWS RDS, Google Cloud SQL, Azure, Neon, Supabase)
- Standard SSL/TLS setup
- Default choice for most applications
Example:
npx wrangler hyperdrive create my-db \
--connection-string="postgres://user:password@host:5432/database"
# SSL mode is "require" by default
No configuration needed - this is automatic.
2. verify-ca
What it does:
- Verifies server certificate is signed by expected Certificate Authority (CA)
- Prevents man-in-the-middle attacks
- Requires uploading CA certificate to Hyperdrive
When to use:
- Enhanced security requirements
- Self-signed certificates
- Private/internal certificate authorities
Setup:
Step 1: Upload CA certificate:
npx wrangler cert upload certificate-authority \
--ca-cert /path/to/root-ca.pem \
--name my-ca-cert
Output:
✅ Uploaded CA Certificate my-ca-cert
ID: ca-12345678-1234-1234-1234-123456789012
Step 2: Create Hyperdrive with CA:
npx wrangler hyperdrive create my-db \
--connection-string="postgres://user:password@host:5432/database" \
--ca-certificate-id ca-12345678-1234-1234-1234-123456789012 \
--sslmode verify-ca
3. verify-full
What it does:
- Everything from
verify-ca, PLUS - Verifies database hostname matches Subject Alternative Name (SAN) in certificate
When to use:
- Maximum security requirements
- Preventing hostname spoofing
- Compliance requirements (PCI-DSS, HIPAA)
Setup (same as verify-ca, but use --sslmode verify-full):
npx wrangler hyperdrive create my-db \
--connection-string="postgres://user:password@host:5432/database" \
--ca-certificate-id ca-12345678-1234-1234-1234-123456789012 \
--sslmode verify-full
Certificate Requirements
CA Certificate Format
Must be:
- PEM format (
.pemfile) - Root CA or Intermediate CA certificate
- Region-specific (not global bundle with multiple CAs)
Example CA Certificate (root-ca.pem):
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
...
-----END CERTIFICATE-----
Get CA Certificate:
AWS RDS:
wget https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem
# Use region-specific bundle (NOT global bundle)
Google Cloud SQL:
# Download from Cloud SQL instance details page
# Instance → Connections → Server CA certificate
Azure Database:
wget https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem
Client Certificates (mTLS)
Overview
What is mTLS?
- Mutual TLS: Both client and server authenticate each other
- Hyperdrive provides client certificate to database
- Database verifies certificate before allowing connection
When to use:
- Database requires client certificate authentication
- Enhanced security beyond username/password
- Compliance requirements
Setup
Step 1: Generate Client Certificate (if needed):
# Generate private key
openssl genrsa -out client-key.pem 2048
# Generate certificate signing request (CSR)
openssl req -new -key client-key.pem -out client.csr
# Get certificate from your CA (or self-sign for testing)
openssl x509 -req -in client.csr -CA root-ca.pem -CAkey root-ca-key.pem \
-CAcreateserial -out client-cert.pem -days 365
Step 2: Upload Client Certificate to Hyperdrive:
npx wrangler cert upload mtls-certificate \
--cert /path/to/client-cert.pem \
--key /path/to/client-key.pem \
--name my-client-cert
Output:
✅ Uploaded client certificate my-client-cert
ID: mtls-87654321-4321-4321-4321-210987654321
Step 3: Create Hyperdrive with Client Certificate:
npx wrangler hyperdrive create my-db \
--connection-string="postgres://user:password@host:5432/database" \
--mtls-certificate-id mtls-87654321-4321-4321-4321-210987654321
Optionally combine with server certificates:
npx wrangler hyperdrive create my-db \
--connection-string="postgres://..." \
--ca-certificate-id ca-12345678-1234-1234-1234-123456789012 \
--mtls-certificate-id mtls-87654321-4321-4321-4321-210987654321 \
--sslmode verify-full
Complete Setup Examples
Example 1: AWS RDS with verify-full
# 1. Download AWS RDS CA certificate (region-specific)
wget https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem
# 2. Upload CA certificate
npx wrangler cert upload certificate-authority \
--ca-cert us-east-1-bundle.pem \
--name aws-rds-us-east-1-ca
# Output: ID = ca-abc123...
# 3. Create Hyperdrive
npx wrangler hyperdrive create aws-rds-db \
--connection-string="postgres://admin:password@mydb.abc123.us-east-1.rds.amazonaws.com:5432/postgres" \
--ca-certificate-id ca-abc123... \
--sslmode verify-full
Example 2: Self-Hosted with mTLS
# 1. Upload server CA certificate
npx wrangler cert upload certificate-authority \
--ca-cert /path/to/server-ca.pem \
--name my-server-ca
# Output: ID = ca-server123...
# 2. Upload client certificate
npx wrangler cert upload mtls-certificate \
--cert /path/to/client-cert.pem \
--key /path/to/client-key.pem \
--name my-client-cert
# Output: ID = mtls-client456...
# 3. Create Hyperdrive with both
npx wrangler hyperdrive create secure-db \
--connection-string="postgres://user:password@secure-db.example.com:5432/mydb" \
--ca-certificate-id ca-server123... \
--mtls-certificate-id mtls-client456... \
--sslmode verify-full
Example 3: Basic SSL (Default)
# Most cloud databases (AWS, GCP, Azure, Neon, Supabase)
# No certificate configuration needed
npx wrangler hyperdrive create my-db \
--connection-string="postgres://user:password@host:5432/database"
# SSL mode "require" is automatic
Database Configuration
PostgreSQL SSL Setup
postgresql.conf:
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root.crt' # For client certificate verification
# Optional: Require SSL
ssl_min_protocol_version = 'TLSv1.2'
pg_hba.conf (require SSL):
# TYPE DATABASE USER ADDRESS METHOD
hostssl all all 0.0.0.0/0 md5
# Or require client certificates
hostssl all all 0.0.0.0/0 cert
Restart PostgreSQL:
sudo systemctl restart postgresql
MySQL SSL Setup
my.cnf or my.ini:
[mysqld]
require_secure_transport = ON
ssl-ca = /path/to/ca-cert.pem
ssl-cert = /path/to/server-cert.pem
ssl-key = /path/to/server-key.pem
Require client certificates (MySQL user):
CREATE USER 'hyperdrive'@'%' IDENTIFIED BY 'password' REQUIRE X509;
GRANT ALL PRIVILEGES ON mydb.* TO 'hyperdrive'@'%';
FLUSH PRIVILEGES;
Restart MySQL:
sudo systemctl restart mysql
Troubleshooting
Error: "TLS not supported by the database"
Cause: Database doesn't have SSL/TLS enabled.
Solution:
- Enable SSL in database configuration
- Restart database
- Verify SSL enabled:
SHOW ssl;(MySQL) orSHOW ssl;(PostgreSQL)
PostgreSQL verification:
SHOW ssl;
-- Should return "on"
MySQL verification:
SHOW VARIABLES LIKE 'have_ssl';
-- Should return "YES"
Error: "TLS handshake failed: cert validation failed"
Cause: Server certificate not signed by expected CA.
Solutions:
- Verify correct CA certificate uploaded
- Check CA certificate is for correct region (AWS RDS)
- Ensure CA certificate format is PEM
- Verify connection string hostname matches certificate SAN (verify-full mode)
Error: "Server return error and closed connection"
Cause: Database requires client certificate, but none provided.
Solution: Upload client certificate and configure Hyperdrive with mTLS:
npx wrangler cert upload mtls-certificate \
--cert client-cert.pem \
--key client-key.pem \
--name my-cert
npx wrangler hyperdrive create my-db \
--connection-string="..." \
--mtls-certificate-id <id>
Error: "Certificate has expired"
Cause: Server certificate or client certificate expired.
Solutions:
- Renew certificate from certificate authority
- Upload new certificate to Hyperdrive
- Update Hyperdrive configuration
Local Development
SSL in Local Development
Option 1: Disable SSL for local database (NOT recommended):
# Local PostgreSQL without SSL
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgres://user:password@localhost:5432/db?sslmode=disable"
Option 2: Use Tunnel for local database (Recommended):
# Use Cloudflare Tunnel to local database (keeps SSL)
cloudflared tunnel create local-db
cloudflared tunnel run local-db
# Hyperdrive connects via tunnel with SSL
Option 3: Self-signed certificates for local dev:
# Generate self-signed cert
openssl req -new -x509 -days 365 -nodes -out server.crt -keyout server.key
# Configure local PostgreSQL to use it
# Then use verify-ca mode with local CA
Best Practices
- Use default
requiremode unless you have specific security requirements - Use verify-full for production if handling sensitive data
- Store certificates securely - don't commit to git
- Rotate certificates regularly - before expiration
- Test certificate setup in staging before production
- Use region-specific CA bundles (AWS RDS) not global bundles
- Document certificate IDs in project README
- Monitor certificate expiration (set calendar reminders)