Skip to content

Commit aff18bc

Browse files
Merge pull request #1 from satyatulasijalandharch/amazon-verified-permissions-rest-api
Amazon verified permissions rest api
2 parents b8b9c3d + d51fda2 commit aff18bc

File tree

27 files changed

+1026
-0
lines changed

27 files changed

+1026
-0
lines changed

python/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ $ cdk destroy
5151

5252
| Example | Description |
5353
|---------|-------------|
54+
| [amazon-verified-permissions-rest-api](https://github.com/aws-samples/aws-cdk-examples/tree/master/python/amazon-verified-permissions-rest-api/) | Creating a REST API Gateway with Amazon Verified Permissions for fine-grained authorization |
5455
| [api-cors-lambda](https://github.com/aws-samples/aws-cdk-examples/tree/master/python/api-cors-lambda/) | Shows creation of Rest API (GW) with an /example GET endpoint, with CORS enabled |
5556
| [application-load-balancer](https://github.com/aws-samples/aws-cdk-examples/tree/master/python/application-load-balancer/) | Using an AutoScalingGroup with an Application Load Balancer |
5657
| [appsync-graphql-dynamodb](https://github.com/aws-samples/aws-cdk-examples/tree/master/python/appsync-graphql-dynamodb/) | Creating a single GraphQL API with an API Key, and four Resolvers doing CRUD operations over a single DynamoDB |
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
*.swp
2+
package-lock.json
3+
__pycache__
4+
.pytest_cache
5+
.venv
6+
*.egg-info
7+
8+
# CDK asset staging directory
9+
.cdk.staging
10+
cdk.out
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
2+
# Amazon Verified Permissions REST API (AWS CDK Python)
3+
4+
This example deploys a REST API secured by Amazon Verified Permissions (AVP) and Amazon Cognito. The stack demonstrates how to combine a Cedar policy store with an API Gateway Request Authorizer so that only members of the appropriate Cognito group can invoke protected routes.
5+
6+
> :information_source: Detailed guides live in the `docs/` directory:
7+
> - [`docs/architecture.md`](docs/architecture.md) – system design and authorization model
8+
> - [`docs/deployment.md`](docs/deployment.md) – environment setup and deployment steps
9+
> - [`docs/operations.md`](docs/operations.md) – testing, troubleshooting, and cleanup
10+
11+
## Solution Highlights
12+
13+
- **End-to-end RBAC** – Cognito users receive access tokens that are evaluated by AVP before API Gateway invokes your Lambda handlers.
14+
- **Cedar-first design** – The Cedar schema and policies are provisioned with the `cdklabs.cdk_verified_permissions` library for repeatable deployments.
15+
- **Composable infrastructure** – Cognito, Verified Permissions, and API Gateway live in dedicated nested stacks to make future customization straightforward.
16+
- **Language mix** – The authorizer runs on Node.js (to use the AWS SDK for AVP), while the demo business logic stays in simple Python Lambda handlers.
17+
18+
| Resource | Description |
19+
|----------|-------------|
20+
| Cognito User Pool & Client | Provides user management and issues JWT access tokens. Adds `admin` and `user` groups. |
21+
| Verified Permissions Policy Store | Hosts the Cedar schema and static policies mapping Cognito groups to REST actions. |
22+
| API Gateway REST API | Exposes `/`, `/user`, and `/admin` endpoints secured by a custom Request Authorizer. |
23+
| Lambda Functions | Node.js authorizer for AVP calls plus Python handlers that simulate protected resources. |
24+
25+
## Quick Start
26+
27+
### 1. Set Up the Environment
28+
29+
```bash
30+
python3 -m venv .venv
31+
source .venv/bin/activate
32+
pip install -r requirements.txt
33+
```
34+
35+
Install or upgrade the AWS CDK Toolkit if needed:
36+
37+
```bash
38+
npm install -g aws-cdk@latest
39+
```
40+
41+
Bootstrap the target account and region the first time you deploy CDK there:
42+
43+
```bash
44+
cdk bootstrap aws://<ACCOUNT_ID>/<REGION>
45+
```
46+
47+
### 2. Deploy the Stack
48+
49+
```bash
50+
cdk deploy
51+
```
52+
53+
Note the `ApiEndpoint` output once the deployment completes.
54+
55+
For additional deployment options, refer to [`docs/deployment.md`](docs/deployment.md).
56+
57+
## Trying the API
58+
59+
1. Create or confirm a Cognito user and add them to the `user` and/or `admin` groups. The implementation guide provides ready-to-run CLI snippets.
60+
2. Authenticate against the user pool (for example, with `aws cognito-idp initiate-auth`) and capture the access token.
61+
3. Call the API with the bearer token:
62+
63+
```bash
64+
curl -i \
65+
-H "Authorization: Bearer $ACCESS_TOKEN" \
66+
"$API_URL/user"
67+
```
68+
69+
- Members of the `user` group receive `Hello from User!`.
70+
- Only `admin` members may call `/admin`.
71+
72+
## Project Layout
73+
74+
```
75+
├── app.py # CDK entry point
76+
├── stack/
77+
│ ├── main.py # Root stack wiring together nested stacks
78+
│ ├── apigw/ # REST API, Lambda integrations, authorizer
79+
│ ├── cognito/ # Cognito user pool, client, and groups
80+
│ ├── verified_permissions/ # Cedar schema and policies
81+
│ └── lambdas/ # Authorizer (Node.js) and demo handlers (Python)
82+
└── docs/implementation-guide.md # In-depth deployment and operations guide
83+
```
84+
85+
## Customizing Verified Permissions
86+
87+
1. Update `stack/verified_permissions/schema.py` with new entity types or actions.
88+
2. Modify or add policy definitions under `stack/verified_permissions/policy/`.
89+
3. Redeploy with `cdk deploy` to publish the schema and policies.
90+
91+
Consider migrating to policy templates if you need per-tenant or per-resource authorization decisions.
92+
93+
## Cleanup
94+
95+
Destroy the stack when you are finished to avoid unexpected charges:
96+
97+
```bash
98+
cdk destroy
99+
```
100+
101+
## Additional Reading
102+
103+
- [`docs/architecture.md`](docs/architecture.md) – architecture diagrams, component breakdown, and Cedar policy model.
104+
- [`docs/deployment.md`](docs/deployment.md) – prerequisites, bootstrapping, and deployment workflows.
105+
- [`docs/operations.md`](docs/operations.md) – post-deployment tasks, troubleshooting tips, and sample CLI commands.
106+
- [Amazon Verified Permissions User Guide](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/)
107+
- [Cedar policy language](https://www.cedarpolicy.com/)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/usr/bin/env python3
2+
import os
3+
import aws_cdk as cdk
4+
from stack.main import Backend
5+
6+
app = cdk.App()
7+
Backend(
8+
app,
9+
"AmazonVerifiedPermissionsRestAPI",
10+
env=cdk.Environment(
11+
account=os.getenv("CDK_DEFAULT_ACCOUNT"),
12+
region=os.getenv("CDK_DEFAULT_REGION"),
13+
),
14+
)
15+
16+
app.synth()
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
{
2+
"app": "python3 app.py",
3+
"watch": {
4+
"include": [
5+
"**"
6+
],
7+
"exclude": [
8+
"README.md",
9+
"cdk*.json",
10+
"requirements*.txt",
11+
"source.bat",
12+
"**/__init__.py",
13+
"**/__pycache__",
14+
"tests"
15+
]
16+
},
17+
"context": {
18+
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
19+
"@aws-cdk/core:checkSecretUsage": true,
20+
"@aws-cdk/core:target-partitions": [
21+
"aws",
22+
"aws-cn"
23+
],
24+
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
25+
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
26+
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
27+
"@aws-cdk/aws-iam:minimizePolicies": true,
28+
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
29+
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
30+
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
31+
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
32+
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
33+
"@aws-cdk/core:enablePartitionLiterals": true,
34+
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
35+
"@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true,
36+
"@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true,
37+
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
38+
"@aws-cdk/aws-route53-patters:useCertificate": true,
39+
"@aws-cdk/customresources:installLatestAwsSdkDefault": false,
40+
"@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true,
41+
"@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true,
42+
"@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true,
43+
"@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true,
44+
"@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true,
45+
"@aws-cdk/aws-redshift:columnId": true,
46+
"@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true,
47+
"@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true,
48+
"@aws-cdk/aws-apigateway:requestValidatorUniqueId": true,
49+
"@aws-cdk/aws-kms:aliasNameRef": true,
50+
"@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true,
51+
"@aws-cdk/core:includePrefixInUniqueNameGeneration": true,
52+
"@aws-cdk/aws-efs:denyAnonymousAccess": true,
53+
"@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true,
54+
"@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true,
55+
"@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true,
56+
"@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true,
57+
"@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true,
58+
"@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true,
59+
"@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true,
60+
"@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true,
61+
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
62+
"@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true,
63+
"@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true,
64+
"@aws-cdk/aws-eks:nodegroupNameAttribute": true,
65+
"@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true,
66+
"@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true,
67+
"@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false,
68+
"@aws-cdk/aws-s3:keepNotificationInImportedBucket": false,
69+
"@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false,
70+
"@aws-cdk/aws-ecs:disableEcsImdsBlocking": true,
71+
"@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true,
72+
"@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true,
73+
"@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true,
74+
"@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true,
75+
"@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true,
76+
"@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true,
77+
"@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true,
78+
"@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true,
79+
"@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true,
80+
"@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true,
81+
"@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true,
82+
"@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true,
83+
"@aws-cdk/core:enableAdditionalMetadataCollection": true,
84+
"@aws-cdk/aws-lambda:createNewPoliciesWithAddToRolePolicy": true,
85+
"@aws-cdk/aws-s3:setUniqueReplicationRoleName": true
86+
}
87+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Architecture Overview
2+
3+
## Solution Summary
4+
5+
This project deploys a reference REST API that protects endpoints with [Amazon Verified Permissions (AVP)](https://aws.amazon.com/verified-permissions/) and Amazon Cognito. It demonstrates how to combine a Cedar policy store with an API Gateway Request Authorizer so that only members of the appropriate Cognito group can invoke protected routes.
6+
7+
## High-Level Diagram
8+
9+
![High-level architecture diagram](diagram.svg)
10+
11+
## Core Components
12+
13+
| Component | Purpose | Source Reference |
14+
|-----------|---------|------------------|
15+
| Amazon Cognito User Pool | Manages users and issues JWT access tokens. Provides `admin` and `user` groups for RBAC. | `stack/cognito/main.py` |
16+
| Amazon Verified Permissions | Stores the Cedar schema and group-based policies. | `stack/verified_permissions/` |
17+
| Amazon API Gateway REST API | Provides `/`, `/user`, and `/admin` resources secured by the custom authorizer. | `stack/apigw/main.py` |
18+
| Request Authorizer Lambda (Node.js) | Exchanges the bearer token and request context for an AVP decision via `isAuthorizedWithToken`. | `stack/lambdas/authorizer/main.js` |
19+
| Demo Business Lambdas (Python) | Return simple payloads to illustrate RBAC outcomes. | `stack/lambdas/{user,admin}/main.py` |
20+
21+
## Request Authorization Flow
22+
23+
1. A client authenticates against the Cognito User Pool to obtain an access token.
24+
2. The client calls the API Gateway endpoint, sending the JWT in the `Authorization` header.
25+
3. API Gateway forwards the request to the custom Request Authorizer Lambda.
26+
4. The authorizer extracts the bearer token, request path, and method, then calls `VerifiedPermissions.isAuthorizedWithToken`.
27+
5. Verified Permissions evaluates the Cedar policies against the supplied action and principal:
28+
- Members of the `admin` group can invoke all routes.
29+
- Members of the `user` group can invoke `/` and `/user` only.
30+
6. API Gateway allows or denies the original request based on the evaluation result.
31+
32+
## Authorization Model
33+
34+
### Namespace and Entities
35+
36+
The Cedar namespace is `amazonverified`. It defines:
37+
38+
- `User`: Represents a Cognito user.
39+
- `UserGroup`: Represents Cognito groups (`admin`, `user`).
40+
- `Application`: Represents the protected API surface.
41+
42+
Actions map one-to-one with the REST routes: `get /`, `get /user`, and `get /admin`.
43+
44+
### Schema Reference
45+
46+
The Cedar schema is defined in `stack/verified_permissions/schema.py` and supplied to the `PolicyStore` during stack synthesis. The schema is serialized to JSON through `cedar_schema = {"cedar_json": json.dumps(cedar_json_schema)}`.
47+
48+
### Policies
49+
50+
Policies are provided via `StaticPolicyDefinitionProperty` constructs:
51+
52+
- `stack/verified_permissions/policy/admin.py` grants the `admin` group access to every action.
53+
- `stack/verified_permissions/policy/user.py` grants the `user` group access to `get /` and `get /user`.
54+
55+
Because policies refer to Cognito groups using the pattern `"<userPoolId>|<groupName>"`, redeploying to a new environment automatically scopes the policy to the correct pool.
56+
57+
### Extending the Model
58+
59+
1. Update `cedar_json_schema` with new actions or entity types.
60+
2. Add or modify policy definitions. You can compose static policies or migrate to policy templates for dynamic authorizations.
61+
3. Re-deploy the stack to publish the new schema and policies.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Deployment Guide
2+
3+
> Verified Permissions is available in specific AWS regions. Choose a supported region (for example, `ap-south-1`) before deploying.
4+
5+
## Prerequisites
6+
7+
- AWS account with permissions to create IAM, Cognito, Lambda, API Gateway, and Verified Permissions resources.
8+
- AWS CLI configured with credentials for the target account and region.
9+
- Node.js v22.20.0 or lts (required for the AWS CDK Toolkit and Lambda bundling).
10+
- Python 3.13 or later.
11+
- AWS CDK Toolkit (`npm install -g aws-cdk@latest`).
12+
13+
## Set Up the Project Environment
14+
15+
```bash
16+
python3 -m venv .venv
17+
source .venv/bin/activate
18+
pip install -r requirements.txt
19+
```
20+
21+
If the virtual environment fails to create automatically, create it manually with the same commands.
22+
23+
## Bootstrap the Environment (First Deployment Only)
24+
25+
```bash
26+
cdk bootstrap aws://<ACCOUNT_ID>/<REGION>
27+
```
28+
29+
Replace `<ACCOUNT_ID>` and `<REGION>` with the target deployment values.
30+
31+
## Deploy the Stack
32+
33+
```bash
34+
cdk deploy
35+
```
36+
37+
The deployment outputs the REST API endpoint (for example, `https://abc123.execute-api.us-east-1.amazonaws.com/prod/`). Record this value for testing.
38+
39+
## Updating the Stack
40+
41+
After modifying infrastructure or policies, redeploy with the same command:
42+
43+
```bash
44+
cdk deploy
45+
```
46+
47+
CDK will perform a change set comparison and apply only the required updates.

python/amazon-verified-permissions-rest-api/docs/diagram.svg

Lines changed: 37 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)