Secure connections
Save PostgreSQL connection details with encrypted passwords, SSL settings, URL import, testing, search, edit, and delete actions.
Connect PostgreSQL with SSL
PostgreSQL has six sslmode values and only two of them actually protect you. The difference between them is not encryption — it is whether anyone checked who they were encrypting to.
Short answer: sslmode=require encrypts the connection but performs no certificate verification, so it does not protect against an attacker who can intercept your traffic. Use verify-full for anything crossing a network you do not control: it validates the certificate chain against a CA you supply and checks that the hostname matches. That is the mode that actually prevents interception.

PgDeck is shaped around PostgreSQL tasks that happen every day: connect, inspect, filter, edit, query, manage structure, copy, and export.
Save PostgreSQL connection details with encrypted passwords, SSL settings, URL import, testing, search, edit, and delete actions.
Browse schemas and tables, search the table list, pin favorites, filter rows, sort columns, resize columns, and paginate results.
Run SELECT and non-SELECT statements from multi-tab SQL editors with syntax highlighting and interactive query results.
Edit cells, add rows, duplicate rows, set NULL, stage deletes, review pending changes, and commit everything in one transaction.
disable never encrypts. allow and prefer will use TLS if offered and silently fall back to plaintext if not — prefer is the default, which means an unconfigured client may not be encrypted at all. require always encrypts but verifies nothing. verify-ca checks the certificate chain. verify-full also checks that the hostname you connected to matches the certificate.
Download the CA certificate from your provider, then reference it with sslrootcert. Without a root certificate, verify modes cannot work — and with only require, an attacker positioned between you and the server can present their own certificate, decrypt everything, and forward it on. Your connection is encrypted to the wrong party.
postgres://user:password@db.example.com:5432/mydb?sslmode=verify-full&sslrootcert=/path/to/ca.crtDo not assume. pg_stat_ssl reports whether your own backend is using TLS, which version, and which cipher. If ssl comes back false while you believed you were using SSL, your sslmode was probably prefer and the server declined.
SELECT ssl, version, cipher, bits
FROM pg_stat_ssl
WHERE pid = pg_backend_pid();Managed providers do this for you. On your own server, set ssl = on in postgresql.conf with a certificate and key, then restart. The key must be readable only by the postgres user or the server refuses to start — that permission check is deliberate.
# postgresql.conf
ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
# The key must not be group- or world-readable
chmod 600 server.key
chown postgres:postgres server.keyA client-side sslmode is a request, not a guarantee — it protects that client only. To make encryption mandatory for everyone, use hostssl rather than host in pg_hba.conf, which refuses any non-TLS connection matching that rule. Reload afterwards; pg_hba.conf does not need a restart.
# pg_hba.conf — hostssl refuses unencrypted connections
hostssl all all 0.0.0.0/0 scram-sha-256
SELECT pg_reload_conf();Encryption without authentication protects against passive eavesdropping and nothing else. With sslmode=require the client accepts any certificate, including a self-signed one generated by whoever is sitting between you and the server. They terminate your TLS session, read your credentials and your data in clear, and open their own connection onward. Everything looks normal at both ends. verify-full is what closes this, by checking the certificate chains to a CA you trust and that the hostname matches.
verify-ca confirms the certificate was issued by a CA you trust but not that it was issued for the host you are connecting to. If the CA signs certificates for many hosts — which is exactly the case with a cloud provider's shared CA — another customer's valid certificate would pass. verify-full adds the hostname check and is the mode to use unless you have a specific reason not to.
Every managed provider publishes a CA bundle: Amazon RDS has regional bundles, and Supabase, Neon, Azure, and Google Cloud SQL each provide theirs from the console. Download it over HTTPS from the provider's own documentation, store it somewhere stable, and point sslrootcert at it. Do not copy a certificate from a forum post.
sslcert and sslkey let the client present its own certificate, so the server can authenticate you by certificate rather than password. Combined with the cert authentication method in pg_hba.conf, this removes passwords from the connection entirely. It is more setup and more key rotation, and it is the strongest option available where that trade is worth making.
Encrypting the connection does not make a database safe to expose to the internet. Automated scanners find open port 5432 quickly and will attempt credential stuffing against it regardless of TLS. Keep the database on a private network and reach it through a bastion host or SSH tunnel, and use TLS as well rather than instead.
More on choosing, comparing, and running a PostgreSQL desktop client.
verify-full for anything crossing a network you do not control. It encrypts the connection, validates the server certificate against a CA you supply, and checks that the hostname matches. require encrypts but verifies nothing, which leaves you open to interception.
Only against passive eavesdropping. require accepts any certificate, so an attacker able to intercept your traffic can present their own, decrypt everything, and forward it on undetected. Use verify-full, which checks the certificate chain and the hostname.
verify-ca checks the certificate was issued by a CA you trust. verify-full also checks the certificate was issued for the host you are connecting to. Since cloud providers sign many customers' certificates with a shared CA, verify-ca alone would accept another customer's certificate.
Query pg_stat_ssl for your own backend: SELECT ssl, version, cipher FROM pg_stat_ssl WHERE pid = pg_backend_pid(). If ssl is false, your sslmode was probably prefer, which silently falls back to an unencrypted connection.
Use hostssl instead of host in pg_hba.conf, which refuses any connection not using TLS for matching rules, then reload with SELECT pg_reload_conf(). A client-side sslmode only protects that one client; the server-side rule applies to everyone.