Security
Encryption
TLS
Developer Reference

Encryption at Rest vs Encryption in Transit

Two distinct requirements that protect against two different threats. Most systems need both — and confusing them is a common source of security gaps.

Quick Answer

Encryption at rest protects data stored on disk or in a database from physical or logical access to the storage medium. Encryption in transit protects data moving between systems from eavesdropping on the network. They address different threat models and are both required in most production systems.

TL;DR

  • Encryption at rest protects stored data — databases, files, backups, object storage.
  • Encryption in transit protects data moving over a network — HTTPS, API calls, service-to-service traffic.
  • They protect against different attackers: at rest = physical or logical storage access; in transit = network interception.
  • HTTPS does not encrypt data at rest. Data arriving over TLS is still plaintext in your database unless you encrypt it there too.
  • Most compliance frameworks (SOC 2, PCI DSS, HIPAA) require both.
  • At rest: use AES-256 with proper key management. In transit: use TLS 1.2+ with modern cipher suites.
  • Neither replaces proper access controls and authorization — encryption is not a substitute for authorization.

Definitions

Encryption at Rest

Data is encrypted while stored on a physical medium — hard drives, SSDs, cloud object storage, database files, backups, and archives.

Protection applies when data is not being actively used. The threat is someone gaining access to the physical hardware, a storage snapshot, or a database export.

Typical tech: AES-256 (disk encryption, database TDE, field-level encryption), envelope encryption with KMS.

Encryption in Transit

Data is encrypted while moving between two systems — browser to server, service to service, client to database, or any network hop.

Protection applies when data is being transmitted. The threat is a network attacker intercepting, reading, or modifying traffic in flight.

Typical tech: TLS 1.2/1.3 (HTTPS, WSS, SMTPS), mTLS for service-to-service, VPN for internal networks.

Side-by-Side Comparison

