mTLS everywhere in Kubernetes: not just in and out
Thu, 04/07/2022 – 16:18
TLS everywhere is a good practice
To prevent security incidents from happening in the first place, Kubernetes Documentation mentions that “TLS must be enabled for each component that supports it to avoid traffic detection, verify the identity of the server, and (for mutual TLS) verify the identity of the client.”
In the meantime, it’s important to understand that TLS must be used to encrypt all communication in the cluster between services, not just ingress. However, this security control is often overlooked on the grounds that the cluster is secure and there is no need to provide encryption in transit within the cluster. (There are also many cases where mTLS is used, but mTLS is configured incorrectly by the application platform team or does not comply with the organization’s security policy. But that’s a topic for another blog.)
OWASP Kubernetes Security Cheat Sheet mentions that “Kubernetes expects all API communication in the cluster to be encrypted by default with TLS.” However, there is a drawback with TLS: TLS guarantees authenticity, but by default this only happens in one direction: the client authenticates the server, but the server does not authenticate the client.
This is where mTLS comes in handy: mTLS makes authenticity symmetric.
What is mutual TLS authentication?
mutual authentication, also known as two-way authentication, is a security process in which entities authenticate each other before actual communication occurs. In a network environment, this requires both the client and the server to provide digital certificates to prove their identities. In a mutual authentication process, a connection can occur only if the client and server exchange, verify, and trust each other’s certificates.
The default of TLS is to authenticate only in one direction because the identity of the client is often irrelevant; this is the case with websites, for example. Of course, not validating the identity of the client makes sense for serving web pages, but there are many types of communication where the identity of the client is important. API calls are one example: if you’re calling a service, then the service needs to know who you are for a variety of reasons, from providing personalized information to billing you. You cannot make an API call without providing some sort of client identity.
Many services use an authentication token to validate the identity of clients. Instead of using this token, mutual authentication via mTLS provides some features that are particularly beneficial for services like Kubernetes.
mTLS authentication is done entirely outside of the application without requiring any application-level features to create, register, or manage identities. With mTLS, a new client can be instantly authenticated. Also, the app doesn’t need to know anything about authentication or provide endpoints to manage it.
These features are what make mTLS so ideal for securing all communications within Kubernetes.
mTLS everywhere is an even better practice
mTLS is a great way to secure all communication between microservices in a Kubernetes environment, for all the reasons listed above.
First of all, it protects all communications. When we deploy our applications as multiple services, sensitive customer data is sent over the network between these services. Without proper encryption, anyone with access to the network can read this sensitive data and forge requests.
Second, it is about auditing and authorization. When calls to services come from authenticated entities, you can audit and record the appropriate metrics. Auditing gives you insight into what and how the customer is doing, and can also detect abnormal activity and prevent violations. This is also important for authorization. Does the authenticated call have the right, with authorization to access the specific data? Authentication and authorization work together to ensure the confidentiality and integrity of your communications.
Third, it takes care of authentication. Since authentication takes place outside of the application, its developers are not required to create flows and procedures to manage identity verification. Instead, they can focus on building and securing business logic and providing a well-functioning application.
Last but not least, it’s all about the user experience. Traditional token authentication can become cumbersome for returning users. Instead, mTLS authentication is performed once, at the platform level, and the user is not required to validate its identity when jumping between services.
TLS certificate management is important
mTLS is ideal for securing communication between microservices. But there is a catch. Machine identity management faces the challenge of creating and distributing all these certificates. This certificate distribution challenge is compounded by the fact that, in environments like Kubernetes, a “service” is, in effect, an ephemeral instance that can be created or destroyed on the fly, each requiring its own certificate set.
This challenge is compounded by certificate rotation in response to certificate compromise. With the lifecycle of certificates shortening each year, you must reissue certificates before they expire. This means that we need to repeat the entire CSR (Certificate Signing Request) and certificate flow, for each ephemeral service, from time to time.
This is where cert-manager comes in handy. certificate manager, developed by the Jetstack team at Venafi, makes certificate authorities and certificates first-class resource types in the Kubernetes API, allowing developers to easily request machine identities for applications, while machines platform and security can maintain control and visibility. Learn more about the success of cert-manager here.