Unclassified

Neon ↔ Cloudflare Tunnel Configuration

Overview

Secure, encrypted tunnels connect Cloudflare Workers to Neon PostgreSQL databases across all 3 deployment profiles.


Dev Profile Tunnel

Endpoint Configuration

profile: dev
endpoint: neon.dev.integratewise.internal:5432
type: tcp
encryption: TLS 1.2
auth_method: JWT

Setup Steps

  1. Create Neon branch for dev:
neon branches create --project-id dev-project --branch dev-branch
  1. Get connection string:
neon connection-string --project-id dev-project --branch dev-branch
# postgresql://user:pass@neon.dev.integratewise.internal/dev_db
  1. Configure in Wrangler:
[env.dev.vars]
NEON_DATABASE_URL = "postgresql://user:pass@neon.dev.integratewise.internal/dev_db"
NEON_TUNNEL_ENDPOINT = "neon.dev.integratewise.internal"
  1. Generate JWT token:
openssl genrsa -out dev_key.pem 2048
openssl rsa -in dev_key.pem -pubout -out dev_pub.pem

# Create JWT payload
cat > dev_jwt_payload.json <<EOF
{
  "aud": "neon-tunnel-dev",
  "iss": "integratewise-dev",
  "sub": "dev-worker",
  "iat": $(date +%s),
  "exp": $(($(date +%s) + 86400))
}
EOF

# Sign JWT (using offline tool or service)
# Store in: NEON_TUNNEL_AUTH_TOKEN
  1. Test connection from Worker:
// services/gateway/src/index.ts
const client = new postgres.Client({
  connectionString: env.NEON_DATABASE_URL,
  ssl: {
    rejectUnauthorized: true,
    ca: env.NEON_TUNNEL_CERT, // If using mTLS
  },
});

await client.connect();

Monitoring

# Check tunnel status
curl https://neon.dev.integratewise.internal/health

# Monitor latency
neon telemetry --project-id dev-project

# View connection pool
SELECT count(*) FROM pg_stat_activity;

Customer Zero Profile Tunnel

Endpoint Configuration

profile: customer-zero
endpoint: neon.customer-zero.integratewise.internal:5432
type: tcp
encryption: TLS 1.3
auth_method: mTLS (certificate pinning)
certificate_rotation: every 60 days
backup_certificates: 2

Setup Steps

  1. Create dedicated Neon project for Customer Zero:
neon projects create --name "IntegrateWise Customer Zero"
neon branches create --project-id customer-zero-project --branch production
  1. Get connection string:
neon connection-string \
  --project-id customer-zero-project \
  --branch production
