Skip to main content
Supabase encrypts all data by default, both at rest and in transit, ensuring your data is protected throughout its lifecycle. This encryption is transparent and requires no configuration.

Encryption Overview

Supabase implements a comprehensive encryption strategy:

At Rest

All data stored on disk is encrypted with AES-256

In Transit

All connections use TLS 1.2+ encryption

Backups

Database backups are encrypted before storage

Automatic

No configuration needed, always enabled

Encryption at Rest

Database Storage

All data stored in your Postgres database is encrypted at rest using:
  • Algorithm: AES-256 encryption
  • Scope: All database files, indexes, and WAL files
  • Key Management: Managed by cloud provider infrastructure
  • Performance: Transparent encryption with minimal overhead
Encryption at rest is provided by the underlying cloud infrastructure and is always enabled. You cannot disable it.

What is Encrypted

The following are encrypted at rest:
  • Database tables: All user data in tables
  • Indexes: All database indexes
  • Write-Ahead Logs (WAL): Transaction logs
  • Backups: Daily backups and PITR snapshots
  • Storage objects: Files uploaded to Supabase Storage
  • Temporary files: Any temporary database files

Storage Encryption

Files uploaded to Supabase Storage are also encrypted:
// Files are automatically encrypted when uploaded
const { data, error } = await supabase
  .storage
  .from('avatars')
  .upload('public/avatar1.png', file)

// Encryption is transparent - no special handling needed

Encryption in Transit

All network communication is encrypted using TLS (Transport Layer Security).

HTTPS for APIs

All HTTP APIs use TLS 1.2 or higher:
  • PostgREST (REST API): https://your-project.supabase.co/rest/v1
  • GoTrue (Auth): https://your-project.supabase.co/auth/v1
  • Realtime: wss://your-project.supabase.co/realtime/v1 (WSS = WebSocket Secure)
  • Storage: https://your-project.supabase.co/storage/v1
HTTPS is enforced on all API endpoints. HTTP requests are automatically redirected to HTTPS.

PostgreSQL Connections

Database connections support SSL/TLS encryption:
# SSL is enabled by default
psql "postgresql://postgres:[password]@db.your-project.supabase.co:5432/postgres"

# Explicitly require SSL
psql "postgresql://postgres:[password]@db.your-project.supabase.co:5432/postgres?sslmode=require"

SSL Modes

PostgreSQL supports multiple SSL modes:
ModeDescriptionProtection
disableNo SSLNone (not recommended)
allowTry SSL, fallback to unencryptedOpportunistic
preferPrefer SSL, fallback to unencryptedOpportunistic (default)
requireRequire SSL, but don’t verify certPrevents eavesdropping
verify-caRequire SSL, verify CAPrevents MITM attacks
verify-fullRequire SSL, verify CA and hostnameStrongest protection
For production applications, use verify-full for maximum security.

Using verify-full Mode

1

Download the CA certificate

Get your CA certificate from the Dashboard:
  1. Go to DatabaseSettings
  2. Scroll to SSL Configuration
  3. Download Certificate Authority (CA) certificate
2

Add to trusted CAs

Add the certificate to PostgreSQL’s trusted CAs:
cat prod-ca-2021.crt >> ~/.postgresql/root.crt
3

Connect with verify-full

Connect using the highest security mode:
psql "postgresql://postgres:[password]@db.your-project.supabase.co:5432/postgres?sslmode=verify-full"
Or with connection string:
const { Pool } = require('pg')

const pool = new Pool({
  host: 'db.your-project.supabase.co',
  port: 5432,
  database: 'postgres',
  user: 'postgres',
  password: 'your-password',
  ssl: {
    rejectUnauthorized: true,
    ca: fs.readFileSync('prod-ca-2021.crt').toString(),
  },
})

SSL Enforcement

Enforce SSL for all database connections:

Enable SSL Enforcement

  1. Go to DatabaseSettings
  2. Find SSL Configuration
  3. Enable Enforce SSL on incoming connections
  4. Click Confirm
Enabling SSL enforcement triggers a brief database reboot (usually seconds, longer for large databases).

Check SSL Status

Verify SSL enforcement is enabled:
supabase ssl-enforcement --project-ref <your-ref> get --experimental
Output:
SSL is being enforced.

Client Library Encryption

JavaScript/TypeScript

The Supabase client automatically uses HTTPS:
import { createClient } from '@supabase/supabase-js'

