Encryption in transit

Lesson 2 of 5 in Encryption and Masking.

Every AWS service endpoint accepts TLS. That is not the same as refusing anything else, and the gap between "supports TLS" and "requires TLS" is where the exam lives. In a data platform the gap is wider than elsewhere, because a pipeline talks to a dozen endpoints and the weakest one sets the real guarantee.

Amazon S3 accepts both HTTP and HTTPS. A bucket is not TLS-only because you intended it to be; the enforcement is a bucket policy statement with Effect: Deny when aws:SecureTransport is false. Two refinements appear in questions. The deny must cover the bucket and its objects — arn:aws:s3:::bucket and arn:aws:s3:::bucket/* — because a policy naming only objects leaves bucket-level calls unprotected. And protocol version is a separate condition key, s3:TlsVersion: aws:SecureTransport is a yes-or-no about encryption and says nothing about TLS 1.2 versus 1.0, so a requirement phrased "must use TLS 1.2 or later" needs the version key.

Amazon Redshift has two halves that are easy to confuse. Server side, require_ssl is a parameter group setting: set it true and the cluster refuses non-TLS connections. Because it lives in a parameter group the change applies on a reboot, which is why "we set it and nothing happened" is a routine report. Client side, the JDBC or ODBC sslmode decides what TLS actually buys — require encrypts without verifying the server certificate, so it does not protect against an impostor endpoint, while verify-ca and verify-full check the chain and, for verify-full, the host name. A requirement about man-in-the-middle protection needs verify-full, not merely require_ssl.

Amazon MSK has two independent settings and one dangerous value. Broker-to-broker encryption is on or off. Client-to-broker is TLS only, plaintext only, or TLS and plaintext — and the third accepts unencrypted connections on a separate port, so a cluster described as "TLS enabled" can be carrying cleartext from the one legacy producer nobody migrated. Note the interaction with authentication: IAM access control and SASL/SCRAM both require TLS, so choosing either forecloses plaintext for those listeners.

The rest, briefly. An AWS Glue JDBC connection has a "Require SSL connection" property that is off unless you set it, and a Glue job's Spark shuffle can be encrypted through its security configuration. Amazon EMR in-transit encryption needs certificates provided in the security configuration — it is not a checkbox. Amazon RDS has rds.force_ssl or the engine equivalent. Kinesis, DynamoDB and the AWS APIs are HTTPS endpoints already.

And the point most often got wrong: a VPC endpoint is not encryption in transit. Interface and gateway endpoints keep traffic off the public internet, which is a genuine and separate benefit — reduced exposure, no NAT cost, and the ability to write an endpoint policy. The traffic is still TLS because the service endpoint is TLS, and an endpoint does nothing to require it. A question offering "create a VPC endpoint" as the way to enforce encryption in transit is offering the wrong control; the two are complements. The deeper treatment is on the security path at requiring encryption on the wire and private paths.

One pipeline, every hop, and whether encryption is actually required

  1. Producer → Kinesis or MSK

    Kinesis is an HTTPS API, so this hop is encrypted by construction. MSK is not: the client-to-broker setting may be TLS, plaintext, or both, and "both" means a plaintext listener is live. Check the setting rather than the intention, and remember IAM or SCRAM authentication forces TLS on those listeners.

  2. Stream → Firehose → Amazon S3

    Service-to-service over AWS-internal paths, encrypted. The decision here is about at rest: Firehose must be told which key to use for the destination, and a delivery stream writing to an unencrypted prefix is a real finding even though the hop itself was fine.

  3. Anything → Amazon S3

    The hop where enforcement is yours. S3 accepts HTTP, so add a bucket policy denying when aws:SecureTransport is false — on the bucket ARN and the object ARN. For a TLS-version floor, use s3:TlsVersion. A VPC endpoint reduces exposure and does not substitute for the deny.

  4. Glue job → JDBC source

    Off unless you turn it on. The connection has a "Require SSL connection" property, and for a self-managed database you also need the server to present a certificate the driver trusts. This is the hop most often left in the clear, because it works either way and nothing complains.

  5. Analyst → Amazon Redshift

    require_ssl in the parameter group refuses plaintext connections, and takes effect on reboot. Then the client’s sslmode decides whether the certificate is verified at all: require encrypts without verification, verify-full checks the chain and the host name. Only the second answers a man-in-the-middle requirement.

  6. Within EMR: node to node

    In-transit encryption for EMR is configured in a security configuration and needs certificates supplied — a PEM bundle in Amazon S3 or a custom certificate provider. It is not a single checkbox, and local disk encryption is a separate setting again, so "the cluster is encrypted" is always an incomplete claim.

  7. Verify by trying to break it

    The only test that means anything: attempt the plaintext connection and confirm it is refused. curl http://bucket.s3.amazonaws.com/key should fail; psql "sslmode=disable" against Redshift should fail. A configuration review proves what was intended, and a refused connection proves what is true.

Key terms: aws:SecureTransport, require_ssl (and sslmode), MSK encryption in transit, s3:TlsVersion, VPC endpoint (PrivateLink)

Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.