Hardening your AWS environment with (not so popular) SCPs part 1
In today's digital landscape, where cloud computing serves as the backbone for countless organizations, ensuring robust security measures is paramount. Amidst the myriad of tools and features offered by Amazon Web Services (AWS), Service Control Policies (SCPs) stand out as a foundational element in establishing and maintaining a secure AWS environment.
SCPs serve as guardrails for your AWS environment, allowing organizations to centrally manage permissions across multiple AWS accounts. They define the actions that principals (users and roles) in an AWS account can or cannot perform. As AWS security professionals we have lots of options for detective controls but sadly the same is not true for preventive controls. SCPs play a pivotal role in enforcing security and compliance policies across an organization's AWS infrastructure.
We all know our bread-and-butter SCPs that everyone applies to their organizational setup In this article I would like to introduce some not so popular and hopefully new to you SCPs.
Stay tuned as we uncover the intricate workings of AWS Service Control Policies and unveil their pivotal role in safeguarding your AWS environment against unauthorized access, data breaches, and compliance lapses or console mishaps.
First, I would like to focus on Secrets Manager – the tool that helps you manage database credentials, application credentials, OAuth tokens, API keys, and other secrets you don’t want necessarily to be viewed by the common public or even some of your staff. Luckily for us Secrets Manager (unlike many other IAM services) has quite a few condition keys that we can use.
The SCP I found useful in high security organizations blocks the possibility to create secrets that are public:
{
"Effect": "Deny",
"Action": "secretsmanager:PutResourcePolicy",
"Resource": "*",
"Condition": {
"Null": {
"secretsmanager:BlockPublicPolicy": "true"
}
}
}
With this policy attached the users won’t be able to configure a secret that does not block public access. Small warning if you want to apply this to an existing organization. The action defined above “PutResourcePolicy” is the sole action responsible for writing the policy down. If there was an existing policy that allowed this, users Infrastructure as Code pipelines will fail until they fix their policy. If you want to apply this SCP to your existing organization, perhaps it is wise to warn your user base if you don’t want too many calls to the service desk.
In high security environments we usually want to control who can access what by encrypting it with our own KMS key. Secrets Manager secrets should be no exception to that rule, however this is sadly not the default setting on AWS. Good thing though is that we can remediate this with the following SCP:
{
"Effect": "Deny",
"Action": "secretsmanager:CreateSecret",
"Resource": "*",
"Condition": {
"StringNotLikeIfExists": {
"secretsmanager:KmsKeyId": "*"
}
}
}
With the above in place the users will not be able to create a secret if it is not KMS encrypted. Simple and elegant.
Staying with the topic of Public Sharing lets focus on Lambda a bit. The functions created by Lambda can be made public and accessed without any authentication instead of through eg. API Gateway. While an organization might require this to operate their software properly we could try hardening it this way:
{
"Action": [
"lambda:CreateFunctionUrlConfig",
"lambda:UpdateFunctionUrlConfig"
],
"Resource": "*",
"Effect": "Deny",
"Condition": {
"StringNotEquals": {
"lambda:FunctionUrlAuthType": "AWS_IAM"
}
}
}
This SCP when applied will make sure that if a public function is used, it at least has to be IAM authenticated thus preventing anonymous action. Preventing direct anonymous API calls is a good compromise if public functions cannot be entirely disabled.
Last one for today is not really about security but perhaps saving yourself from a costly mistake. AWS S3 has a nice feature called object lock. It’s a compliant way that allows you to prove that you have not made any changes to the data after the lock is applied. It also has a maximum retention period of 100 years. In case someone applies this to your 1PB bucket the resulting bill will keep on giving for years.
I don’t know if an escalation path exists inside of AWS that can remove the lock but if you apply the following to your organization, you might save yourself from a costly bill or lots of AWS support calls:
{
"Sid": "SetRetentionPeriod",
"Effect": "Deny",
"Principal": "*",
"Action": [
"s3:PutObjectRetention"
],
"Resource": "*",
"Condition": {
"NumericGreaterThan": {
"s3:object-lock-remaining-retention-days": "10"
}
}
}
Conclusion
Many organizations operating in regulated environments straight up know the maximum retention periods the regulators require them to apply so it makes sense to set the number to that period. Organizations that do not envision themselves needing to lock the object might consider prohibiting the S3 lock at all. After all, who knows how malicious actors will ransom your data in the future.
This article begins a series of not so obvious and popular SCPs. We believe the policies suggested in this article provide security improvements that all organizations should consider implementing. Just as a precaution – any SCPs added to a live and existing environment presents a risk of breaking the application and should be rolled out in a controlled manner. We have rolled out these and more successfully within our and our customers environment as we continue to improve the security posture of our products.
Stay tuned as we uncover the intricate workings of AWS Service Control Policies and unveil their pivotal role in safeguarding your data and operations.