At RestIn Transit
Threat modelPhysical storage access, DB export/backup theft, cloud storage misconfigurationNetwork eavesdropping (MITM), traffic analysis, downgrade attacks
Where it appliesDatabases, object storage (S3, GCS), disk volumes, backups, archives, log filesHTTP/API traffic, WebSockets, email (SMTPS), database connections, internal service calls
Typical techAES-256-GCM, database TDE (Transparent Data Encryption), filesystem encryption (LUKS, FileVault, BitLocker), envelope encryptionTLS 1.3 (HTTPS), mTLS for service-to-service, DTLS for UDP, WireGuard/IPSec for VPN
Key managementCritical — keys must be stored separately from data. Use KMS (AWS KMS, GCP KMS, HashiCorp Vault). Rotate keys periodically.Certificate lifecycle management. Auto-renew with ACME (Let's Encrypt). Session keys are ephemeral (no rotation needed).
Common mistakesEncrypting with a key stored next to the data; not encrypting backups; using ECB mode; skipping field-level encryption for sensitive columnsIgnoring cert warnings; disabling verify in code; mixed content; accepting old TLS versions; not using mTLS internally
ExamplesEncrypted RDS instance, S3 bucket with SSE-KMS, LUKS-encrypted disk, bcrypt-hashed passwords, AES-encrypted credit card numbersHTTPS website, TLS-terminated load balancer, encrypted Postgres connection, mTLS between microservices

Real-World Examples

At Rest

Relational databases

PostgreSQL, MySQL, and SQL Server all support Transparent Data Encryption (TDE), which encrypts data files at the storage layer. For column-level protection (e.g., SSNs, credit cards), add field-level encryption in the application using AES-256-GCM.

Object storage (S3, GCS, Azure Blob)

Enable SSE-KMS (Server-Side Encryption with Customer Managed Keys) on every bucket. With SSE-S3 the cloud provider manages the key — with SSE-KMS you control it.

Backups and snapshots

Backups are high-value targets and are often forgotten. Encrypt all database snapshots and backup archives. Never store plaintext backups in a different location from your encrypted primary data.

Disk volumes

LUKS (Linux), FileVault (macOS), or BitLocker (Windows) encrypt the entire disk. This protects against a stolen laptop or decommissioned server drive but does not protect against an OS-level attacker with an unlocked system.

In Transit

HTTPS APIs

All external HTTP traffic must use TLS. Configure your load balancer or CDN (CloudFront, nginx) to terminate TLS and redirect port 80 to 443. Use HSTS headers to prevent protocol downgrades.

Service-to-service calls

Internal microservice traffic often travels over a private network but is still vulnerable to lateral movement attacks. Use mTLS (mutual TLS) or a service mesh (Istio, Linkerd) so every service authenticates both directions.

Browser traffic

HTTPS via TLS 1.3 covers browser-to-server communication. Combine with HSTS (HTTP Strict Transport Security), CSP (Content Security Policy), and avoiding mixed content.

Database connections

Applications connecting to databases (Postgres, MySQL, Redis, MongoDB) should enable TLS on the connection string. Many cloud-managed databases require TLS by default; verify it is not being disabled.

What You Need for Each

Encryption at Rest Checklist

  • Enable storage-layer encryption on all databases (TDE)
  • Enable encryption on all object storage buckets
  • Encrypt all backup snapshots
  • Use customer-managed keys (CMK) via KMS for sensitive data
  • Store encryption keys separately from encrypted data
  • Enable key rotation (annual at minimum)
  • Add field-level encryption for the most sensitive columns (PII, card data)
  • Audit key access with logging

Encryption in Transit Checklist

  • TLS 1.2 minimum, TLS 1.3 preferred
  • Automate certificate renewal (ACME / Certbot)
  • Enable HSTS with includeSubDomains
  • Redirect all HTTP → HTTPS (no mixed content)
  • Use AEAD cipher suites only (AES-GCM, ChaCha20-Poly1305)
  • Enable mTLS for internal service-to-service calls
  • Verify TLS on all outbound API calls (never disable verify)
  • Monitor certificate expiry with alerting

Common Misconceptions

"HTTPS means my data is secure everywhere"

HTTPS protects data during transmission. Once the data arrives at the server, TLS is no longer involved. If your database is not encrypted and is breached, the attacker gets plaintext data regardless of whether it was sent over HTTPS. You need encryption at rest separately.

"Encryption at rest replaces authorization"

Encryption at rest protects against physical or unauthenticated storage access — it does not protect against an authenticated application user reading data they should not have access to. A misconfigured API endpoint that exposes all user records bypasses encryption entirely. Authorization controls and encryption are both required and serve different purposes.

Common Mistakes

Encrypting data but storing the key in the same database

If an attacker dumps the database, they get both the ciphertext and the key. Keys must be stored in a separate, access-controlled system (KMS, Vault, HSM).

Not encrypting database backups

Backups are a common attack vector. Your live database might be locked down, but if backups are stored as plaintext files in an S3 bucket, that is the easier target.

Relying on cloud provider defaults without understanding them

AWS S3 and RDS encrypt at rest by default now, but with provider-managed keys. If the provider's IAM is misconfigured or the provider is subpoenaed, your data is accessible. For regulated data, use customer-managed keys.

Disabling TLS verification in application code

Setting verify=False or rejectUnauthorized:false in dev environments and shipping to production removes all authentication guarantees. The channel is encrypted but you cannot verify who you are talking to.

Not encrypting internal network traffic

Internal traffic on a private VPC or Kubernetes cluster is not automatically encrypted. An attacker with access to the internal network can still intercept plaintext inter-service calls. Use mTLS or a service mesh.

Try the Tool: JWT Decoder

If you are debugging API authentication, JWTs are a common token format transmitted over TLS-encrypted connections. Use the JWT Decoder to inspect claims, check the signing algorithm, verify expiry timestamps, and understand what is inside the token — all locally in your browser without uploading the token anywhere.

Open JWT Decoder →

Frequently Asked Questions

Related Resources