One of the larger hurdles to climb when becoming FedRamp moderate is encrypting all data in transit using FIPS validated encryption modules. This article describes one approach to satisfying this requirement for anyone running a Kubernetes cluster on AWS.

For those lucky souls who are unfamiliar with FIPS, it stands for Federal Information Processing Standard (FIPS), which is a joint US and Canadian government standard that specifies the security requirements for cryptographic modules that protect sensitive information. FedRamp specifically requires you to satisfy two related controls: SC-8 and SC-13.

According to SSP Appendix A - Moderate FedRamp Security Controls, SC-8 requires us to:

Protect the confidentiality AND integrity of transmitted information.

Which can be satisfied with a combination of control SC-8(1) — cryptography and SC-8(5) — physical security.

Guidance: For each instance of data in transit, confidentiality AND integrity should be through cryptography as specified in SC-8(1), physical means as specified in SC-8(5), or in combination.

Furthermore, and this is the bad news, any use of SC-8(1) must be implemented using cryptography that satisfies SC-13, which states that we must:

Implement the following types of cryptography required for each specified cryptographic use: FIPS-validated or NSA-approved cryptography.

To become FIPS validated, a cryptographic module must be certified by Cryptographic Module Validation Program of the NIST Computer Security Resource Center.

Putting these two controls together, we can state that for FedRamp certification, any use of encryption for protecting data in transit must use a CMVP validated cryptographic module to show that it meets FIPS standard.

Satisfying SC-8

So, back to the point. Imagine you are running a Kubernetes cluster on AWS. How do we go about satisfying SC-8?

We can start by relying on the separation between physical security and cryptography. All major cloud providers provide some form of physical security that satisfies SC-8(5). Furthermore, if your cloud provider can certify that they satisfy those physical controls, they are typically inheritable by any software running within that data centre.

Per the FedRamp guidance document The Rev. 5 Approach to SC-8, and Protecting Data-in-Transit

  • For DIT guaranteed to stay within a single CAA, typically a data center, physical protection via SC-8(5) will be sufficient.
  • More typically, for DIT that traverses from one CAA/data center to another:
    • Physical protection from a sending component can extend from the component to the data center edge
    • Encryption protection via SC-8(1) must be in place between the data centers
    • Physical protection picks up again from the second data center’s edge to the receiving component

In my solution for SC-8, we only need to leverage the physical security of individual EC2 instances to state that any traffic remaining on the host satisfies SC-8(5), and build or compliant cluster out from that basis. Given that an entire AWS data centre satisfies SC-8(5), we can conclude that individual EC2 instances satisfy SC-8(5) as well, and avoid having to encrypt process to process traffic.

An EC2 host is considered physically secure and traffic between processes on the host satisfies SC-8(5).

What about traffic that exits a Node? In this case, my recommendation is to leverage AWS Nitro EC2 instances. All Nitro instances support FIPS validated encryption and have a CMVP certificate. This means that all traffic exiting a Nitro instance is encrypted by a FIPS validated module, under the following conditions:

  • The instances are in the same Region.
  • The instances are in the same VPC or peered VPCs
  • The traffic does not pass through a virtual network device or service, such as a load balancer or a transit gateway.

If you are able to use Nitro for all Kubernetes hosts, service-to-service traffic will automatically be encrypted using a FIPS validated module, covering a large amount of data-in-transit.

Furthermore, AWS data storage services that run within customer VPCs (e.g. RDS, OpenSearch, ElastiCache), can also be provisioned on Nitro-based instances, providing validated encryption for data in transit to these AWS-managed services.

If you are using only Nitro-based instances, traffic is encrypted between all instances in the same Region and VPC.

At this point we have leveraged physical security of individual nodes to guarantee all process to process traffic on a node satisfies SC-8 via control SC-8(5). Furthermore, all node to node traffic satisfies SC-8 via control SC-8(1) by leveraging the CMVP validated cryptographic modules available on AWS Nitro-based instances, even across Amazon data centres, as long as they reside in the same AWS Region and VPC. This alone covers a huge amount of data in transit, but it leaves us with two remaining problems to solve: ingress traffic entering our VPC from the public Internet, and egress traffic originating from our VPC and targeting the public Internet.

In Kubernetes, handling ingress traffic is implementation specific, so I’m going to make some assumptions on that implementation, and since it is a straightforward way to achieve SC-8 compliance, I’m going to go ahead and assume you are using Ingress-Nginx Controller for Kubernetes. A similar outcome can be achieved with alternative ingress controllers, but that is outside the scope of this article.

