Zero Trust Architectures (ZTA) on AWS with Verified Permissions service

Introduction

This post is written as a brief prescriptive guidance for building Zero Trust Architectures (ZTA) in AWS Cloud. Before we delve deep into how to build ZTA, lets start with a quick overview of what this architecture entails and why moving beyond perimeter based security in cloud is increasingly leading to ZTA.

Trust no one, verify every one; breach is inevitable and has possibly already occurred - is the ZTA security framework's over arching principle. Unlike traditional security models working on assumption of everything within an organization's network is trustworthy (just by virtue of being part of organization), ZTA grants no such concessions. Only the paranoid survives - ZTA treats all users, devices, and applications as potential threats, regardless of their location or origin and acts as tough enforcer to prevent unauthorized access while also leveraging principle of least privilege. Architecting ZTA means user or service requests require continuous authentication, authorization, verifying validation of access requests, privilege escalations etc.

Moving beyond perimeter-based security in the cloud involves shifting from traditional security models that focus on defending the network perimeter to more dynamic, identity-centric approaches. In the cloud, where resources are distributed and accessible from anywhere, relying solely on perimeter defenses is not adequate. Instead, security must be multi layered and deeply embedded at every layer, with a strong emphasis on verifying the identity, context, and behavior of users, devices, and applications regardless of their location. This approach, often embodied in ZTA, ensures that security controls are consistently applied, reducing the risk of breaches and unauthorized access in the inherently fluid cloud environment.

Evolution of ZTA in AWS

In larger context of ZTA, often the term ZTNA (Zero Trust Network Access) is also used because it addresses a specific challenge of securing network access. ZTNA is one of the key components that make up ZTA, but it is not the only one. ZTA can encompass various other aspects, such as Zero Trust Application Access (ZTAA), which focuses on securing access to applications, or Zero Trust Data Access (ZTDA), which centers on protecting data. These classifications allow organizations to target specific areas of their IT environment with Zero Trust principles, ensuring comprehensive security across different layers and components.

AWS environment

In AWS, the transition from traditional VPNs to Zero Trust Network Access (ZTNA) has evolved significantly, beginning with third-party solutions like Zscaler, Netskope, Palo Alto Networks and others that pioneered ZTNA principles and built first rate products to implement ZTNA. These early implementations allowed organizations to enforce secure, identity-based access to applications without relying on traditional perimeter defenses, a major leap of faith. As the need for more integrated solutions grew, hyper scalers such as AWS and GCP introduced new services with application access in mind, which natively incorporates ZTA concepts. Verified Access (ZTNA) and Verified Permissions (ZTAA) services by AWS are part of ZTA framework. Both services are AWS's commitment to enhancing security by moving beyond traditional VPN solutions for networks and simple RBAC/IAM based approach to applications, to a more secure, scalable, and cloud-native approach to access control with ZTA as the underlying principle.

In this post, we will understand a bit more on Verified Permissions service from AWS, a managed service that provides fine-grained access control for applications, enabling developers to define and enforce complex authorization policies at scale - using PBAC (Policy Based Access Control) and a policy authoring language called Cedar. It allows organizations to specify who can access what resources within an application, based on detailed, context-aware policies that align with Zero Trust principles faithfully. By integrating seamlessly with identity providers and other AWS services, Verified Permissions ensures that access decisions are consistently applied across all environments, helping to secure applications against unauthorized access while simplifying policy management and compliance. We will cover the verified access at length in the next sections.

Core components of ZTA in AWS

Core components of Zero Trust in AWS include:

  • AWS Identity and Access Management (IAM): Central to managing identities and access permissions within AWS, IAM enforces the principle of least privilege, controlling who can access AWS resources and what actions they can perform
  • AWS Verified Access: Zero Trust, secure network access service for applications, accessible from AWS VPC services
  • AWS Verified Permissions: Zero Trust, secure application access service
  • Mutual TLS (mTLS): Ensures that both the client and server authenticate mutually before establishing a secure communication channel, providing a strong foundation for Zero Trust by verifying identities at the transport layer.
  • Identity-Aware Proxies: Act as intermediaries that enforce identity-based access controls, ensuring that only authenticated and authorized users can access specific applications or resources, aligning with the Zero Trust principle of continuous verification. In the context of an Identity-Aware Proxy (IAP), the term "proxy" typically refers to a service-based proxy rather than a traditional VM-based proxy. Specifically, this is achieved with a managed service that operates at the application layer, sitting between users and applications. It authenticates users and enforces access policies based on identity and context before allowing traffic to reach the protected resources. While AWS doesn't offer a direct IAP service, it provides the necessary tools and services to build a similar functionality. AWS Verified Permissions can be considered a form of Identity-Aware Proxy (IAP) specifically designed for application-level access control.

