Dance like Nobody’s Watching; Encrypt like Everyone Is
While AWS is making computing easier, it can be challenging to know how to effectively use encryption. In this screencast, we provide an overview of the encryption landscape on AWS. This includes services like AWS Certificate Manager, AWS Key Management Service, and the Encryption SDK, which provide encryption in transit and at rest. In addition, we share how to enable encryption for services such as Amazon DynamoDB, Amazon EBS, Amazon RDS, and Amazon S3. Finally, we show you how to automate encryption provisioning for some of these services using AWS CloudFormation.
Below, I’ve included a screencast of the talk I gave last week at the AWS NYC Summit in July 2019 along with a transcript (generated by Amazon Transcribe).
This is Paul Duvall – founder and CTO Mphasis Stelligent. I gave this talk at the AWS New York City Summit in 2019 so just sharing this as a screencast as well. At Stelligent, we’ve been helping companies apply DevOps practices on AWS for over a decade now. So what I’ll be sharing here is based on that perspective. When you think about encryption, encryption is about protecting your data from unauthorized access so you’re gonna learn how to apply encryption in a practical way and doing that through automation. But, before we get into this, I want to share a perspective on what we often see when it comes to security and compliance, in general, at most enterprises.
What we often see is that security is something that’s the responsibility of a separate team or might be multiple teams that are further downstream in the software development life cycle. So, if you imagine you have a development team and they’re writing code, writing tests, maybe they’re performing continuous integration. They might be doing this over a period of a few weeks or so and then they’re ready to release, so let’s just say it goes to QA, then it might go to a change advisory board, internal audit, and in some cases, it might go to a separate security team that gets involved, and the problem is that there’s often a significant amount of time between, say, when a developer commits the code and then when there might be any kind of security and compliance checks that are applied – that are comprehensive in nature. And, so even if there are some security control directives that are well documented, it doesn’t mean that they’re always run for every release and doesn’t mean that they’re run the exact same way every single time. And then there’s also the fact that it could be weeks before the developer made that change and the developer’s going to lack context if (the security team) brings it up, and there’s gonna be pressure to release and things like that. The reason this occurs in many organizations is because of the cost as the result of processes that might require human intervention, even if it’s just one thing that they have to do so (these compliance checks) often get batched and they get scheduled across all the different application service teams and that these central security, operations, and audit teams have to support. Another reason, and when you think about from an AWS perspective, because (even though) you can automate all of these things, there might simply be the lack of knowledge that you can (perform) this (automation). So it’s not just sort of the old style data centers, non-cloud types of companies, but even companies that are using AWS might lack the knowledge that they can actually just check a box or automate this through the SDK or through CloudFormation.
And so, as Werner Vogels talks about, the bottom line of all this is that security is everyone’s job, and the beauty of this now is that AWS gives you the tools to bake the security and compliance into every step of the software development process. So, from the standpoint of encryption, you can automate all the encryption as a part of your software development process. You can also automate things like static analysis and runtime checks against your software in order to ensure that you’re always in compliance with your encryption directives. And so, as Werner also says, you can “dance like nobody’s watching, but we encrypt like everyone is”. AWS announced – and this is as of July 2019 – that 117 AWS services now integrate with KMS. As of now, there are about 175-180 total services on the AWS platform and so much more than half of these services provide that provide (this integration with KMS). These might be storage services like S3, EBS, database services like RDS and DynamoDB. The plan is to eventually have all the services have this capability.
In terms of I’ll be covering, I’ll be talking about how do you automate all of this. How do you incorporate this into the software development lifecycle, how to use things like AWS CloudFormation? How do you use the SDK or how’d you get access to the API ultimately in order to make this a part of that software development process. When developers need to apply things like client-side encryption or they need to manage secrets – things like that. We’ll go over that a little bit in terms of client-side encryption. Once that you need to send (data) over the wire, you need to encrypt in transit we’ll be talking about things like AWS Certificate Manager and CloudFront along with ELB. And then how do you encrypt that data at rest, either through database services like RDS, DynamoDB, EBS, S3 and so forth. And then the underlying service that allows you to encrypt all these (resources) is the Key Management Service. So we’ll go over that and also how to give fine-grained permission to keys and fine-grained permission to the service itself. Then when it gets into production and you want to detect whether or not encryption is enabled or not against all your AWS accounts, we’ll cover AWS Config Rules and CloudWatch Event Rules as well. AWS just recently announced that they provide encryption over VPC for certain instances – the Nitro instances – so briefly cover that. Then finally we’ll talk about logging. You can log all of your API calls, but then – from an encryption standpoint – how do you know when those keys are used and then any of the mitigations you might have to go through as a result of that monitoring and logging.
So there’s a heuristic that we use when we look at really anything that we’re building in deploying, testing, and releasing into production. And, there are three steps to this, and the first is to codify: codify all the things. So whether it’s in an AWS service or it’s application code, configuration, infrastructure, or the data: we can codify all that. We can use things like AWS CloudFormation to automate the provisioning configuration of these services: whether it’s database or storage, or it’s the pipeline itself, containers and things like that. How do we codify all of that? And the next thing we consider as a part of this heuristic is then how do you create a pipeline out of this? And not just how do you code it and version it, but how do you put it through a series of stages and actions in which your building, testing, deploying, and getting it out to end users and the users might not just be end users of the services and applications that your customers consume but it also might be internally within AWS and some of the security services or even AWS accounts. You might put (these services) through a deployment pipeline as well. And, the last part of this is then how do you secure it? How do you ensure that security is run as a part of your pipelines? How do you ensure that you have security of the pipeline through hardened-build images and that you’re ensuring that everything goes through the proper checks, how to give fine-grained permission to all the resources in your AWS accounts. So these are the three steps that we consider and, from an encryption standpoint, we’re gonna look at how do you codify that encryption. How do you put the encryption through a pipeline and then how do you secure that?
So let’s take a look at a brief example of doing this from an automation lens, and so AWS CloudFormation is the service that allows you to automate that provisioning. So let’s imagine you have a bootstrap template that you create a stack out of. And so you have sort of the core (and you might be running this from the command line) services that you wanna have set up. Whether that’s KMS – the key management service – AWS Config Rules, and Identity and Access Management and finally, the pipeline itself. And, then in the pipeline itself, you can put stages and actions and services that you might be automating as a part of that. In this example, let’s imagine that we have a directive that we want to have encryption enabled for all of our AWS services and so we’re gonna look at that from a couple of different perspectives. One is every time you build up the software system, you want to make sure that they’re not going to introduce any security vulnerabilities. In the context of encryption, we want to make sure that anything that we build that needs encryption has it turned on, and so we can use a static analysis tool like cfn_nag, which is an open source tool that has 45 built-in rules to it and you can look for encryption on certain AWS resources. And if it doesn’t have the encryption, we can fail the build, give notification and, before we even launch the infrastructure, we can have remediation to that and committed back to the version control repository and then we’re on our way. But then we can also set up detection controls as well with automated detection mechanisms and we can do that through AWS Config Rules. AWS Config notices any state change to a number of different resources in your AWS account, so we could set up a Config Rule that looks for changes to say that your DynamoDB tables or your RDS databases or ensuring your EBS volumes are encrypted. So, we can do that at it from a static perspective as part of the pipeline. But then we can also automate the provisioning of these resources and deploy these rules and, under the hood, these rules are running these checks in something like AWS Lambda. You know, we can write that in a number of different languages: Python, Ruby, and so forth. We can run this based on schedule or based on whatever the event is could be based on schedule, whether there’s a state change and then we perform remediation actions based on that could be to slack developers and say, you wanna automate this and here’s how you automate it where it might be to disable that resource or to automatically say, turn encryption on – if that’s the rule that we’re looking at, that’s a kind of overall view of how you might do this.
So let’s get into the first part of this and that is automation. Automation is providing a number of different ways on AWS. So, AWS CloudFormation provides this common language you can define in JSON or YAML or you could have higher level tools such as the AWS CDK (Cloud development kit) that provides an abstraction layer that generates CloudFormation templates for you, but this way you can define this in code. You can define this in a template, you can version it, you can test the CloudFormation template itself, just as you would any other software asset. You can also use the SDKs, there’s AWS SDKs for all the common languages that are used, whether it’s JavaScript, Java, .NET, Python, Ruby, so forth any of those common languages that you might be using. You get access to all the APIs as a result of that and CloudFormation provides support for most AWS resources and so, from an encryption standpoint, you’ll see some of these examples is there might be a property like a KMS key, or server-side encryption (SSE) that you can turn on which is just a property/boolean you make true and then you’re on your way. You’re able to automate that process. It’s great to have that checkbox in the console, but if you want a repeatable, testable process then AWS CloudFormation is one of the great ways of doing that.
So this is generic – having nothing to do with encryption – has to do with more about CloudFormation just to give you a high-level view if you haven’t seen it before. You have things like parameters and resources, and outputs. These are some of the common constructs that you’ll see in a CloudFormation template. And so you generally will see multiple parameters that you be able to provide to customize the behavior of the stack that you’re going to create from this template. Then you might have multiple (AWS) resources. Typically you’re going to see a CloudFormation template that has hundreds of lines of configuration code, it’s declarative in nature, and so it determines how it applies these changes and you can set dependencies and things like that. It can definitely get a more complex and simple example that you see but the idea is that you were we’re defining all over you can define all your AWS resources in code using this CloudFormation language.
From a development standpoint, especially when it comes to client-side encryption, AWS provides the encryption SDK to support client-side encryption. It provides support for a number of different programming languages like Java, C, Python, and provides CLI support so you can really run it with any language that you happen to be using. The other service you come across as developers is that you often have the need to store secrets somewhere, and that could be the user name and password for the database, it could be API keys and so forth. The AWS Secrets Manager is a fully managed service that allows you to create these secrets, generate random secrets, and provide cross-account access and then integrates with a number of different services. So, for example, it integrates with DynamoDB and RDS, and RedShift automatically, so you can generate username and password randomly, never even see (these secrets) and rotate through that automatically using the Secrets Manager manager service. And we’ll touch on this a little bit later when it comes to the management as well.
And so this is an example of using the (AWS) Encryption SDK. And this is a Python example in which we’re taking some plain text source data. We want to encrypt it and then we convert into ciphertext and then we can decrypt it as well. One thing to note, when people look at encryption, they always kind of think back two decades ago when there was a 20 to 40% hit on their performance. With the use of KMS, there is not that performance hit as KMS actually performs the encryption so you don’t have the hit on the service that you used on the compute side or the database, or whatever you happen to be using so keep that in mind when it comes to encryption, because often people believe that there’s a performance degradation, and that’s not the case.
So we’ve talked about encrypting on the client-side. Then when we send (data) over the wire (i.e. in transit) we want to have the capability to secure the connection between the end user and the endpoint that they’re hitting and AWS provides a number of different services around that. One is the AWS certificate manager or ACM and what this does is allows you to generate public certificates, part of a certificate authority, and it also rotates that certificate for you and so you don’t get into the bind of, say, having a certificate expired and then that means your website’s down. And if you’ve ever been through that before, you know the troubles that ensue as a part of that. And so (ACM) manages a lot for you. It’s freely available, there are 25 certificates that you apply to an Application Load Balancer. Another service (that supports in transit encryption) that’s really useful is CloudFront, which is a CDN so it provides the performance caching and things like that. But what it also does is it gives you access to AWS Shield for volumetric DDOS protection, and so you, and you just get that built in for with CloudFront. In fact, if you take a look at the Well-Architected Framework in the Security Pillar – (AWS goes) over some examples that in the GitHub repositories, some quickstarts and so they have some CloudFormation code so forth in which it uses CloudFront with Certificate Manager and you can get all that set up in less than an hour, so definitely have a look at that.
This is a simple ACM example, in CloudFormation, in which we’re generating a certificate against TLD against our top-level domain, which is example.com. And so you can see it’s pretty simple to set this up. So, we’re assuming maybe you created the domain using Route53, you’ve set up your DNS and you attach that certificate to your Load Balancer, CloudFront, and then you’re often running with this CloudFormation code.
The endpoint could be any number of things, but, in the case of encryption in transit, we have this example where you’re hitting a website. So when we go to this website, we see the lock and we can look at more information as well. But we know that there’s a certificate authority that’s identified that the connection between the end user and this website has been encrypted, so it’s secure in transit.
So, at rest, how do we encrypt at rest? And there’s a number of different services of those 117 services that help you encrypt your data. One is EBS, Amazon Elastic Block Store. In fact, recently, EBS now provides the ability to encrypt your volumes by default. So all the volumes that you create with EBS or you can select them one by one to encrypt it. But again, basically, it’s pretty much a checkbox for all these. You have a KMS key and you associate that KMS key with that particular service, or with that the resource in that particular service. Other ones are RDS and DynamoDB. We’ll take a look at an example of DynamoDB in a moment. Amazon S3 for objects storage – you can encrypt that on the server side as well. And so the underpinnings of all this, as I mentioned, is the Key Management Service, which we’ll get to that in a moment, but that allows you to create, manage these keys and rotate them and things like that. But what we’re doing is we’re creating these keys and then attaching that key id to the resource of those particular services so that were able to encrypt our data at rest.
Here’s an example of encrypting data at rest in CloudFormation for DynamoDB. So we have a DynamoDB table resource in CloudFormation, we have some of the other properties and attributes that were specifying, but the one here is we have the SSESpecification property, we have a boolean and we turn that on and now for this particular table that we’ve defined using CloudFormation, we have encryption turned on at rest using this property. As we discussed, you could have a checkbox but with this allows you do is make that part of the software development process and codify it.
And then you see the results of that in the DynamoDB console.
The underpinnings of everything I’m talking about, from an encryption standpoint, is the key management service or KMS, and you can create and manage these keys and then these keys – what are known as customer master keys. There are (also) some built-in AWS-managed keys for specific services as well – such as S3 and others. But you can also create your own CMKs these customer master keys and these customer master keys then allow you to generate data keys and then with these encrypted data keys, then you can encrypt the plain text for any of the services or any of the data that’s used by some of the services that you need to encrypt and that has KMS support. You can also get fine-grained access through something known as a key policy as well and you’ll see an example of that. The other ability you have is automatic rotation, so you can check a box or you can automate, of course, but you can check a box in KMS to say I want an annual automatic rotation of this particular key or these keys. For fine-grained access to the KMS service itself, we can do that through an Identity and Access Management service – through IAM. The other service is AWS CloudHSM. So this is a cloud-based hardware security module. It provides asymmetric encryption and it’s a single tenant. If you look at KMS, it provides is symmetric encryption. This means that you’re using the same key to encrypt and decrypt with asymmetric encryption using different keys on encryption/decryption used the same math but different keys. Both are FIPS 140-2 compliant. This is the NIST standard that it adheres to but KMS is Level 2 of FIPS 140-2. CloudHSM gives that extra level when it comes to asymmetric and using the single tenant hardware security module, it’s level 3 and KMS is multi-tenant.
We discussed this before but here’s Secrets Manager, which enables you to create secrets across all your services you need a state for, you can use the secrets manager for rotating these secrets, generating random secrets, and giving you cross-account access to these secrets as well.
Here’s an example of defining a KMS key in CloudFormation. I’m able to enable that key rotation. We talked about how you enable the checkbox in the console but in this case, we’re defining it as code. Enabling key rotation means this custom master key that I’m creating here will automatically rotate once a year by doing it this way. I can also set the pending window for deletion. So if I want to delete this key, I can set anywhere from 7 days to 30 days, 30 days being the default between the time when I disable a key and then when that key automatically gets deleted. And this just gives us time because once a key is gone, it’s gone. You can’t use it. If you created a key, you attached it to a resource and that key ultimately gets deleted, you’re never going to get it back. So, it gives you a window to make sure and we’ll talk about how you find the use of your KMS keys using CloudTrail a little bit later. So the rest of this is that key policy I talked about this is giving fine-grained permission on the key itself. Identity and Access Management gives you fine-grained permission on the use of KMS. And then this gives you fine-grained permission on the key here that we’re creating in CloudFormation. So this indicates which IAM user has access, and then the second policy allows the administration of this key. Lastly, the use of that key is defined as well. And you can see how you’re able to define the principal on which actions they’re able to create, there is actually a number of other actions that you’re typically defining your confirmation template.
And then you see that in the Key Management (Service) console. And so if I went over to say the key rotation tab, I would see a checkbox there that would indicate that it’s automatically being rotated.
So, I mentioned how we can statically look for whether or not encryption is going to be enabled, at least from an automation standpoint, through CloudFormation and tools like cfn_nag. But from a runtime perspective, how do you detect these changes, or how do you detect that encryption may have been turned off, and so you have the directive that everything needs to be encrypted, but maybe it didn’t get automated or maybe someone turned it off after it went into production. Well, you can have these detective controls in place using something like AWS Config Rules and Config Rules notices any state changes and, in the case of encryption, let’s imagine that you know, someone turned off or never enabled encryption for DynamoDB, it notices that change and then you can configure it in such a way so that it runs through some kind of remediation workflow: it might slack the developer and let them know how to codify that, it could automatically enable it or it could just disable that resource altogether or at least maybe give some kind of warning that will let them know that they won’t be able to use that resource if it’s not encrypted. There are lots of different ways you can do this, but ultimately these Config Rules are defined in AWS Lambda so you can write your own custom rules but then there’s also there’s 86 managed rules that Config Rules comes with of which six are encryption related. So if you want to extend that to say all the AWS services that KMS supports, you could do that through the custom rules. And then there are some other services that are relevant as well, such as Cloudwatch event rules gives you this near real-time stream events, since it can perform actions based on that. Then Inspector also helps you from a detection standpoint as well.
And so here’s an example of defining a Config Rule. We’re provisioning this Config Rule in AWS CloudFormation. We’re using one of those managed Config Rules for encryption. And this one is saying that we want to make sure that any CloudTrail that gets created needs to have encryption enabled. If it’s not, it’s going to let us know and then we might have a workflow process, as I talked about before, in terms of auto-remediation or notification, it goes to a knowledge base. However, we decide that the best way to inform and be responsive to developers in terms of what that directive the overall control directive is.
And then we see the Config Rules dashboard that lets us know that we’re not compliant with the particular rule that we’ve set up.
On the networking side, AWS announced encryption across the VPC for all its new Nitro instances on and then you can also encrypt between your data center and AWS using the AWS VPN. You can define that code as well.
The last thing I want to talk about is logging. So AWS CloudTrail logs all API calls not just securing, compliance, and encryption, but it’s gonna log all the calls that you make to the AWS API. But when it comes to encryption, what CloudTrail helps us with is the use of, say, the Key Management Service or CloudHSM and it’s going to notify us when particular keys or use. This becomes useful if you wanted to table a key and you want to know which users are using that (key), then how they’re accessing things like that, they can also encrypt the CloudTrail trails themselves. You saw the detection check for that with AWS Config Rules.
And then here’s how we do that in CloudFormation. We’re defining the AWS CloudTrail Trail resource and then we have a KMS ID. You might imagine that maybe elsewhere in this CloudFormation template we’ve automated the provisioning of the KMS Key and we’ve automated the provisioning of the KMS alias (and that’s what we’re referring to here). So the alias points back to that key and then we’re using able to use that key ID and attach that to this trail. We can enable things like log file validation to ensure that nothing got modified. But this is the way that we have to encrypt that trail and then be in compliance with that (encryption) directive and then be in compliance – operationally – with that Config Rule that we’ve set up to run.
And so this is a JSON Payload from CloudTrail. We can see the KMS API action get called, it’s trying to decrypt, at what time it happened, against this key, against this EBS volume, and from this resource. And this is the user that was making that request and so it can help us troubleshoot in a case that we need to disable a key. It’ll give us some time to hunt down the use of that key before we actually go through that action.
Overall, these are the takeaways. Don’t write the crypto yourself – AWS provides AES 256-bit GCM encryption, so you definitely don’t need the write the crypto yourself. If you want to look at the third-party attestations in terms of SOC compliance and FIPS 140-2 standard, PCI, and so forth. You can actually use AWS Artifact for that – if your auditors are looking for that and you have that requirement. (With this), you have that level of trust to know that the third party has looked at this and they understand how the service works and within the AWS data centers and so forth. The other thing we went over is how encryption becomes part of that software development life cycle using CloudFormation, you can use other tools for that, you can build in static analysis checks to ensure that encryption is occurring prior to launching the resources as a part of your software systems, as a part of your infrastructure. You can automate all these things as a part of a deployment pipeline. You can get encryption in transit through the use of CloudFront, through the use of the AWS Certificate Manager – to get that transport layer of encryption with CloudFront, you can integrate that with AWS Shield to get that DDOS protection. Of course, KMS is the underpinning of all this. KMS allows us to create keys and delete them grant access to them, get the fine-grained permission. You can rotate keys. You’re assured it doesn’t go outside the hardware-security module on which it’s running. You can also use Secrets Manager to store secrets for things like usernames and passwords, things that you needed a state for and you need to have encrypted, it will perform the rotation for you and allowing you to generate random secrets. Likewise, with ACM, it performs this certificate rotation as well. We also run detective controls for runtime encryption checks using AWS Config Rules or CloudWatch Event Rules, so that once it’s in use (whether it’s preproduction or production) we can run those checks to ensure that we’re always in compliance. We can use CloudTrail and we encrypt CloudTrail logs, but we can also monitor key usage to ensure that we know how the keys are being used and any actions we might need to take before, say, we delete a key. And then finally, when it comes to internal or external audits that you need to perform – if you’re able to build this all into your end-to-end software development lifecycle, it makes that whole process easier and you’re always in compliance with the directives that you have in place. You’re always in compliance with any of the compliance regimes that are out there both inside the cloud that AWS provides but also inside the cloud because of the services and the way you’re able to use these services as a part of your overall software development lifecycle.
Thanks very much. You can reach me on Twitter and you can reach me at the email address. And if you have any questions, feel free to reach out to us at Stelligent.
Stelligent Amazon Pollycast
|