Skip to content

Commit ba35b3e

Browse files
committed
2 parents 725dc50 + a0eb385 commit ba35b3e

File tree

142 files changed

+4704
-271
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

142 files changed

+4704
-271
lines changed

alb-lambda-cdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"typescript": "~3.9.7"
2222
},
2323
"dependencies": {
24-
"aws-cdk-lib": "2.80.0",
24+
"aws-cdk-lib": "2.177.0",
2525
"constructs": "^10.0.0",
2626
"source-map-support": "^0.5.21"
2727
}
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
2+
# Created by https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode
3+
4+
### Linux ###
5+
*~
6+
7+
# temporary files which can be created if a process still has a handle open of a deleted file
8+
.fuse_hidden*
9+
10+
# KDE directory preferences
11+
.directory
12+
13+
# Linux trash folder which might appear on any partition or disk
14+
.Trash-*
15+
16+
# .nfs files are created when an open file is removed but is still being accessed
17+
.nfs*
18+
19+
### OSX ###
20+
*.DS_Store
21+
.AppleDouble
22+
.LSOverride
23+
24+
# Icon must end with two \r
25+
Icon
26+
27+
# Thumbnails
28+
._*
29+
30+
# Files that might appear in the root of a volume
31+
.DocumentRevisions-V100
32+
.fseventsd
33+
.Spotlight-V100
34+
.TemporaryItems
35+
.Trashes
36+
.VolumeIcon.icns
37+
.com.apple.timemachine.donotpresent
38+
39+
# Directories potentially created on remote AFP share
40+
.AppleDB
41+
.AppleDesktop
42+
Network Trash Folder
43+
Temporary Items
44+
.apdisk
45+
46+
### PyCharm ###
47+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
48+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
49+
50+
# User-specific stuff:
51+
.idea/**/workspace.xml
52+
.idea/**/tasks.xml
53+
.idea/dictionaries
54+
55+
# Sensitive or high-churn files:
56+
.idea/**/dataSources/
57+
.idea/**/dataSources.ids
58+
.idea/**/dataSources.xml
59+
.idea/**/dataSources.local.xml
60+
.idea/**/sqlDataSources.xml
61+
.idea/**/dynamic.xml
62+
.idea/**/uiDesigner.xml
63+
64+
# Gradle:
65+
.idea/**/gradle.xml
66+
.idea/**/libraries
67+
68+
# CMake
69+
cmake-build-debug/
70+
71+
# Mongo Explorer plugin:
72+
.idea/**/mongoSettings.xml
73+
74+
## File-based project format:
75+
*.iws
76+
77+
## Plugin-specific files:
78+
79+
# IntelliJ
80+
/out/
81+
82+
# mpeltonen/sbt-idea plugin
83+
.idea_modules/
84+
85+
# JIRA plugin
86+
atlassian-ide-plugin.xml
87+
88+
# Cursive Clojure plugin
89+
.idea/replstate.xml
90+
91+
# Ruby plugin and RubyMine
92+
/.rakeTasks
93+
94+
# Crashlytics plugin (for Android Studio and IntelliJ)
95+
com_crashlytics_export_strings.xml
96+
crashlytics.properties
97+
crashlytics-build.properties
98+
fabric.properties
99+
100+
### PyCharm Patch ###
101+
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
102+
103+
# *.iml
104+
# modules.xml
105+
# .idea/misc.xml
106+
# *.ipr
107+
108+
# Sonarlint plugin
109+
.idea/sonarlint
110+
111+
### Python ###
112+
# Byte-compiled / optimized / DLL files
113+
__pycache__/
114+
*.py[cod]
115+
*$py.class
116+
117+
# C extensions
118+
*.so
119+
120+
# Distribution / packaging
121+
.Python
122+
build/
123+
develop-eggs/
124+
dist/
125+
downloads/
126+
eggs/
127+
.eggs/
128+
lib/
129+
lib64/
130+
parts/
131+
sdist/
132+
var/
133+
wheels/
134+
*.egg-info/
135+
.installed.cfg
136+
*.egg
137+
138+
# PyInstaller
139+
# Usually these files are written by a python script from a template
140+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
141+
*.manifest
142+
*.spec
143+
144+
# Installer logs
145+
pip-log.txt
146+
pip-delete-this-directory.txt
147+
148+
# Unit test / coverage reports
149+
htmlcov/
150+
.tox/
151+
.coverage
152+
.coverage.*
153+
.cache
154+
.pytest_cache/
155+
nosetests.xml
156+
coverage.xml
157+
*.cover
158+
.hypothesis/
159+
160+
# Translations
161+
*.mo
162+
*.pot
163+
164+
# Flask stuff:
165+
instance/
166+
.webassets-cache
167+
168+
# Scrapy stuff:
169+
.scrapy
170+
171+
# Sphinx documentation
172+
docs/_build/
173+
174+
# PyBuilder
175+
target/
176+
177+
# Jupyter Notebook
178+
.ipynb_checkpoints
179+
180+
# pyenv
181+
.python-version
182+
183+
# celery beat schedule file
184+
celerybeat-schedule.*
185+
186+
# SageMath parsed files
187+
*.sage.py
188+
189+
# Environments
190+
.env
191+
.venv
192+
env/
193+
venv/
194+
ENV/
195+
env.bak/
196+
venv.bak/
197+
198+
# Spyder project settings
199+
.spyderproject
200+
.spyproject
201+
202+
# Rope project settings
203+
.ropeproject
204+
205+
# mkdocs documentation
206+
/site
207+
208+
# mypy
209+
.mypy_cache/
210+
211+
### VisualStudioCode ###
212+
.vscode/*
213+
!.vscode/settings.json
214+
!.vscode/tasks.json
215+
!.vscode/launch.json
216+
!.vscode/extensions.json
217+
.history
218+
219+
### Windows ###
220+
# Windows thumbnail cache files
221+
Thumbs.db
222+
ehthumbs.db
223+
ehthumbs_vista.db
224+
225+
# Folder config file
226+
Desktop.ini
227+
228+
# Recycle Bin used on file shares
229+
$RECYCLE.BIN/
230+
231+
# Windows Installer files
232+
*.cab
233+
*.msi
234+
*.msm
235+
*.msp
236+
237+
# Windows shortcuts
238+
*.lnk
239+
240+
# Build folder
241+
242+
*/build/*
243+
244+
# End of https://www.gitignore.io/api/osx,linux,python,windows,pycharm,visualstudiocode
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.PHONY: build-CombinedLayer clean
2+
3+
# Default target
4+
build-CombinedLayer:
5+
mkdir -p "$(ARTIFACTS_DIR)/python"
6+
pip install requests -t "$(ARTIFACTS_DIR)/python"
7+
pip install python-jose -t "$(ARTIFACTS_DIR)/python"
8+
pip install cryptography -t "$(ARTIFACTS_DIR)/python"
9+
10+
clean:
11+
rm -rf "$(ARTIFACTS_DIR)"
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Certificate-Bound Access Tokens using Amazon API Gateway and Amazon Cognito
2+
3+
This pattern makes use of API Gateway and Cognito to implement certificate-bound access tokens. For more on certificate-boud access tokens, review the [RFC](https://datatracker.ietf.org/doc/html/rfc8705). This solution has some manual steps which will be discussed later.
4+
5+
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example.
6+
7+
## Requirements
8+
9+
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html)~ if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources.
10+
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)~
11+
* [AWS Serverless Application Model](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)~ (AWS SAM) installed
12+
* [Docker installed](https://docs.docker.com/engine/install/).
13+
* A domain that you own.
14+
* A certificate issued under the domain you own.
15+
* Create client certificate as per the [mTLS blogpost](https://aws.amazon.com/blogs/compute/introducing-mutual-tls-authentication-for-amazon-api-gateway/).
16+
17+
Place the trust store in the S3 bucket that you will specfiy when deploying in the solution.
18+
19+
## Deployment Instructions
20+
21+
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository:
22+
```
23+
git clone https://github.com/aws-samples/serverless-patterns
24+
```
25+
26+
2. Change directory to the pattern directory:
27+
```
28+
cd apigw-cognito-certificate-bound-access-token
29+
```
30+
31+
3. Build the solution:
32+
```
33+
sam build --use-container
34+
```
35+
36+
3. Deploy the solution:
37+
```
38+
sam deploy --guided
39+
```
40+
41+
Parameter_overrides:
42+
* BucketName - to store client certificate and trust store.
43+
* CACertKey - trust store.
44+
* ClientCertKey - client certificate Amazon S3 object key.
45+
* CustomDomainCertArn - custom domain AWS Certificate Manager certficate ARN.
46+
* CustomDomainName - custom domain name for API Gateway. Must match CustomDomainCertArn.
47+
48+
## How it works
49+
50+
This pattern creates an Amazon API Gateway REST API with a custom domain name and enables mTLS. Further, it creates a Cognito User Pool. The Cognito User Pool is used to issue certificate-bound access tokens. The REST API makes use of an authorizer to compare the "cnf" claim in the access token to the fingerprint of the client certificate sent as part of the mutual authentication TLS handshake.
51+
52+
## Testing
53+
54+
1. Determine the fingerprint of the client certificate and base64 encode it:
55+
```
56+
openssl x509 -in client-cert.crt -noout -fingerprint -sha256 | cut -d'=' -f2 | tr -d ':' | xxd -r -p | base64 | tr -d '='
57+
```
58+
59+
2. Navigate to the Cognito User Pool created in the solution. [Then create and verify](https://docs.aws.amazon.com/cognito/latest/developerguide/signing-up-users-in-your-app.html) a user.
60+
61+
3. Add the certificate fingerprint to the `custom:cert_fingerprint` custom attribute of the user.
62+
63+
4. [Create a DNS record](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-api-gateway.html) for the custom domain.
64+
65+
5. [Get an access token](https://docs.aws.amazon.com/cognito/latest/developerguide/authentication-flows-public-server-side.html) from Cognito.
66+
67+
Example of getting an access token using the AWSCLI:
68+
```
69+
aws cognito-idp admin-initiate-auth \
70+
--user-pool-id YOUR_USER_POOL_ID \
71+
--client-id YOUR_CLIENT_ID \
72+
--auth-flow ADMIN_USER_PASSWORD_AUTH \
73+
--auth-parameters 'USERNAME=YOUR_USERNAME,PASSWORD=YOUR_PASSWORD' \
74+
--region us-east-1 \
75+
--query 'AuthenticationResult.AccessToken' \
76+
--output text
77+
```
78+
79+
Notes that this requires the `ADMIN_USER_PASSWORD_AUTH` auth flow which is not enabled by default by this solution. You will need to do it on the console. This is only for testing purposes.
80+
81+
6. Test the solution:
82+
83+
```
84+
curl -v https://<your_custom_domain>/example --cert client-cert.crt --key client-cert.key -H "Authorization: <certificate_bound_access_token>"
85+
```
86+
87+
You should see output as follows:
88+
```
89+
{"message": "Hello from the example function!", "event": {"resource": "/example", "path": "/example"...
90+
```
91+
92+
## Cleanup
93+
94+
1. Delete the stack
95+
```bash
96+
sam delete
97+
```
98+
1. Confirm the stack has been deleted
99+
```bash
100+
aws cloudformation list-stacks --query "StackSummaries[?contains(StackName,'STACK_NAME')].StackStatus"
101+
```
102+
----
103+
Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
104+
105+
SPDX-License-Identifier: MIT-0

apigw-cognito-certificate-bound-access-token/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)