It should be noted that the concept and term "Identity-Aware Proxy" (IAP) were originally popularized by Google. Google introduced IAP as part of their BeyondCorp security model, which is their implementation of ZTA. BeyondCorp shifts access control from the network perimeter to individual users and devices, and IAP plays a crucial role in enforcing access policies based on user identity and context. While Google originated and popularized the term, the concept has since been adapted by various organizations and open-source projects, but its origins trace back to Google's BeyondCorp initiative.

In the interest staying on topic, in this post we will focus on AWS Verified Permissions and IAM and will not be focusing on mTLS or AWS Verified Access. Discussing mTLS and its application in AWS via AWS ACM (Amazon Certificate Manager) and or other tools requires a longer discussion and deserves its own blog post. Same goes for AWS verified access, which I will be blogging about in coming weeks. Briefly the following table highlights the key differences between AWS Verified Access and Verified Permissions both however, are key building blocks of ZTA framework in AWS.

AWS Verified Access vs Verified Permissions

AWS Verified Permissions

AWS Verified Permissions is a managed policy-based service that enables fine-grained, centralized access control for applications. AWS Verified Permissions supports Policy-Based Access Control (PBAC). In PBAC, the access control decisions are based on explicit policies defined by the administrators, typically using a policy language like AWS's Cedar. These policies can incorporate various attributes (e.g., roles, resource types, or conditions), but the access decision is ultimately driven by the policies, making it policy-based. This effectively decouples access control from the application, allowing you to manage authorization policies separately from the application code. This service provides a centralized, policy-based system where you can define, update, and manage access control policies outside of the application logic.

AWS Verified Permissions differs from traditional IAM policies, which primarily focuses on managing access to AWS resources with a PARC (Principal, Actions, Resources and Constraints) model to define IAM policies and should not to be confused with PBAC - both are policy based nonetheless. AVP (Amazon Verified Permissions) PBAC can use attributes within the policies, but the primary focus is on managing and evaluating policies rather than directly using user or resource attributes as in pure RBAC, ABAC systems. In ABAC, the attributes (like user roles, locations, environment, or resource tags) directly determine access without needing predefined policies for each access scenario. This distinction is important to understand.

The main components of AWS verified permissions are

  • Policy Store: This is where authorization policies are stored. Policies are expressed in the Cedar policy language, which allows to define permissions based on user attributes, resource attributes, and context. ?
  • Cedar Policy Language: This is the language used to express your authorization policies. It supports both role-based access control (RBAC) and attribute-based access control (ABAC) authorization models. ?
  • Authorization APIs: These verified permissions APIs allow application to evaluate policies and make access decisions. ?
  • Integration with Identity Providers: The service can be integrated with various identity providers, such as Amazon Cognito, to authenticate users and retrieve their identity information.

Setup and Integration

To set up AWS Verified Permissions, you begin by defining authorization policies using AWS Cedar—a policy language used by the service. These policies dictate access to resources based on user roles, actions, and conditions. The next step is to register your application within the Verified Permissions service, which includes specifying the resources and operations it manages.

For an application delivered via Amazon API Gateway, Verified Permissions can be integrated to check permissions before processing API requests. The gateway invokes the AWS Verified Permissions API to evaluate whether the requesting user is allowed to perform the desired action on a specific resource, based on the policies you’ve defined. To understand this a little more clearly

You can integrate AWS Verified Permissions with API Gateway by using a Lambda Authorizer. The process works like this:

  • API Gateway receives a request.
  • It passes the request context (including the user identity from Cognito or another authenticator) to a Lambda Authorizer.
  • The Lambda Authorizer queries AWS Verified Permissions by calling its API to check whether the user has permission to perform the action on the specified resource.
  • Based on the policy evaluation result from Verified Permissions, the Lambda Authorizer returns an “Allow” or “Deny” response to API Gateway.
  • API Gateway either forwards the request to the backend or denies it based on the response.
  • The below sample lambda code shows how this is achieved at the API GW level. In the provided code, the policyStoreId is passed as an environment variable to the Lambda function
  • The code below calls verified permissions - invokes is_authorized API from boto3 SDK minimal. The code below is for illustrative purposes only, for more information on API usage refer to https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/verifiedpermissions/client/is_authorized.html

import json
import os
import boto3

# Initialize the Verified Permissions client
verified_permissions = boto3.client('verifiedpermissions')

