Encryption keys: where to put them and how to work with application secrets in the cloud?
Encryption keys, application passwords or other secrets are the same as house keys. You don't want to lose them, they need to be safe, and they should be replaced from time to time. The days when the database password was directly part of the application code are thankfully gone. The typical trend is to store passwords securely outside the application. So today we'll take a detailed look at how to work with passwords or secrets in general in the cloud and what tools we can use.
What keys or secrets will we encounter?
Working with keys or other secrets can be divided into two basic areas: management encryption keys and the report application secrets. Neither of them should be underestimated.
Encryption keys
Encryption keys are an essential component for data encryption. The generally recommended approach is encrypt data anytime, anywhere, however, in this article we will focus on data encryption in the cloud. First, let's divide it into encryption during transmission (data in transit) a encryption of stored data (data at rest).
Data encryption during transmission
This method of encryption is typically implemented using technologies SSL/TLS or IPsec. The aim of these technologies, or protocols, is to secure the data transmission itself. For simplicity, we can think of these protocols as a secure tunnel between devices. The data inside this tunnel is accessible to the individual end devices, but the outside world (e.g., the ISP's devices) cannot see into this tunnel. A typical representative encryption data in transit is familiar to all of us https protocol.
Encryption of stored data
In this area, which is more interesting for us in terms of cloud usage, two basic approaches are usually applied, namely client-side encryption and server-side encryption.
Client-side encryption
The implementation of client-side encryption is always individual, since (as the name implies) the client (typically the application) is responsible for encryption. The data is therefore encrypted by the application itself before being stored in the cloud.
The implementation of client-side encryption is therefore always up to the developer of the application itself. Generally speaking, it provides higher confidence than server-side encryption (because we have complete control over the encryption), but on the other hand it also brings some potential problems - complicates and prolongs application development and in case of incorrect implementation, vice versa may reduce the level of security.
Server-side encryption
In the case of server-side encryption, encryption occurs within the data store (whether it is a virtual server, database, or other resource). From the application's point of view, nothing changes - the application works with unencrypted data and does not need to be interfered with in any way.
What about the encryption keys?
In all cases, i.e. when using client-side encryption, server-side encryption, but also when encrypting in transit, it is necessary to use encryption keys (i.e. passwords or certificates). The following applies:
- to store somewhere with restricted access.
- manage their life cycle.
- audit their use.
Application secrets
The second area that should not be forgotten is managing and storing application secrets, e.g. various service passwords, connection strings, application certificates, etc.
The goal is to separate application secrets from application code. Thus, in the application code no passwords or other secrets are to be stored. The meaning is clear: segregation of duty between development and password manager. The developer doesn't (and shouldn't) need to know the password to, for example, a database. The developer only needs to know who (or what service) to ask for the password.
The second major advantage of separating passwords from the application to an external service is easy access audit to these secrets and the possibility automatic password rotation.
What does it look like in practice? The application only implements Software Development Kit (SDK) some of the services for storing secrets, for example AWS Secret Manager. The following (simplified) example shows how an application can retrieve the database_password password from AWS Secret Manager:
Tools for encryption keys and application secrets in the cloud
Both key public cloud environments, Amazon Web Services and Microsoft Azure, offer a comprehensive portfolio of services for working with keys and application secrets.
Amazon Web Services
In an AWS environment, we can use two key services. The service for working with encryption keys is AWS Key Management Service (KMS), to work with application secrets then AWS Secret Manager.
AWS Key Management Service
This service offers two basic encryption key distributions:
- AWS managed keys: These are keys that are completely managed by AWS. You as a customer don't have to worry about their lifecycle or manipulate them in any way, you just use the keys to encrypt your data.
- Customer managed keysA: You are in complete control of these keys. You are responsible for their generation and their entire life cycle. Key material to create the key can be KMS itself, you can key material import for example from your own HSM or you can use AWS CloudHSM.
The higher the complexity of the encryption infrastructure, the more difficult it will be to manage and the higher the cost.
On the other hand, I think it is important to mention that even the most basic customer managed key generated directly in KMS (in the figure above it corresponds to Native KMS) meets the conditions for PCI DSS Level 1.
Since security and quality controls in AWS KMS have been validated and certified to meet the requirements of PCI DSS Level 1 certification, you can directly encrypt Primary Account Number (PAN) data with an AWS KMS CMK. The use of a CMK to directly encrypt data removes some of the burden of managing encryption libraries. Additionally, a CMK can't be exported from AWS KMS, which alleviates the concern about the encryption key being stored in an insecure manner. As all KMS requests are logged in CloudTrail, use of the CMK can be audited by reviewing the CloudTrail logs.
How does it look then in terms of encrypting individual resources, whether databases, virtual servers or other services? Once you have generated an encryption key (whether AWS Managed or Customer Managed), you can immediately use it to encrypt individual components - for example EBS volume.
It is certainly worth mentioning the fact that all resources in AWS are not encrypted by defaulty and the user must explicitly enable encryption. In contrast In Microsoft Azure, all resources are encrypted by default.
AWS Secret Manager
As I have already hinted, Secret Manager is used to store application secrets - typically various passwords. Several native AWS services are supported by default, and of course you can store any type of secrets you want.
The great advantage of Secret Manager is the possibility to automatic rotation of individual passwords. However, this functionality requires a custom Lambda function that performs this rotation. This is not an out-of-the box functionality of Secret Manager.
Microsoft Azure
There is only one service in Azure that is designed to handle both encryption keys and application secrets - Azure Key Vault.
Encryption is handled in a similar way to AWS - so you have the option of using either the so-called platform-managed keys (analogous to AWS Managed Keys), i.e. keys completely managed by Azure, or customer-managed keys, or a combination thereof.
The second part Azure Key Vault are the secrets themselves (analogous to Secret Manager), but there is no support for automatic password rotation.
Who I am, is just me, or the foundation of identity
Now that we know how to store each application's secrets, the last step is: how to actually the application gains access to specific secrets? By virtue of your identity!
There is never any "access token" to the AWS Secret Manager or Azure Key Vault (I'm not dealing with keys locked in the vault with another key), but the application (or the component where the application runs) has its identity assigned.
So how to work with the application identity?
Application Identity & Amazon Web Services
AWS environment uses Identity and Access Management (IAM) role. Each component, whether it is a virtual server, a Lambda function, or a Kubernetes Pod, has assigned their role. Within this role, specific IAM policies are then defined, within which individual permissions are specified.
The following example shows IAM policywhich allows you to read two items stored in Secret Manager - MySecret1 a MySecret2:
Then all that is left is to assign a specific IAM role to a specific resource.
So in an AWS environment, it is application identity defined by the IAM role assigned to the application.
Application Identity & Microsoft Azure
Here the situation is similar. The only difference is that identity management is used for Azure Active Directory. Each component (virtual server, App Service, Azure Function) has its own identity - either system or user assigned.
So first we create managed identity for our application:
Once it is managed identity created, we can assign it to our application (or the resource within which the application runs) - in this case, for example, a virtual server:
Then all that's left to do is to set the standard rights (access control) in the required Key Vault:
And that's it. The app has created its managed identity, which is assigned to the resource and access control this identity allows certain actions. So in Azure, the application identity defined by its managed identity.
What to take away from this?
Today we described the basic principles of working with encryption keys in individual cloud environments and showed how to extract passwords from our applications and store them securely in individual external services.
Please remember that data encryption is one of the fundamental security pillars of working with data in the cloud. At the same time, I dare say that application secrets (whether passwords or other sensitive data) definitely do not belong in application code or configuration files and should be stored outside the application itself.
And once again, I remind you in AWS, unlike Azure, data is not encrypted in any way!
If you were in the area needed any help, we will be happy to work with you as part of our services Migrate applications to the cloud We'll go over all aspects of proper data encryption in the cloud.
And if you already have this area sorted out, I'd be happy for any comments on the topic. Do you use services like Azure Key Vault or Secret Manager or have you decided to go down the road of other solutions, such as Vault by Hashicorp? Do you import your own keys from your HSM or do you make do with keys generated by the cloud environment itself?
If you enjoy our articles and find them interesting, be sure to check out the previous parts Cloud Encyclopedia - A quick guide to the cloud.