Platform engineering is rooted in a fundamental principle: cultivating a culture within development teams. This culture is not merely about saving time or streamlining development processes. Rather, it's about creating superior products through the application of standards and well-defined solutions, providing developers with clear guidelines where they might otherwise struggle to find direction. This becomes especially critical in areas like security and observability, where such a culture can often mean the difference between success and failure.
In this article, we will explore how we at Permit have successfully implemented this culture, specifically in the context of permissions and authorization for our product users. We believe that our approach can serve as a valuable model for creating more effective platform engineering teams.
Permissions That Scale
One of the challenges developers often experience with the amounts of data that our application processes is the complexity of managing a vast web of policies that govern the permissions over this data. Managing the authorization of users and systems has become an increasingly challenging task.
For the last couple of years, the concept of Policy-as-Code has emerged as a powerful solution to this challenge. Domain-specific declarative languages like Rego and Cedar leverage the best practices of software development to manage and enforce policies with precision and agility.
At Permit.io, we've witnessed firsthand the transformative impact of integrating a Policy-as-Code culture within organizations, especially when it comes to navigating the complexities inherent in modern software development and data management.
Just Do It! (as code)
Policy-as-Code is essentially about translating organizational rules and procedures into code. This approach draws on a fundamental insight: complex logic is most effectively managed and understood when expressed as declarative code. By adopting the tried and true practices of software management—such as versioned history, continuous integration and deployment (CI/CD), testing, benchmarks, code reviews, and auditing—we empower ourselves with the tools to handle policies with the same level of scrutiny and flexibility as our software.
On the surface of it, by defining all of our policies as code we can unify all of our compliance and security needs in one fell swoop.
Code is not magic
However, it's crucial to acknowledge that Policy-as-Code is not a panacea. While it significantly streamlines policy management, several challenges remain, particularly concerning its implementation. How do we ensure that Policy-as-Code is applied consistently across an organization? How can we make it accessible to those without a development background? And perhaps most importantly, how do we choose the right Software Development Life Cycle (SDLC) models that align with Policy-as-Code?
Consider the scenario of a shared database or message queue that houses sensitive data. This data, once it leaves its original source, can be transformed by various services or their consumers, often as part of Extract, Transform, Load (ETL) flows. Ensuring that our policies protect this data across different teams and services requires a unified approach that is challenging to scale across diverse teams or developers.
This difficulty stems not from technical limitations but from cultural ones. As different developers contribute to the software, a phenomenon known as 'code drift' occurs, where deviations from the initial policy intentions compromise the policy's effectiveness.
Moreover, as schemas evolve across services, tracking data becomes increasingly complex, exacerbating these challenges.
Cultured code
Addressing these issues requires a cultural shift. Instead of trying to limit our teams' operational freedom, we should focus on empowering them. This starts with understanding that implementing Policy-as-Code is fundamentally a cultural challenge. By embracing a culture that values shared responsibility and collective adherence to policy guidelines, we can create an environment where policies are respected and enforced more naturally.
An effective strategy is to establish a baseline policy that allows individual services to enforce their own access controls while adhering to overarching organizational guidelines. This approach not only meets the unique needs of different teams but also ensures that fundamental security and compliance standards are uniformly maintained. The integrity of these baseline guidelines can be ensured through various mechanisms, such as integrating policy checks into CI tests and conducting thorough code reviews focused on policy compliance.
Additionally, providing teams with modular enforcement tools can facilitate more effective policy implementation. These modules can help gather statistics and identify behavioural patterns from audit logs, offering insights into how policies are being applied in practice. Linking these enforcement points to Data Loss Prevention (DLP) systems can further enhance policy effectiveness by shifting data tracking to a pattern-based approach, which is more adaptable to the dynamic nature of data flows and schema changes.
Meta-Policy CI - the organizational flow to apply cross org policy as code
Conclusion
Embracing Policy-as-Code within an organization requires a comprehensive approach that goes beyond mere technical implementation. It necessitates fostering a culture that values collaboration, empowerment, and shared responsibility for policy compliance. By addressing the cultural aspects of Policy-as-Code, leveraging modular tools for enforcement, and ensuring flexibility to adapt to changing needs, we can pave the way for more secure, compliant, and efficient operations across our teams and services. As developers and tech leaders, it's our responsibility to champion this cultural shift, ensuring that our organizations can navigate the complexities of modern software and data management with confidence and agility.
Written by
Or Weis
Co-Founder / CEO at Permit.io