def lambda_handler(event, context):
    # Extract relevant information from the event
    method_arn = event['methodArn']
    principal_id = event['requestContext']['identity']['userArn']
    http_method = event['httpMethod']
    resource_path = event['path']

    # Construct the PARC for Verified Permissions
    principal = {
        "entityId": principal_id,
        "entityType": "user"  # Assuming the principal is a user - for illustrative purposes
    }
    action = {
        "actionId": http_method  # Use the HTTP method as the action ID
    }
    resource = {
        "resourceType": "ApiResource",
        "resourceId": resource_path
    }

    try:
        # Call Verified Permissions and determine Action status
        response = verified_permissions.is_authorized(
            policyStoreId=os.environ['POLICY_STORE_ID'],
            principal=principal,
            action=action,
            resource=resource
        )

        # Determine if Action is allowed or denied
        effect = 'Allow' if response['decision'] == 'ALLOW' else 'Deny'

        # Generate the IAM policy and return the authorization response
        return {
            'principalId': principal_id,
            'policyDocument': generate_policy(method_arn, effect)
        }

    except Exception as e:
        print(f"Error during authorization: {str(e)}")
        return {
            'principalId': principal_id,
            'policyDocument': generate_policy(method_arn, 'Deny')
        }

def generate_policy(method_arn, effect):
    return {
        'Version': '2012-10-17',
        'Statement': [
            {
                'Action': 'execute-api:Invoke',
                'Effect': effect,
                'Resource': method_arn
            }
        ]
    }        

In the above code, policy store may have a policy for a user joeblow who is allowed to use GET myapp/orders API. Policy is written in Cedar.

permit(
    principal == User::"joeblow",  // The user is "joeblow"
    action == Action::"GET",       // The action is a GET request
    resource == ApiResource::"myapp/orders"  // The resource is "myapp/orders"
)
when { true };        

Similarly, when using EC2 instances behind a Load Balancer, you can incorporate Verified Permissions to control access to backend services. For instance, each incoming request can trigger a policy evaluation via the Verified Permissions API, ensuring only authorized users gain access to the backend EC2 instances or other application endpoints. ALB does not directly support Lambda Authorizers or invoking AWS Verified Permissions - authorization decisions need to be enforced within the backend service (whether that's EC2, Lambda, or another service). - you can integrate AWS Verified Permissions at the backend to provide fine-grained, policy-based access control after ALB handles authentication (with OIDC or Cognito authentication providers)

By centralizing the policy management in AWS Verified Permissions (using Policy Stores), you can streamline the enforcement of access controls across multiple components of your applications, offering a scalable and consistent authorization mechanism.

By automating the process of policy enforcement for application access via DevOPs pipelines, one can ensure that any changes to the application (such as adding/removing modules or modifying roles or other attributes) are reflected in the access control policies without requiring manual updates. The pipeline can automatically push updates and apply the necessary access control rules to AWS Verified Permissions, ensuring consistent, secure, and up-to-date policies.

Conclusions

In conclusion, adopting Zero Trust Architecture (ZTA) in AWS, especially with AWS Verified Permissions for application access, offers a robust and flexible approach to securing modern applications. By decoupling access control logic from application code and leveraging fine-grained, policy-based authorization with tools like Cedar, you can achieve consistent, scalable application security enforcement.

In the example of using Lambda with API Gateway to invoke the Verified Permissions's Policy Store component, ensures that every request is evaluated for its legitimacy, adhering to the "never trust, always verify" principle of Zero Trust. Furthermore, integrating policy updates into your DevOps pipeline enhances agility by allowing seamless policy management and deployment, ensuring that security controls are always aligned with the dynamic needs of application and its life cycle. As businesses continue to evolve in the cloud, building Zero Trust frameworks with AWS services provides a scalable, automated, and secure foundation for long-term growth.

In the next part of ZTA on AWS we will explore AWS Verified Access in depth.

要查看或添加评论,请登录

Ravi (拉维) C.的更多文章

  • Implementing S3 Conditional Writes

    Implementing S3 Conditional Writes

    Introduction Amazon Simple Storage Service (S3) is a highly scalable object storage service that provides secure…

  • AWS Glue Data Quality?-?From Raw to?Refined

    AWS Glue Data Quality?-?From Raw to?Refined

    Introduction What is Data Quality? Almost every enterprise today is data driven, providing a platform for businesses to…

  • Advanced Threat Modeling Techniques for AWS Architectures

    Advanced Threat Modeling Techniques for AWS Architectures

    Introduction With organizations increasingly adopting cloud environments for the various benefits they offer—such as…

    2 条评论

社区洞察

其他会员也浏览了