aws-cdk-verified-permissions
v0.20.1
Published
AWS CDK construct for implementing Attribute-Based Access Control (ABAC) with AWS Verified Permissions and Amazon Cognito
Maintainers
Readme
AWS CDK Verified Permissions Construct
A CDK construct library for AWS Verified Permissions that makes it easy to implement Attribute-Based Access Control (ABAC) in your applications using AWS Verified Permissions integrated with Amazon Cognito. This construct simplifies the implementation of fine-grained permissions based on user attributes, resource properties, and context.
Features
- 🔒 Simplifies AWS Verified Permissions setup and configuration
- 🔑 Seamless integration with Amazon Cognito for identity management
- 📝 Support for Cedar policy language for fine-grained access control
- 🧩 Implementation of Attribute-Based Access Control (ABAC) patterns
- 📊 CloudTrail integration for authorization decision logging
- 📁 Ability to load Cedar policies from external files
- 👥 Automatic creation of default admin and user groups
- 🔄 Post-confirmation Lambda trigger for user group assignment
- ✅ Schema validation for both Cedar schemas and Cognito attributes
Installation
# Using npm
npm install aws-cdk-verified-permissions
# Using yarn
yarn add aws-cdk-verified-permissions
# Using pnpm
pnpm add aws-cdk-verified-permissionsUsage
Here's a basic example of how to use the construct:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as cognito from 'aws-cdk-lib/aws-cognito';
import * as iam from 'aws-cdk-lib/aws-iam';
import { VerifiedPermissions } from 'aws-cdk-verified-permissions';
export class MyStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Create a Cognito User Pool
const userPool = new cognito.UserPool(this, 'UserPool', {
selfSignUpEnabled: true,
userPoolName: 'my-user-pool',
// Add custom attributes if needed
customAttributes: {
'role': new cognito.StringAttribute({ mutable: true }),
'department': new cognito.StringAttribute({ mutable: true })
}
});
// Create a User Pool Client
const userPoolClient = new cognito.UserPoolClient(this, 'UserPoolClient', {
userPool,
generateSecret: false
});
// Create an authenticated role
const authenticatedRole = new iam.Role(this, 'AuthenticatedRole', {
assumedBy: new iam.ServicePrincipal('cognito-identity.amazonaws.com')
});
// Define Cedar JSON schema for authorization model
const cedarSchema = {
entityTypes: {
User: {
shape: {
role: { type: 'String' },
department: { type: 'String' }
}
},
Document: {
shape: {
department: { type: 'String' },
classification: { type: 'String' }
}
}
},
actions: {
read: {
appliesTo: {
resourceTypes: ['Document'],
principalTypes: ['User']
}
},
write: {
appliesTo: {
resourceTypes: ['Document'],
principalTypes: ['User']
}
}
}
};
// Create the VerifiedPermissions construct
const verifiedPermissions = new VerifiedPermissions(this, 'VerifiedPermissions', {
namespace: 'myapp',
cedarJsonSchema: cedarSchema,
identitySource: {
userPool,
userPoolClients: [userPoolClient],
requiredAttributes: {
'role': userPool.userPoolProviderAttribute('custom:role'),
'department': userPool.userPoolProviderAttribute('custom:department')
}
},
authenticatedRole,
createDefaultAdminPolicy: true
});
// Add custom policy to allow users to read documents in their department
verifiedPermissions.addStaticPolicy({
name: 'DepartmentRead',
description: 'Allow users to read documents in their own department',
statement: `
permit(
principal,
action == myapp::Action::"read",
resource
)
when {
principal.department == resource.department
};
`
});
// Alternatively, load policies from a directory
verifiedPermissions.addStaticPoliciesFromPath('./policies');
}
}API Reference
VerifiedPermissions
Main construct that sets up AWS Verified Permissions with Cognito integration.
Constructor
new VerifiedPermissions(scope: Construct, id: string, props: VerifiedPermissionsProps)Properties
namespace: string- The namespace used for resource namingidentitySource: CfnIdentitySource- The identity source configuration
Methods
addStaticPolicy(props: { name: string, description: string, statement: string }): CfnPolicy- Adds a static Cedar policy to the policy storeaddStaticPoliciesFromPath(path: string): void- Loads and adds multiple Cedar policies from JSON files in the specified directory path
Configuration Interfaces
VerifiedPermissionsProps
Properties required to initialize a VerifiedPermissions construct.
interface VerifiedPermissionsProps extends Omit<CfnPolicyStoreProps, "schema"> {
namespace: string;
cedarJsonSchema: CedarJson;
principalEntityType?: string;
validateCedarSchema?: boolean;
identitySource: CognitoIdentityProvider;
createDefaultAdminPolicy?: boolean;
authenticatedRole: Role;
}CognitoIdentityProvider
Configuration for the Cognito identity provider integration.
interface CognitoIdentityProvider {
userPool: UserPool;
userPoolClients: UserPoolClient[];
requiredAttributes: RequiredAttributes;
groupEntity?: string;
createAdminGroup?: boolean;
createUserGroup?: boolean;
}Using Cedar Policy Files
Instead of defining Cedar policies directly in your CDK code, you can store them in separate files and load them using the addStaticPoliciesFromPath method. This approach offers several advantages:
- Better organization of complex policy sets
- Easier policy management and version control
- Separation of policy logic from infrastructure code
- Ability to reuse policies across different stacks
Cedar Policy File Format
Cedar policy files must:
- Have the
.cedarfile extension - Contain a JSON object with the following structure:
{
"name": "PolicyName",
"description": "A description of what this policy controls",
"statement": "permit(principal, action, resource) when { /* Cedar policy conditions */ };"
}Example policy files are available in the examples/policies directory of this repository.
Loading Policies from Files
To load all policies from a directory:
// Load all Cedar policies from the ./policies directory
verifiedPermissions.addStaticPoliciesFromPath('./policies');CloudTrail Integration
The VerifiedPermissions construct optionally creates a CloudTrail trail for logging authorization decisions when enableCloudTrail is set to true. This configuration includes:
- A CloudWatch log group for storing authorization logs
- An S3 bucket for storing CloudTrail events
- File validation for security and integrity
This integration helps with auditing, debugging, and compliance requirements by providing detailed logs of all authorization decisions made through AWS Verified Permissions.
Default User Management
When configured with createAdminGroup and createUserGroup options, the construct will:
- Create default admin and user groups in the Cognito User Pool
- Deploy a Lambda function that automatically adds newly confirmed users to the user group
- Configure permissions for administrators to have full access to resources
This simplifies the initial setup of role-based access control in your application.
Cedar Policy Language
The construct uses Cedar policy language for defining authorization rules. Cedar is a powerful policy language developed specifically for fine-grained permissions:
- Supports complex conditions based on attributes
- Allows for hierarchical resource relationships
- Enables context-aware authorization decisions
Learn more about Cedar policy language in the AWS documentation.
Contributing
Contributions are welcome! Please see our Contributing Guide for information on how to submit pull requests and format commit messages for our semantic-release workflow.
Releases
This project uses semantic-release for automated version management and package publishing. The version is automatically determined by analyzing commit messages that follow the Conventional Commits specification.
License
This library is licensed under the Apache License, Version 2.0. See the LICENSE file.
