You can also watch the video version of this here: https://youtu.be/s_T9ABuxq6A and https://youtu.be/m18U-OxJqII
Cloud providers have the concept of shared responsibility when it comes to the security of their platform. Shared responsibility means that the cloud provider and the account owner are together responsible for the security of that account and its contents. The specifics of who is responsible for what varies with each individual service and depends on the abstraction of that service. The abstraction of a service refers to the evolution of cloud services:
- Infrastructure-as-a-Service
- Platform-as-a-Service
- Container-as-a-Service
- Function-as-a-Service
- Software-as-a-Service
The further down that list you go, the more abstracted the service offering is and the more responsibilities lie with the provider. For example, with a virtual server, the cloud provider is responsible for the hardware and the network, and you are responsible for picking the operating system, configuring, hardening and maintaining the operating system and all software and code installed in the operating system. You will also need to set up additional servers to ensure redundancy and implement scaling and backup yourself using additional services.
With platform-as-a-service, the responsibility of the operating system goes to the provider along with redundancy, scaling and, in some cases, backup. With function-as-a-service, you are responsible for service configuration and application code. Everything else is the responsibility of the provider. Software-as-a-Service is a little bit different as you are only interacting with the interface of a provided application and not with any infrastructure or code. An example of this is Amazon Quicksight, which is used for data analytics in the cloud.
When designing a cloud-native application, it is important to understand the abstraction level of the services you want to use so that it is clear who is responsible for which part of the security. This will help to make sure you are doing everything you can on your side and can trust the cloud provider to take care of the rest.
Principle of Least Privilege (PoLP)
The Principle of Least Privilege is a common cybersecurity strategy and certainly not unique to Serverless, but it is far more powerful with these types of applications due to the more fine-grained access controls and independent nature of microservices and managed services in the cloud. Privilege, in this case, means permissions - the ability to access something. This principle states that each entity, which could be a user or a service, should only have the minimal permissions it needs to perform its tasks. In a small start-up, the team members might all have full access to the cloud account. This is easy to implement and convenient for them as it does not cause any blockers that could impede productivity and get in the way of innovation. For larger organisations, this approach does not work as more controlled access needs to be implemented. Even for startups, a more constrained approach should sometimes be considered. For example, do you really want an inexperienced developer being able to accidentally launch a 26$ / hour server? (Yes, these do exist - check out the EC2 pricing page).
Through cloud access policies, you can control what team members have access to. Policies can be used to simply block access to more expensive or unnecessary services, or for a more complex custom approach deciding on which exact services and actions within those services are permitted. The Principle of Least Privilege prefers the latter approach, which is considerably more work to implement and frequently needs updating. Without a dedicated security team member, this can be a challenging task and a daunting amount of work. The user management service does provide some useful tricks to reduce permissions a little bit. For example, you can limit access to services based on time of day, weekday or IP address.
Managing microservice permissions according to the Principal of least Privilege is a bit easier. Microservices are a lot more predictable because each one of them is performing a specific task, and so the permissions for that task can be easily determined. For example, if a microservice needs to store a file in the storage service then it would be easy to simply give it full access to that service, and this is still a common approach, but it does not meet the Principle of Least Privilege. The correct permission would be to allow the microservice only to write files to the service. It does not need to read files, so this permission should not be included.
The ability to be much tighter with permissions is a great security advantage that this type of architecture has over a server-based application where the minimum permissions are ‘everything that the entire application needs access to’ as opposed to ‘only the access that this one microservice needs’.
To go deeper on this topic and to read many more related topics about Serverless Architecture please buy the book Serverless - Beyond the buzzword here: serverlessbook.co