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 it is advisable to replace them from time to time. Fortunately, the days when the password to the database was directly part of the application code are gone. The typical trend is to store passwords securely outside the application. So today we will 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: managing encryption keys and managing application secrets. Neither should be underestimated.
Encryption keys are an essential component for data encryption. The generally recommended approach is to encrypt data always and everywhere, but in this article we will focus on encrypting data in the cloud. First, let’s divide it into encryption in transit(data in transit) and encryption of stored data (data at rest).
Data encryption during transmission
This type of encryption is typically implemented using SSL/TLS or IPsec technologies. 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 available to individual end devices, but the outside world (such as ISP devices) cannot see into the tunnel. A typical representative of encryption data in transit is the well-known https protocol.
Encryption of stored data
In this area, which is of more interest to us in terms of cloud use, there are usually two basic approaches, namely client-side encryption and server-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 it is stored in the cloud.
The implementation of client-side encryption is therefore always up to the developer of the application itself. In general, it provides higher confidence than server-side encryption (because we have complete control over the encryption), but on the other hand, it brings some potential problems – it complicates and prolongs the development of the application and, if implemented incorrectly, can reduce the level of security.
In the case of server-side encryption, encryption occurs within the data store (whether it is, for example, a virtual server, database, or other resource). From the application point of view, nothing changes – the application works with unencrypted data and it is not necessary to interfere with it 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, encryption keys (i.e. passwords or certificates) must be used. It is true for them that we must:
- stored somewhere with restricted access.
- manage their life cycle.
- audit their use.
The second area that should not be forgotten is the management and storage of application secrets, e.g. various service passwords, connection strings, application certificates and so on.
The goal is to separate application secrets from application code. Therefore, no passwords or other secrets should be stored in the application code. The meaning is clear: segregation of duty between development and password manager. The developer does not (and should not) need to know the password to, for example, the 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 the ease of auditing access to these secrets and the ability to automatically rotate passwords.
What does it look like in practice? The application merely implements the Software Development Kit (SDK) of one of the secret storage services, such as 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
AWS Key Management Service
This service offers two basic encryption key distributions:
- AWS managed keys: these are keys that are completely managed by AWS. As a customer, you don’t have to worry about their life cycle or manipulate them in any way, you just use the keys to encrypt your data.
- Customer managed keys: these keys are completely managed by you. You are responsible for their generation and their entire life cycle. The key material for key creation can be the KMS itself, you can importkey material from your own HSM for example, or you can use AWS CloudHSM.
The higher the complexity of the encryption infrastructure, the more difficult it will naturally be to manage and the higher the cost.
On the other hand, I think it’s important to mention that even the most basic customer managed key generated directly in KMS (corresponding to Native KMS in the figure above) meets the requirements forPCI 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 then look 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 noting that all resources in AWS are not encrypted by default 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 it is possible to store any other type of secrets.
A great advantage of Secret Manager is the ability to automatically rotate individual passwords. However, for this functionality, a custom Lambda function is required to perform this rotation. This is not an out-of-the box functionality of Secret Manager.
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 – you have the option to use either so-called platform-managed keys (similar to AWS Managed Keys), i.e. keys completely managed by Azure, or customer-managed keys, or a combination of both.
The second part of Azure Key Vault is the secrets themselves (similar to Secret Manager), but there is no support for automatic password rotation.
Who I am is just me, or identity is the foundation
Now that we know how to store individual application secrets, the last step remains: how does an application actually gain access to specific secrets? Based on your identity, after all!
The application is never given an “access token” to AWS Secret Manager or Azure Key Vault (I’m not talking about keys locked in the vault with another key), but the application (or the component where the application runs) is assigned its own identity.
So how to work with the application identity?
Application Identity & Amazon Web Services
Identity and Access Management (IAM) roles are used in the AWS environment. Each component, whether it is a virtual server, a Lambda function or a Kubernetes Pod, is assigned a role. Within this role, specific IAM policies are then defined within which individual permissions are specified.
The following example shows an IAM policy that allows you to read two entries stored in Secret Manager, MySecret1 andMySecret2:
Then all that remains is to assign a specific IAM role to a specific resource.
Thus, in an AWS environment, application identity is defined by the IAM role assigned to the application.
Application Identity & Microsoft Azure
Here the situation is similar. The only difference is that Azure Active Directory is used for identity management. Each component (virtual server, App Service, Azure Function) has its own identity – either system oruser assigned.
So first we create a managed identityfor our application:
Once the managed identity is 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 is left to do is to set the standard rights (access control) in the desired Key Vault:
And that’s it. The application has created its managed identity, it is assigned to the resource and the access controlallows certain actions to this identity. Thus, in Azure,the identity of an application is 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 don’t forget 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 as a reminder, data is not encrypted in AWS (unlike Azure)!
If you need any help in this area, we would be happy to go over all aspects of proper data encryption in the cloud with you as part of our Cloud Application Migration services.
And if you already have this area sorted out, I’d be happy for any comments on the topic. Are you using services such asAzure Key Vaultor Secret Manageror have you decided to go the route 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 installments of the Cloud Encyclopedia – a quick guide to the cloud.
This is a machine translation. Please excuse any possible errors.