// Automatically uses HTTPS
const supabase = createClient(
  'https://your-project.supabase.co', // HTTPS required
  'your-anon-key'
)

Python

from supabase import create_client, Client

# Automatically uses HTTPS
url: str = "https://your-project.supabase.co"
key: str = "your-anon-key"
supabase: Client = create_client(url, key)

Flutter/Dart

import 'package:supabase_flutter/supabase_flutter.dart';

await Supabase.initialize(
  url: 'https://your-project.supabase.co', // HTTPS enforced
  anonKey: 'your-anon-key',
);

Application-Level Encryption

For additional security, implement application-level encryption for sensitive fields:

Example: Encrypting Sensitive Data

import { createClient } from '@supabase/supabase-js'
import CryptoJS from 'crypto-js'

const supabase = createClient(url, key)
const ENCRYPTION_KEY = process.env.ENCRYPTION_KEY // Store securely!

// Encrypt before storing
const encryptField = (text) => {
  return CryptoJS.AES.encrypt(text, ENCRYPTION_KEY).toString()
}

// Decrypt after retrieving  
const decryptField = (ciphertext) => {
  const bytes = CryptoJS.AES.decrypt(ciphertext, ENCRYPTION_KEY)
  return bytes.toString(CryptoJS.enc.Utf8)
}

// Store encrypted data
const { data, error } = await supabase
  .from('user_secrets')
  .insert({
    user_id: userId,
    ssn: encryptField('123-45-6789'),
    credit_card: encryptField('4111-1111-1111-1111')
  })

// Retrieve and decrypt
const { data: secrets } = await supabase
  .from('user_secrets')
  .select('*')
  .eq('user_id', userId)
  .single()

const decryptedSSN = decryptField(secrets.ssn)
Application-level encryption adds security but:
  • Cannot be queried or indexed by the database
  • Adds complexity to your application
  • Requires secure key management

Key Management

Platform Encryption Keys

Supabase manages encryption keys for:
  • At-rest encryption: Cloud provider managed keys
  • TLS certificates: Automatically renewed
  • JWT secrets: Rotatable via Dashboard
Platform encryption keys are managed by Supabase and the underlying cloud infrastructure. You cannot access or rotate these keys.

Application Keys

Manage your API keys securely:
1

Store securely

Use environment variables, never hardcode:
.env
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-key
2

Rotate if compromised

If keys are exposed:
  1. Go to SettingsAPI
  2. Click Generate new key
  3. Update applications
  4. Revoke old key
3

Use appropriate keys

  • anon key: Client-side applications
  • service_role key: Server-side only, never in clients

Compliance

Supabase encryption meets compliance requirements:

Certifications

  • SOC 2 Type II: Audited encryption controls
  • GDPR: EU data protection requirements
  • HIPAA: Healthcare data (Enterprise plan)
  • ISO 27001: Information security standards

Data Residency

Choose your database region for data residency:
  • US East: Virginia
  • US West: Oregon
  • EU West: Ireland
  • EU Central: Frankfurt
  • AP Southeast: Singapore
  • AP Northeast: Tokyo
  • AP South: Mumbai
All data, including backups, remains in your selected region.

Best Practices

1

Always use HTTPS

Never use http:// in production - always https://
2

Enable SSL enforcement

Require SSL for all database connections
3

Use verify-full for database

Maximum security with certificate verification
4

Encrypt sensitive fields

Add application-level encryption for highly sensitive data
5

Secure API keys

Store in environment variables, rotate if exposed
6

Enable Point-in-Time Recovery

Encrypted backups with fine-grained recovery

Troubleshooting

Error: SSL connection has been closed unexpectedlySolution:
  • Verify SSL is supported by your client
  • Check SSL mode: try sslmode=require
  • Ensure firewall allows SSL connections
  • Download and use CA certificate for verify-full
Error: certificate verify failedSolution:
  • Download latest CA certificate from Dashboard
  • Ensure certificate is in correct location (~/.postgresql/root.crt)
  • Check certificate hasn’t expired
  • Verify hostname matches certificate
Error: SSL is not supportedSolution:
  • Update client library to latest version
  • Check if SSL/TLS is compiled in client
  • Use sslmode=prefer to allow fallback (not recommended for production)

Encryption Checklist

Before going to production:

Next Steps

Network Security

Configure IP restrictions and network rules

Row Level Security

Implement granular data access control

Production Checklist

Complete pre-launch security review

Compliance

Learn about compliance certifications