Building authorization into software products is becoming an increasingly complex task as both software vendors, and software-centric enterprises shift their efforts toward cloud native computing.
Gone are the monolithic architectures and perimeter-based security strategies of old. In their place: applications consisting of numerous ephemeral microservices interacting in real-time with third-party SaaS applications and services.
Furthermore, the cloud is now the center of gravity for such cloud native applications – but on-premises assets remain an important part of the IT landscape, especially for enterprises. And software vendors and enterprises must both consider assets on the edge as well.
All these characteristics of modern IT impact the challenge of authorization – what permissions do users have on particular applications and services, given those assets are widely distributed and inherently dynamic?
Fortunately, the best practices of cloud native computing itself – beyond simply Kubernetes best practices – bring clarity to such authorization challenges. Here are the basics.
Cloud Native Best Practice #1: Declarative Control Plane
Cloud native computing depends upon comprehensive declarative abstractions that enable organizations to configure and control their IT infrastructure automatically as a matter of policy.
In other words, cloud native computing calls for a control plane that enables organizations to configure and control their entire IT landscape via declarative configurations and automated workflows.
This control plane decouples policy from code – an essential best practice for supporting authorization in cloud native environments.
Without this separation, developers end up mixing code for the authorization layer with the application code itself, leading to problematic technical debt that impedes the organization’s ability to support dynamic microservices and in general, expand the functionality of the applications over time.
Cloud Native Best Practice #2: Statelessness
In the cloud native context, microservices are inherently stateless. Given their fundamentally ephemeral nature, it would slow everything down if individual microservices kept track of the state of anything.
Instead, Kubernetes abstracts the persistence layer so that microservices can access state information as needed, without the fear of losing information should the microservice go away – and most importantly, without slowing down the behavior of the microservice.
Traditional approaches to authorization, in contrast, are inherently stateful. Sessions must keep track of the identities of authorized users and the permissions they have during the session.
Sessions, however, don’t exist as such in a cloud native world. The authorization infrastructure must behave in a fundamentally stateless manner, determining and applying appropriate permissions on the fly for each request.
Cloud Native Best Practice #3: Real-Time Behavior
Second, only to ephemerality, the most important benefit of microservices’ stateless nature is the ability to execute interactions in real-time.
‘Real-time’ doesn’t mean simultaneous. Rather, it refers to event-driven behavior that takes place immediately upon the event in question.
Cloud native authorization layers must therefore be event-driven as well. When applications leverage user invites, role assignments, or access to third-party services or data, such capabilities must take place in real-time.
In fact, every time an event that affects authorization takes place, the cloud native infrastructure in place must ensure the authorization layer learns about it and remains in sync with both the application and relevant third-party data sources.
Real-time behavior thus takes place within the context of a stateless architecture by spinning up copies of an authorization microservice as necessary. These microservices then sync up with real-time, event-driven updates to keep their state up to date.
Cloud Native Best Practice #4: Zero Trust
If we can no longer retain authentication and authorization information as session state, then it follows that every interaction is untrusted. We must go through the authentication and authorization process every time, for every request – an example of what we call zero trust.
The downside to such zero trust interactions is their performance overhead. Essentially, we must log in and authorize every user every time they click on anything. Won’t that slow everything down?
Not if we take a cloud native approach to our authentication and authorization technology itself. We must leverage microservices for such functions, as well as lightweight protocols that are fundamentally cloud native in nature in that they take full advantage of the declarative cloud native control plane.
Cloud Native Best Practice #5: GitOps
GitOps is a set of best practices for deploying and managing code in production, but it is also an important subset of broader cloud native principles for IT generally.
Cloud native best practices #1 – 4 above require that the development team create a separate microservice to manage permissions, where they can update it as necessary in a real-time, event-driven fashion.
They must make sure those updates, therefore, also follow cloud native principles – and that’s where GitOps comes in.
GitOps enables developers to create a pull request for every version change for every microservice, including the ones they use for authorization.
As developers update their products (including their access control layers), they can push a new commit with new code, leveraging standard GitOps tests and checks before automatically applying the changes to the authorization layer at deployment.
Cloud Native Best Practice #6: Hybrid End-to-End
The term ‘cloud native’ would suggest that everything is happening in the cloud – but that’s not necessarily the case. In reality, cloud native means we’re extending the core best practices of the cloud (scale, elasticity, ephemerality, etc.) to all of IT – including on-premises and the edge.
Cloud native authorization, therefore, must work in this hybrid, end-to-end environment, even though each organization will have a different mix of old and new technologies in place. Fortunately, all the practices covered in this article empower organizations to make this requirement a reality.
As long as we have a comprehensive control plane, event-driven zero-trust interactions, as well as mature, standards-based APIs gluing everything together, then it is finally possible to build a cloud native authorization layer that meets organizations’ needs now and into the future.
The Intellyx Take
There is more to the cloud native authorization story than what fits in this article – so it’s a good thing it’s the first in a series.
In the second article in the series, we’ll be discussing the various open-source solutions that can help developers implement a cloud native authorization layer, including the Open Policy Agent (OPA) and the Open Policy Administration Layer (OPAL).
The third article will talk about using a SaaS solution to streamline permissions instead of having developers build their own – including more details about Permit.io’s SaaS-based cloud native permissions layer.
Copyright © Intellyx LLC. Permit.io is an Intellyx customer. Intellyx retains final editorial control of this article.