# postgresql://user:pass@neon.customer-zero.integratewise.internal/customer_zero_db
  1. Generate mTLS certificates (Let's Encrypt):
# Primary certificate (rotate every 60 days)
certbot certonly \
  --standalone \
  --domain neon.customer-zero.integratewise.internal \
  --email ops@integratewise.com

# Private key
openssl pkcs8 -in /etc/letsencrypt/live/neon.customer-zero.integratewise.internal/privkey.pem \
  -topk8 -nocrypt -out customer_zero_private.key

# Public cert
cp /etc/letsencrypt/live/neon.customer-zero.integratewise.internal/fullchain.pem \
  customer_zero_cert.pem

# CA bundle
curl https://letsencrypt.org/certs/isrgrootx1.pem > ca_bundle.pem
  1. Configure in Wrangler:
[env.customer-zero.vars]
NEON_DATABASE_URL = "postgresql://user:pass@neon.customer-zero.integratewise.internal/customer_zero_db"
NEON_TUNNEL_ENDPOINT = "neon.customer-zero.integratewise.internal"
NEON_TUNNEL_REGIONS = "us-east"
NEON_CONNECTION_POOL_MIN = "10"
NEON_CONNECTION_POOL_MAX = "100"
  1. Store certificates in Cloudflare Secrets:
wrangler secret put NEON_TUNNEL_CERT --env customer-zero < customer_zero_cert.pem
wrangler secret put NEON_TUNNEL_KEY --env customer-zero < customer_zero_private.key
wrangler secret put NEON_TUNNEL_AUTH_TOKEN --env customer-zero "jwt_token_here"
  1. Enable Connection Pool (Neon):
neon connection-pooling enable \
  --project-id customer-zero-project \
  --branch production \
  --pool-size 25

Connection Pool Configuration

-- pgBouncer pooling on Neon
SET client_encoding = 'UTF-8';

-- Create pool connection
SELECT create_pool_connection(
  'customer_zero_pool',
  'transaction',
  25,
  300
);

Monitoring

# Check tunnel certificate expiration
openssl x509 -in customer_zero_cert.pem -noout -dates
# notBefore=Dec 15 10:00:00 2024 GMT
# notAfter=Mar 15 10:00:00 2025 GMT

# Monitor connection pool
SELECT
  database,
  user,
  state,
  count(*) as connections
FROM pg_stat_activity
GROUP BY database, user, state;

# Health check
curl -X GET https://neon.customer-zero.integratewise.internal/health \
  --cert customer_zero_cert.pem \
  --key customer_zero_private.key

Backup Certificate Rotation

# Day 1: Create backup cert 1
certbot certonly \
  --standalone \
  --domain neon.customer-zero.integratewise.internal-backup-1 \
  --email ops@integratewise.com

# Day 30: Create backup cert 2
certbot certonly \
  --standalone \
  --domain neon.customer-zero.integratewise.internal-backup-2 \
  --email ops@integratewise.com

# Day 60: Rotate primary cert
certbot renew --force-renewal

# Update secrets
wrangler secret put NEON_TUNNEL_CERT_BACKUP_1 --env customer-zero < backup1_cert.pem
wrangler secret put NEON_TUNNEL_CERT_BACKUP_2 --env customer-zero < backup2_cert.pem

External Users Profile Tunnel

Endpoint Configuration

profile: external-users
endpoints:
  - us-east.neon.integratewise.io:5432
  - eu-west.neon.integratewise.io:5432
  - ap-south.neon.integratewise.io:5432
type: tcp
encryption: TLS 1.3 + TLS 1.2 fallback
auth_method: mTLS with certificate pinning
certificate_rotation: every 330 days (before expiry)
backup_certificates: 3
circuit_breaker:
  failure_threshold: 50%
  timeout: 60s
  half_open_requests: 3

Setup Steps

  1. Create multi-tenant Neon project:
neon projects create --name "IntegrateWise External Users"
neon branches create --project-id external-users-project --branch production

# Enable read replicas for each region
neon replicas create \
  --project-id external-users-project \
  --branch production \
  --region us-east-1

neon replicas create \
  --project-id external-users-project \
  --branch production \
  --region eu-west-1

neon replicas create \
  --project-id external-users-project \
  --branch production \
  --region ap-south-1
  1. Get connection strings for each region:
# US East
neon connection-string \
  --project-id external-users-project \
  --branch production \
  --replica us-east
# postgresql://user:pass@us-east.neon.integratewise.io/multi_tenant_db

# EU West
neon connection-string \
  --project-id external-users-project \
  --branch production \
  --replica eu-west
# postgresql://user:pass@eu-west.neon.integratewise.io/multi_tenant_db

# AP South
neon connection-string \
  --project-id external-users-project \
  --branch production \
  --replica ap-south
# postgresql://user:pass@ap-south.neon.integratewise.io/multi_tenant_db
  1. Generate DigiCert EV certificates (1-year validity):
# Primary certificate
certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  --domain neon.integratewise.io \
  --domain "*.neon.integratewise.io" \
  --preferred-chain "DigiCert Global Root CA" \
  --email ops@integratewise.com

# Extract keys for each region
openssl pkcs8 -in /etc/letsencrypt/live/neon.integratewise.io/privkey.pem \
  -topk8 -nocrypt -out external_users_private.key

openssl x509 -in /etc/letsencrypt/live/neon.integratewise.io/fullchain.pem \
  -out external_users_cert.pem

# Create region-specific cert aliases (SANs already included)
cp external_users_cert.pem us_east_cert.pem
cp external_users_cert.pem eu_west_cert.pem
cp external_users_cert.pem ap_south_cert.pem
  1. Configure in Wrangler:
[env.external-users.vars]
NEON_TUNNEL_ENDPOINT = "neon.integratewise.io"
NEON_TUNNEL_REGIONS = "us-east,eu-west,ap-south"
NEON_CONNECTION_POOL_MIN = "50"
NEON_CONNECTION_POOL_MAX = "500"
NEON_POOL_IDLE_TIMEOUT = "30s"
NEON_POOL_STATEMENT_CACHE_SIZE = "50"
NEON_CIRCUIT_BREAKER_ENABLED = "true"
NEON_CIRCUIT_BREAKER_FAILURE_THRESHOLD = "50"
NEON_CIRCUIT_BREAKER_TIMEOUT = "60000"
  1. Store certificates in Cloudflare Secrets (with backup rotation):
# Primary
wrangler secret put NEON_TUNNEL_CERT --env external-users < external_users_cert.pem
wrangler secret put NEON_TUNNEL_KEY --env external-users < external_users_private.key

# Backup 1 (created day 1)
wrangler secret put NEON_TUNNEL_CERT_BACKUP_1 --env external-users < backup1_cert.pem

# Backup 2 (created day 180)
wrangler secret put NEON_TUNNEL_CERT_BACKUP_2 --env external-users < backup2_cert.pem

# Backup 3 (created day 300, before primary expires)
wrangler secret put NEON_TUNNEL_CERT_BACKUP_3 --env external-users < backup3_cert.pem
  1. Enable advanced pooling:
neon connection-pooling enable \
  --project-id external-users-project \
  --branch production \
  --pool-size 100 \
  --pool-mode transaction \
  --idle-timeout 30

# Per-region pooling
for region in us-east eu-west ap-south; do
  neon connection-pooling enable \
    --project-id external-users-project \
    --replica $region \
    --pool-size 100 \
    --pool-mode transaction \
    --idle-timeout 30
done
  1. Enable Row-Level Security (RLS) on all tables:
-- Enable RLS on tables
ALTER TABLE tenants ENABLE ROW LEVEL SECURITY;
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE connectors ENABLE ROW LEVEL SECURITY;
-- ... etc

-- Create policy for tenant isolation
CREATE POLICY tenant_isolation_policy ON users
  USING (tenant_id = current_setting('app.current_tenant_id')::uuid);

CREATE POLICY tenant_isolation_policy ON connectors
  USING (tenant_id = current_setting('app.current_tenant_id')::uuid);

-- ... etc for all multi-tenant tables

Connection Pool Configuration

-- Configure pgBouncer for multi-region
SET client_encoding = 'UTF-8';

-- US East
SELECT create_pool_connection(
  'us_east_pool',
  'transaction',
  100,
  30
);

-- EU West
SELECT create_pool_connection(
  'eu_west_pool',
  'transaction',
  100,
  30
);

-- AP South
SELECT create_pool_connection(
  'ap_south_pool',
  'transaction',
  100,
  30
);

Monitoring

# Certificate expiration check (automated weekly)
for cert in us_east_cert.pem eu_west_cert.pem ap_south_cert.pem; do
  echo "=== $cert ==="
  openssl x509 -in $cert -noout -dates -subject
  # Alert if expires in < 30 days
done

# Multi-region connection pool status
for region in us-east eu-west ap-south; do
  echo "=== $region region ==="
  curl -X GET "https://$region.neon.integratewise.io/health" \
    --cert external_users_cert.pem \
    --key external_users_private.key \
    --insecure  # In prod, verify cert
done

# Circuit breaker metrics
SELECT
  endpoint,
  failures,
  successes,
  failure_rate,
  circuit_state
FROM circuit_breaker_metrics
WHERE profile = 'external-users'
ORDER BY endpoint;

# Connection pool status per tenant
SELECT
  tenant_id,
  active_connections,
  idle_connections,
  total_connections,
  region
FROM pg_stat_activity
GROUP BY tenant_id, region;

Automatic Certificate Rotation

#!/bin/bash
# certificate-rotation.sh - Run weekly

PROFILE="external-users"
CERT_EXPIRY_WARNING_DAYS=30

check_certificate_expiry() {
  local cert_file=$1
  local expiry_date=$(openssl x509 -in $cert_file -noout -dates | grep notAfter | cut -d= -f2)
  local expiry_epoch=$(date -d "$expiry_date" +%s)
  local now_epoch=$(date +%s)
  local days_until_expiry=$(( ($expiry_epoch - $now_epoch) / 86400 ))

  echo "Certificate expires in: $days_until_expiry days"

  if [ $days_until_expiry -lt $CERT_EXPIRY_WARNING_DAYS ]; then
    echo "ALERT: Certificate expiring in $days_until_expiry days"

    # Rotate certificates
    certbot renew --force-renewal \
      --dns-cloudflare \
      --domain neon.integratewise.io

    # Update backups (shift them)
    mv backup2_cert.pem backup3_cert.pem
    mv backup1_cert.pem backup2_cert.pem
    cp external_users_cert.pem backup1_cert.pem

    # Update secrets
    wrangler secret put NEON_TUNNEL_CERT --env $PROFILE < external_users_cert.pem
    wrangler secret put NEON_TUNNEL_CERT_BACKUP_1 --env $PROFILE < backup1_cert.pem
    wrangler secret put NEON_TUNNEL_CERT_BACKUP_2 --env $PROFILE < backup2_cert.pem
    wrangler secret put NEON_TUNNEL_CERT_BACKUP_3 --env $PROFILE < backup3_cert.pem

    # Redeploy workers
    wrangler deploy --env $PROFILE

    echo "Certificate rotation completed"
  fi
}

check_certificate_expiry "external_users_cert.pem"

Testing Tunnels

Test Dev Tunnel

# Connect directly
psql "postgresql://user:pass@neon.dev.integratewise.internal/dev_db"

# Test from Worker
curl -X POST https://api.dev.integratewise.internal/test-db \
  -H "Content-Type: application/json" \
  -d '{"query": "SELECT 1"}'

Test Customer Zero Tunnel

# Verify certificate
openssl s_client -connect neon.customer-zero.integratewise.internal:5432 \
  -cert customer_zero_cert.pem \
  -key customer_zero_private.key \
  -CAfile ca_bundle.pem

# Test from Worker
curl -X POST https://api.customer-zero.integratewise.com/test-db \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $JWT_TOKEN" \
  -d '{"query": "SELECT 1"}'

Test External Users Tunnel (Multi-region)

# Test each region
for region in us-east eu-west ap-south; do
  echo "Testing $region.neon.integratewise.io..."

  curl -X POST "https://api.integratewise.com/test-db" \
    -H "Content-Type: application/json" \
    -H "X-Region: $region" \
    -d '{"query": "SELECT 1"}' \
    --cert external_users_cert.pem \
    --key external_users_private.key
done

Troubleshooting

Certificate Issues

# Verify certificate is valid
openssl x509 -in cert.pem -noout -text

# Check certificate chain
openssl verify -CAfile ca_bundle.pem cert.pem

# Extract certificate from running connection
echo | openssl s_client -connect neon.integratewise.io:5432 2>/dev/null | openssl x509

Connection Pool Issues

# Check pool statistics
neon telemetry --project-id external-users-project | grep pool

# Monitor active connections
SELECT pid, usename, application_name, state, query
FROM pg_stat_activity
WHERE state != 'idle'
LIMIT 10;

Latency Issues

# Measure tunnel latency
time psql "postgresql://user:pass@neon.integratewise.io/multi_tenant_db" \
  -c "SELECT 1"

# Check network latency
ping neon.integratewise.io

# Trace network path
traceroute neon.integratewise.io