“Is our data encrypted?” sounds like a yes-or-no question. In practice it is two separate questions with two separate answers, and conflating them is one of the more common gaps in an otherwise reasonable security program. Data can be strongly encrypted at rest and sent across the network in plaintext. It can be encrypted in transit and stored on disk unprotected. Each configuration defends against a different attacker and fails against a different one.
This piece separates the two, explains what each actually stops, and covers the gap that trips up teams who assume “encrypted” is a single checkbox: data in use — the moment it is decrypted in memory to actually be processed.
What does encryption at rest protect against?
Encryption at rest protects data while it is stored — on a disk, in a database, in object storage, on a backup tape. The threat model it addresses is someone gaining direct access to the storage medium or the files on it without going through the application that normally controls access: a stolen laptop, a decommissioned drive that wasn’t wiped, a cloud storage bucket misconfigured to be world-readable, or an attacker who has compromised a host and is reading files directly off disk.
Full-disk encryption (BitLocker, LUKS, FileVault) protects an entire volume and is most valuable against physical loss or theft — a stolen laptop with full-disk encryption enabled is unreadable without the key, which is why it is a baseline control for any device that leaves a building. Database-level and file-level encryption protect more granularly, which matters because full-disk encryption alone does nothing once the operating system has booted and mounted the volume: at that point the data is available to any process running on the machine. Cloud object storage (S3, Azure Blob, GCS) now defaults to server-side encryption at rest in most providers, which addresses one specific failure mode — an attacker who somehow gains access to the underlying physical storage — but does not address the far more common failure mode of a misconfigured bucket policy making the data readable to anyone with the URL. Encryption at rest is not an access-control substitute; a correctly encrypted but publicly-readable bucket is still a breach, because the legitimate decryption happens transparently for any authorized (or misconfigured-as-authorized) request.
What does encryption in transit protect against?
Encryption in transit protects data while it moves across a network — between a browser and a server, between two internal services, between a database and an application tier. The threat model here is an attacker positioned somewhere on the network path: a hostile Wi-Fi network, a compromised router, an attacker who has gained a foothold inside an internal network and is sniffing traffic between services.
TLS (the successor to SSL, and what “HTTPS” actually is) is the dominant mechanism for encryption in transit on the public internet, and modern deployments should run TLS 1.2 at minimum, with TLS 1.3 preferred where supported — earlier versions have known weaknesses that NIST guidance and most compliance frameworks now treat as deprecated. Internally, the same protection matters more than many teams assume: an organization that terminates TLS at the perimeter and then runs plaintext HTTP between internal microservices is fully exposed to anyone who gains a foothold inside that network segment — and given how often initial access and lateral movement happen together in real intrusions, “internal traffic doesn’t need TLS because it’s inside the firewall” is an increasingly dangerous assumption. VPNs and mutual TLS (mTLS) between services extend the same principle to specific network paths and service-to-service authentication, respectively.
Why isn’t “encrypted at rest and in transit” the whole story?
Because there is a third state: data in use — the period when data has been decrypted so a process can actually operate on it, whether that’s an application rendering a record on screen, a database engine running a query, or a machine learning model processing a feature. Encryption at rest and in transit both explicitly stop protecting data during this window, because the whole point of decrypting is to make the data usable again. An attacker who compromises the running process itself — through a code-execution vulnerability, a malicious insider with legitimate access, or a compromised container reading process memory — can access data in its plaintext, in-use state regardless of how strong the at-rest and in-transit encryption was.
This is the gap that confidential computing and hardware-based trusted execution environments (Intel SGX, AMD SEV, and similar technologies) are built to close, by encrypting memory itself and restricting even privileged system software from reading data while a process operates on it. These technologies remain more specialized and less universally deployed than at-rest and in-transit encryption, appropriate for the most sensitive processing scenarios — multi-tenant cloud environments handling regulated data, for instance — rather than a default expectation for every workload. For most organizations, the practical mitigation for the in-use gap is less about deploying confidential computing everywhere and more about minimizing what’s decrypted, for how long, and to which processes — the same least-privilege logic that governs data loss prevention generally.
Where do teams actually get this wrong?
The most common failure is not omitting encryption — most mature organizations do encrypt data at rest and enable TLS for external traffic. The failure is a false sense of completeness: treating “encrypted at rest, encrypted in transit” as equivalent to “the data is protected,” full stop, when it says nothing about access control, key management, or the in-use gap above.
Key management is where this shows up concretely. Encryption is only as strong as the protection around its keys. Storing an encryption key alongside the data it protects, on the same compromised system, defeats the purpose entirely — a key management service, hardware security module, or cloud KMS with its own separate access controls and audit trail is what makes at-rest encryption meaningful against an attacker who has compromised the application layer rather than the storage layer alone. A second common gap is internal traffic left unencrypted on the assumption that “inside the network” implies trust — an assumption that zero trust architecture explicitly rejects, treating network position as no guarantee of safety at all. A third is encrypting data at rest in a database while allowing over-broad application-level access to that same data — the encryption defends against someone reaching the raw storage, but does nothing against an over-permissioned account or a SQL injection vulnerability that goes through the application’s normal, authorized decryption path.
How should the two controls be prioritized together?
Neither control substitutes for the other, and neither substitutes for access control, patching, and monitoring. In practice: enable strong at-rest encryption on anything holding sensitive data as close to a default as your platform allows, manage keys in a dedicated service separate from the data they protect, enforce TLS 1.2+ everywhere data moves — including internal service-to-service traffic, not just the public-facing edge — and treat the in-use gap as a reason to minimize what gets decrypted and where, rather than something to solve with a single tool. The goal is a data-security posture where “is this encrypted” is answered separately and honestly for each of the three states data actually moves through, not collapsed into one comforting checkbox.
Frequently Asked Questions
Is encryption at rest enough to protect stored data?
No. Encryption at rest protects against someone accessing the storage medium directly — a stolen device, an exposed drive, a compromised host reading files. It does not protect against misconfigured access controls (a public cloud storage bucket), over-permissioned accounts, or application-layer vulnerabilities that go through the normal, authorized decryption path.
Do internal services need TLS if they’re behind a firewall?
Yes, in most modern architectures. An attacker who gains a foothold inside a network segment through phishing, a vulnerable service, or lateral movement can sniff plaintext internal traffic just as easily as external traffic. Treating “inside the firewall” as inherently trusted is the network-position assumption that zero trust architecture is specifically designed to remove.
What is the “data in use” gap?
Data in use refers to the period when data has been decrypted so a running process can operate on it — displaying it, querying it, computing on it. Encryption at rest and in transit both stop protecting data during this window by design. Confidential computing and trusted execution environments address this gap for the most sensitive workloads, but most organizations mitigate it through minimizing what’s decrypted and to which processes, rather than universal deployment of specialized hardware.
Where should encryption keys be stored?
Not alongside the data they protect. A dedicated key management service or hardware security module, with its own separate access controls and audit logging, is what makes at-rest encryption meaningful against an attacker who has compromised the application or storage layer. A key stored next to its encrypted data on the same compromised system provides little real protection.
Does TLS 1.0 or 1.1 still provide adequate protection?
No. Both have known cryptographic weaknesses and are treated as deprecated by current guidance and most compliance frameworks. Production systems should run TLS 1.2 as a minimum baseline, with TLS 1.3 preferred where the platform and clients support it.