The nice thing about Nginx is that it uses the OpenSSL library installed on the host system for all cryptographic operations. This means that if you can use a FIPS 140 validated build of OpenSSL operating in FIPS mode on the host OS, NGINX is FIPS compliant when decrypting and encrypting network traffic. Most operating systems provide a FIPS compliant SSL library you can enable by configuring the host to operate in FIPS mode. For example, Amazon Linux has fairly simple instructions to configure the host to operate in FIPS mode.

With the host operating in FIPS mode, Nginx can terminate TLS connections entering the VPC in a FIPS compliant manner, and further communication within the cluster is covered by the Nitro instance types already in place and described earlier.

If your host operating system supplies a FIPS validated version of OpenSSL, nginx will use that to encrypt and decrypt an SSL or TLS traffic.

The last area we need to cover is egress. Nitro instances cannot encrypt data that originates within our VPC and is destined for external destinations. More specifically, in a typical VPC, such traffic will exit our VPC through a NAT gateway and the gateway is responsible for establishing an outbound connection with a different external IP. In these cases, Nitro encryption is not applied. Instead, we need to make sure that this traffic is destined for FIPS validated endpoints and encrypt it using clients that support FIPS compatible ciphers.

For external endpoints managed by AWS, FIPS validated endpoints exist in US and Canadian regions, with a full list of endpoints available online. Thankfully, AWS makes it relatively easy to use these endpoints for code that leverages the AWS SDKs. Specifically, you can set the AWS_USE_FIPS_ENDPOINT environment variable or the use_fips_endpoint configuration setting to tell the SDK to use the FIPS compliant endpoints, which will negotiate the use of FIPS required algorithms or ciphers when establishing a secure connection. The only caveat to this behaviour is that if this setting is enabled and a FIPS endpoint does not exist in the region you are in, the call may fail. This can be problematic if you are deploying the same code base or build container to multiple regions, or if you are using a service that does not have a compatible FIPS endpoint. You can set the endpoint-url option when building your AWS client to override this setting.

What about other, non-AWS services? This is implementation specific, but there are some additional details that can help you. Generally speaking, FIPS validated encryption is only required for data in transit that is considered Controlled Unclassified Information, or CUI. Officially, CUI is information the government creates or possesses, or that an entity creates or possesses for or on behalf of the government. For all intents and purposes, you can substitute customer data for CUI. Remember, only external services that handle CUI require FIPS encryption.

Using this guideline, a first step in making sure all egress traffic is compliant with SC-8 is to first segment that traffic based on the type of data it handles to identify any that may handle CUI. With the list of endpoints that handle CUI in hand, you can work with those external service providers to ensure you are using them in FIPS compliant ways.

Update any external services handling CUI to use FIPS-validated endpoints.


If you are required to implement SC-8 controls to protect all data in transit using FIPS validated encryption, I hope this article helps nudge you towards a solution. I’ve tried to leverage AWS to the greatest extent possible and avoid having to implement security controls using third-party or custom software when a suitable alternative can be leveraged from the cloud service provider. In this case, that meant using Nitro-based instances for all EC2 hosts and RDS and ElastiCache instances, which ensures that data in transit is secured through the CMVP validated Nitro hypervisor. With this in place, ingress and egress traffic can be handled in compliant ways using facilities available on the host and/or provided by external integrations as necessary.

In summary, you can satisfy the SC-8 control via a combination of SC-8(5) and SC-8(1):

  • Process to process on the same host via SC-8 (5):
    • EC2 instances satisfy SC-8 (5) under inheritable controls implemented by Amazon, namely,
      • All EC2 instances reside in an Amazon data centre implementing PE-2(1), PE-2(2), PE-2(3), PE-3(2), PE-3(3), PE-6(2), and PE-6(3)
      • SC-8 (5) has been validated as inheritable by Amazon
      • Nitro instances allow no AWS operator access
  • Host to host traffic within the same data centre via SC-8 (1):
    • All instances use Amazon’s Nitro hypervisor, which encrypts all traffic using CMVP 3739
  • Host to host traffic across data centres via SC-8 (1):
    • Amazon’s Nitro hypervisor encrypts all traffic within the same within the same AWS Region that reside in the same Virtual Private Cloud (VPC)
  • Ingress traffic into a VPC via SC-8 (1):
    • TLS terminate all incoming traffic using FIPS compliant OpenSSL (CMVP 4548)
  • Egress traffic from Workiva’s VPC via SC-8 (1):
    • Use of FIPS validated third-party endpoints, when handling CUI or metadata