Skip to content

Commit d51fda2

Browse files
docs: add documentation with an architecture diagram
1 parent a76912a commit d51fda2

File tree

5 files changed

+318
-34
lines changed

5 files changed

+318
-34
lines changed
Lines changed: 83 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,107 @@
11

2-
# Welcome to your CDK Python project!
2+
# Amazon Verified Permissions REST API (AWS CDK Python)
33

4-
This is a blank project for CDK development with Python.
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.
55

6-
The `cdk.json` file tells the CDK Toolkit how to execute your app.
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
710
8-
This project is set up like a standard Python project. The initialization
9-
process also creates a virtualenv within this project, stored under the `.venv`
10-
directory. To create the virtualenv it assumes that there is a `python3`
11-
(or `python` for Windows) executable in your path with access to the `venv`
12-
package. If for any reason the automatic creation of the virtualenv fails,
13-
you can create the virtualenv manually.
11+
## Solution Highlights
1412

15-
To manually create a virtualenv on MacOS and Linux:
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.
1617

17-
```
18-
$ python3 -m venv .venv
19-
```
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. |
2024

21-
After the init process completes and the virtualenv is created, you can use the following
22-
step to activate your virtualenv.
25+
## Quick Start
2326

24-
```
25-
$ source .venv/bin/activate
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
2633
```
2734

28-
If you are a Windows platform, you would activate the virtualenv like this:
35+
Install or upgrade the AWS CDK Toolkit if needed:
2936

30-
```
31-
% .venv\Scripts\activate.bat
37+
```bash
38+
npm install -g aws-cdk@latest
3239
```
3340

34-
Once the virtualenv is activated, you can install the required dependencies.
41+
Bootstrap the target account and region the first time you deploy CDK there:
3542

43+
```bash
44+
cdk bootstrap aws://<ACCOUNT_ID>/<REGION>
3645
```
37-
$ pip install -r requirements.txt
46+
47+
### 2. Deploy the Stack
48+
49+
```bash
50+
cdk deploy
3851
```
3952

40-
At this point you can now synthesize the CloudFormation template for this code.
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
4173

4274
```
43-
$ cdk synth
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
4483
```
4584

46-
To add additional dependencies, for example other CDK libraries, just add
47-
them to your `setup.py` file and rerun the `pip install -r requirements.txt`
48-
command.
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.
4990

50-
## Useful commands
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+
```
51100

52-
* `cdk ls` list all stacks in the app
53-
* `cdk synth` emits the synthesized CloudFormation template
54-
* `cdk deploy` deploy this stack to your default AWS account/region
55-
* `cdk diff` compare deployed stack with current state
56-
* `cdk docs` open CDK documentation
101+
## Additional Reading
57102

58-
Enjoy!
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: 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
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Operations & Testing
2+
3+
## Post-Deployment Tasks
4+
5+
### Define the Client and User Pool IDs
6+
7+
1. In the AWS Management Console, open **Amazon Cognito** and select your user pool.
8+
2. Copy the **App client ID** for the deployed client and the **User pool ID**.
9+
10+
Set them as shell variables for the commands below:
11+
12+
```bash
13+
CLIENT_ID=<your-app-client-id>
14+
15+
USER_POOL_ID=<your-user-pool-id>
16+
```
17+
18+
### Create a Test User
19+
20+
```bash
21+
aws cognito-idp sign-up --client-id "$CLIENT_ID" --username demo@example.com --password 'P@ssw0rd!' --user-attributes Name=email,Value=demo@example.com
22+
23+
aws cognito-idp admin-confirm-sign-up --user-pool-id "$USER_POOL_ID" --username demo@example.com
24+
```
25+
26+
### Assign Groups
27+
28+
```bash
29+
aws cognito-idp admin-add-user-to-group --user-pool-id "$USER_POOL_ID" --username demo@example.com --group-name user
30+
31+
aws cognito-idp admin-add-user-to-group --user-pool-id "$USER_POOL_ID" --username demo@example.com --group-name admin # optional elevated access
32+
```
33+
34+
## Request Tokens & Call the API
35+
36+
1. Initiate authentication:
37+
38+
```bash
39+
aws cognito-idp initiate-auth \
40+
--auth-flow USER_PASSWORD_AUTH \
41+
--client-id "$CLIENT_ID" \
42+
--auth-parameters USERNAME=demo@example.com,PASSWORD='P@ssw0rd!'
43+
```
44+
45+
2. Extract the `AccessToken` from the response.
46+
3. Invoke the API:
47+
48+
```bash
49+
API_URL=<deployment output>
50+
ACCESS_TOKEN=<token from initiate-auth>
51+
52+
curl -i \
53+
-H "Authorization: Bearer $ACCESS_TOKEN" \
54+
"$API_URL/user"
55+
```
56+
57+
Users in the `user` group receive `Hello from User!`. Only `admin` group members receive `Hello from Admin!` from the `/admin` route.
58+
59+
## Troubleshooting
60+
61+
- **403 errors on every route:** Ensure the token is an *access* token (not an ID token) and that the Cognito app client allows the SRP auth flow.
62+
- **`AccessDeniedException` from AVP:** Confirm the policy store was created in a region that supports Verified Permissions and that the token issuer matches the configured user pool.
63+
- **Caching delays:** The Request Authorizer caches decisions for 120 seconds. Use different tokens or redeploy the stack when testing new policies.
64+
65+
## Observability
66+
67+
The authorizer Lambda logs every AVP decision. Review the CloudWatch log stream for entries similar to `Decision from AVP: Allow` or `Decision from AVP: Deny`.
68+
69+
## Security & Operational Considerations
70+
71+
- Remove `RemovalPolicy.DESTROY` from the user pool before production to avoid accidental data loss.
72+
- Replace the demo Lambda functions with real business logic or integrate with existing services.
73+
- Integrate infrastructure-as-code validation and automated tests before promoting changes.
74+
- Rotate Cognito secrets and enforce password policies that meet organizational requirements.
75+
76+
## Cleanup
77+
78+
To avoid ongoing charges when finished experimenting:
79+
80+
```bash
81+
cdk destroy
82+
```
83+
84+
Verify that the Cognito users, Verified Permissions policy store, and CloudWatch logs are removed.
85+
86+
## Additional Resources
87+
88+
- [Amazon Verified Permissions documentation](https://docs.aws.amazon.com/verifiedpermissions/latest/userguide/)
89+
- [Cedar policy language](https://docs.cedarpolicy.com/)
90+
- [AWS Cloud Development Kit (AWS CDK) v2](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html)

0 commit comments

Comments
 (0)