Skip to content

Commit

Permalink
Merge pull request #363 from permitio/daniel/SDLC-V2
Browse files Browse the repository at this point in the history
V2 of the new SDLC docs
  • Loading branch information
filipermit authored Jun 5, 2024
2 parents b7af0f9 + c4e697a commit b5706d3
Show file tree
Hide file tree
Showing 10 changed files with 326 additions and 281 deletions.
99 changes: 99 additions & 0 deletions docs/how-to/SDLC/CI-CD.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
sidebar_position: 1
title: Manage Policy Life Cycle - CI/CD
sidebar_label: CI/CD
---

Continuous integration and deployment ensure that your authorization system can adapt quickly to software changes and user requirements.
This practice helps automate the update and deployment processes, which minimizes the risk of errors and maximizes operational efficiency.

Enhancing policy management with Continuous Integration and Continuous Deployment (CI/CD) processes allows us
to maintain a consistent and secure authorization layer. Managing and merging policies into various environments while ensuring
consistency and compliance, syncing them to Git and deployments, and utilizing the power of policy as code allows us to
handle authorization swiftly and effectively.

### CI/CD in Permit

Automating updates and deployments through CI/CD ensures that changes are applied consistently and without human error across all environments.
This automation speeds up the deployment process and enhances security by reducing the risk of misconfigurations.
We primarily manage the policy life cycle as part of a CI process by
using [projects and environments](/manage-your-account/projects-and-env)
together with the [Environment API.](https://api.permit.io/v2/redoc#tag/Environments)
By working with Permit environments for CI, CD is automatically achieved using [OPAL](https://github.com/permitio/opal),
as every environment is automatically deployed to PDPs mapped to them
(via their [API secret key](/manage-your-account/projects-and-env#fetching-and-rotating-the-api-key)).

### Version Control and Consistency with GitOps

Maintaining version control and ensuring consistency across environments is essential when managing complex systems.
Using a Git-like model for environments, where each environment corresponds to a branch, helps teams manage development,
staging, and production configurations separately yet consistently. This approach allows for editing, reviewing,
and merging policies as code within a Git repository, ensuring transparency and collaboration.

We achieve this by allowing you to automatically map branches when you [connect your Permit Project to a repository](/integrations/gitops/github),
facilitating efficient lifecycle management and leveraging Git's robust version control system.

:::info
Note that usually you maintain **two lines of branches** -

- your application branches
- your policy branches (Permit Environments).

These are connected together by the PDP and PEPs (e.g. SDKs, gateways) deployed into your application,
which **use the environment API-secret-keys to sync to a specific env**.

```mermaid
flowchart TD
App -->|code changes| NewApp[New App Version]
Policy --> |policy changes| NewPolicy[New Policy Env.]
NewPolicy --> |Prod. Env API-Key| PDP
NewApp --> |Build / CD| Build[App Build]
PDP --> Deployment
Build --> Deployment
```

:::

:::note
You can migrate an application to a new policy by simply pointing its PDP to a new environment.

```mermaid
flowchart LR
ENV --> |Create & Copy Env.| NewEnv
PDP --x ENV[Old Env.]
PDP -- Sync via API Secret --> NewEnv[New Env.]
App -- query --> PDP
```

:::

### CI Flows

Every CI flow should start with the source environment, which would be copied to a staging or preview environment,
tested, reviewed, approved, then merged into the target environment (e.g. production).

```mermaid
gitGraph LR:
commit id:"starting point"
branch "staging env."
branch "target env."
checkout "staging env."
commit id:"checkout" tag:"copy env"
commit id:"policy changes"
commit id:"tests" type: HIGHLIGHT
commit id:"approved"
checkout "target env."
merge "staging env." tag:"copy env"
commit id:"ongoing changes"
```

There are two types of CI flows to consider:

- **Staging flow** - where you have one environment in which you apply policy changes/test before merging into the target environment (e.g. Production).
This is simply achieved by using the `copy-env` API.
- **Preview Branches flow [Recommended]** - where you dynamically create an environment for each policy "pull-request".
This is achieved by using both the `create-env` API (to create the Permit Preview Environment) and the `copy-env`
API (Once to copy from the source environment to the newly created preview environment and once after testing to merge into the target environment (e.g., Production)).

When using these staging or preview environments, you can use each environment's access control to gate who can affect the policy at each stage.
For example, you can give only the developer who triggered the creation of the CI flow access to the preview environment.
10 changes: 10 additions & 0 deletions docs/how-to/SDLC/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"label": "Policy Lifecycle",
"position": 1,
"collapsible": true,
"collapsed": true,
"link": {
"type": "generated-index",
"description": "Permit and the Software Development Lifecycle (SDLC): How to build authorization with CI/CD thorough testing, and precise modeling and implementation."
}
}
45 changes: 45 additions & 0 deletions docs/how-to/SDLC/authz-testing.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
sidebar_position: 2
title: Authorization Testing
sidebar_label: Authorization Testing
---

Authorization policies must be thoroughly tested in a controlled setting before being deployed to production.
Effective testing strategies confirm that the system behaves as expected under various conditions and help catch
potential issues before they affect the production environment.

Here's how testing should be structured:

### **Unit Testing**

Unit tests are essential for verifying the individual components of your authorization policies.
These tests should be designed to run independently from the rest of the system,
allowing for quick checks on the logic and functionality of each policy.

At Permit, unit tests can be executed using policy as code,
where the policy code is loaded directly onto the policy engine
([such as via the OPA test command line](https://www.openpolicyagent.org/docs/latest/policy-testing/)),
ensuring that each component functions correctly in isolation.

### **Application and Integration Testing**

Application and integration tests evaluate how well different parts of your application
work together under real-world scenarios. This involves deploying a
[PDP](/overview/how-does-it-work#the-policy-decision-point-pdp) that is synced to the development environment
and running tests that simulate actual application queries against the PDP. This method ensures that policies are not only theoretically correct,
but are also effectively enforced within the application context.

In Permit, we incorporate these tests into our development cycles, allowing for thorough validation of policy implementations in a
controlled yet realistic setting.

### **Automation of Testing Processes**

Automation plays a vital role in maintaining efficiency and consistency in testing.
Automated tests can be configured to run as part of the CI/CD pipeline, ensuring that every change is vetted before it goes live.
We suggest you consider the following triggers and hooks, which you can mix and match according to your needs:

- The CI system deploys PDPs specifically for testing policy changes.
- Developers can trigger tests automatically through the CI system.
- Tests must pass before environments are merged; if tests fail, the CI system will not proceed with merging changes.
- The CI system uses APIs like Create/Copy-env to establish environments purely for testing purposes, guaranteeing
that each test environment mirrors the target deployment scenario accurately.
162 changes: 162 additions & 0 deletions docs/how-to/SDLC/modeling-implementation-components.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
sidebar_position: 3
title: Modeling and Implementation Components
sidebar_label: Modeling and Implementation Components
---

Precise modeling involves outlining and structuring how authorization processes interact within your application. Below is an explanation of how
[Permit](http://permit.io/) components should be incorporated into your SDLC. This step is critical because it helps create a clear
framework that defines how policies are applied and managed across different application components.

Modeling and implementing a cloud-native authorization system requires a structured approach.
We suggest separating our implementation into a list of several planes, each focused on a different iteration of the SDLC and architecture levels.

These planes—**Applica**tion, **Configuration**, **Data**, and **Enforcement**—serve different functions,
from handling user interactions to managing data security and enforcing policies.

![Permit Components Diagram](/img/diagrams/permit_planes.png)

### The Application Plane

The Application Plane serves as the foundational layer of the authorization layer, designed to align closely with common product architectures,
integrating authorization directly into the software development life cycle (SDLC). Here’s how the key components of this plane are modeled in Permit:

- **Workspaces/Organizations**: These act as the main namespace or administrative domain within the authorization system,
analogous to a development organization in the SDLC.
Generally, each account should have one workspace to maintain a clear organizational structure.
- **Projects**: Projects within a workspace mirror products and can be thought of as equivalent to code repositories.
Each project holds its unique configuration and policies driven by specific product requirements.
- **Environments**: Similar to branches in a code repository, environments within a project manage the deployment and
testing of policies in different stages, such as development or production.
- **Members**: These are the users involved in managing and operating the authorization system,
including developers, security engineers, and product managers, who handle permissions and policy configurations.

:::info
Behind the scenes, Permit creates a Policy as Code repository for each project, and environments are branches in this repository. You can control these repositories yourself using the [GitOps feature](/integrations/gitops/overview).
:::

**Flow and User Interaction**

In the SDLC timeline, the Application Plane is relatively static but critical as it establishes the policy management and deployment structure.
Interaction with the Application Plane is facilitated through various methods:

- **User Interfaces (UIs)**: UIs allow non-technical stakeholders, such as product managers,
to easily manage and navigate the structure of projects and environments.
While costly to create, this type of accessibility is vital for fostering an inclusive environment where
project configurations can be adjusted without deep technical knowledge.
- **GitOps Workflows**: GitOps provides a declarative way to manage infrastructure and configurations using Git.
It allows for transparent version-controlled environments that align with DevOps practices,
making it easier for teams to track changes and roll back if necessary.
- **APIs**: APIs offer developers the flexibility to manage projects and environments programmatically,
integrate with existing CI/CD pipelines,
and automate repetitive tasks. This is particularly useful for dynamically creating environments
that align with feature branches or specific testing needs.

While developing these capabilities in-house can be resource-intensive and complex, our approach at Permit was to
provide these capabilities out of the box, ensuring that developers can choose the most suitable method for their
needs without the overhead of building and maintaining these systems.

### The Configuration Plane

The Configuration Plane is central to defining and managing the rules and policies that govern access within an application.
his plane is essentially about translating the complex requirements of permissions and roles into a structured,
stateless configuration that integrates seamlessly with the application's codebase.
Let’s go over this plane’s components:

- **Resources:** These are the various types of application assets requiring permission management.
Each resource type specifies possible actions that users might undertake. - **Resource Relationships:** Descriptions of potential connections between resources to
facilitate permission derivation.
- **Roles:** User roles within the application, both at the system and resource levels.
- **Role Derivations:** Mechanisms to extend permissions from one role to
another by using relationships.
- **Attributes:** These are specifications that define the characteristics of resources and users,
which can be used to set conditions for access permissions.
- **Condition sets** - the ability to build conditions to match users or resources in a set.
These conditions use the attribute configuration to configure `match` conditions.
- **Policy:** These are the actual rules that determine whether access is allowed or denied
based on roles, resources, and condition sets.
- **Custom Policies:** Advanced policy declarations using specific policy languages (like Rego or Cedar).
Used mostly in very advanced use cases.
- **Data Fetchers:** These synchronize data from the application to the authorization system,
crucial for maintaining current and applicable permission settings.
- **URL Mapping:** This feature links API endpoints directly to resource definitions,
streamlining the integration of authorization layers with application APIs.

**Flow and User Interaction**

Managing the Configuration Plane can be approached through multiple methods,
each offering distinct advantages and catering to different organizational needs:

- **UI**: This method is ideal for non-developer stakeholders, such as product managers,
who need to configure permissions easily and visually. It enhances accessibility and reduces complexity
for users without deep technical knowledge.
- **Infrastructure as Code**: Organizations committed to a code-centric SDLC can manage permissions via tools like the Permit Terraform provider,
integrating permission management directly into their development processes.
- **Raw Policy as Code**: For scenarios where customization needs exceed what is feasible through the UI,
policies can be directly authored and managed in policy code files within version control systems.

As with the application plane, at [Permit.io](http://permit.io/), we tried to enable developers to adopt the method that best fits their workflow.
We support a hybrid approach, recommending the use of the UI for standard role-based and attribute-based access control
configurations while accommodating more complex or stringent rules through custom policy code.

### The Data Plane

As the configuration plane defines the application's authorization layer from the product requirement perspective,
the data plane handles the dynamic elements of application data that influence policy decisions.
It bridges the static configurations set in the Configuration Plane and the real-time enforcement of those policies in the Enforcement Plane.
Let’s go over its components:

- **Users**: The core element of the Data Plane, representing individuals who interact with the application.
User data is often synchronized from identity providers that manage authentication.
- **Attributes**: Attributes associated with users can be pivotal in determining the outcome of policy decisions and
influencing access control based on dynamic user data.
- **Tenants**: Representing groups of users, tenants facilitate segmented policy enforcement, similar to organizational
units in traditional IAM systems or accounts in cloud-native architectures.
- **Role Assignments**: These define the relationships between users and their roles within the application and can extend
to relationships between users and specific resource instances.
- **Resource Instances**: These are specific instances of resources defined in the Configuration Plane,
typically identified by unique identifiers.
- **Relationship Tuples**: These tuples create a graph of relationships between individual instances,
aiding in the derivation of permissions between users and resources.

**Flow and User Interaction**

The management and synchronization of data within the Data Plane are continuous processes tightly integrated
with the application's lifecycle. Data can be handled in various ways:

- **API/SDK**: The most straightforward method for syncing data is through the integration of SDKs or direct API calls
from within the application code. This approach ensures that data remains consistent with the application's state and development cycle.
- **UI**: Data can also be managed via a user interface, which is especially useful for non-developer
stakeholders who need to interact with the data for configuration or testing purposes.
However, direct manipulations in the UI should be used judiciously in production environments to maintain data integrity.
- **Policy Engine APIs**: For advanced data synchronization scenarios, data fetchers or direct policy engine API calls can be used.
These are particularly useful in large-scale environments where data needs to be consistently and automatically updated.

Permit supports API/SDK integrations and provides UI capabilities that allow for easy data manipulation and testing.
For environments where data synchronization needs to be automated and consistent, we utilize its OPAL to link data directly with the policy engines,
maintaining a single source of truth and enhancing the reliability of policy enforcement.

### The Enforcement Plane

The Enforcement Plane is where all the preparatory work done in the other planes comes into action.
It is the most dynamic aspect of a cloud-native authorization system, responsible for the real-time application of configured policies.
This plane ensures that the authorization decisions, such as allowing or denying user actions,
are enforced consistently and accurately across the application. Let’s go over how its components are modeled in Permit:

- **Check Function (`permit.check()`):** This is the core component of the Enforcement Plane in Permit.
It evaluates whether a particular action by a user on a resource should be allowed or denied based on the policies.
The function considers several elements to make this decision:
- **User**: Includes the user ID and, optionally, user attributes.
- **Action**: Specifies the operation the user is attempting.
- **Resource**: Identifies the type or ID of the resource involved and, optionally, resource attributes.
- **Context**: Any additional data that might be relevant for evaluating the policy decision.
- **Data Filtering**: This function assists in filtering data according to the policy evaluation.
It is particularly useful in applications where data visibility depends on user permissions, although it typically requires custom policy code to implement.
- **Local PDP APIs**: These APIs fetch necessary data from the local policy decision point to aid the application in making informed authorization decisions.

**Flow and Integration**
The enforcement logic is embedded within the application code in the software development life cycle.
It acts as the gatekeeper, controlling what users can or cannot do within the application based on the policies defined in earlier planes.

At Permit.io, enforcement is integrated using SDKs or by direct calls to the policy decision point.
This integration allows developers to directly incorporate permission checks and data filtering mechanisms into the application flow.
Loading

0 comments on commit b5706d3

Please sign in to comment.