Required tools to build an AWS CloudFront Lambda@Edge function to authenticate requests
2.0K
Work-In-Progress (WIP)
An attempt to automate the build process of AWS Lambda@Edge function, that is used for authentication and authorization.
appappyour email addressexample.comyour email address
Click SAVE AND CONTINUEapp-ssohttps://app.example.comhttps://app.example.com/_callback
Click CREATESet environment variables according to your application and IdP, either with export MY_VAR=MY_VALUE or with the .env file
AUTHN="GOOGLE" # Identity Provider (IdP)
AUTH_AUTHZ="HOSTED_DOMAIN" # Authorize by email domain
AUTH_HOST_DOMAIN="example.com" # Only users with this domain will be authorized to login
AUTH_REDIRECT_URI="https://app.example.com/_callback"
AUTH_CLIENT_ID="myClientId"
AUTH_CLIENT_SECRET="myClientSecret"
AUTH_CLOUDFRONT_DIST_ID="E1TU2EGCZDDALR"
AUTH_SESSION_DURATION_HOURS=12
Run a container that will build your customized Lambda@Edge function
# Copy `env` to `.env`, or pass environment variables with `-e MY_VAR=MY_VALUE`
docker run --rm -it --env-file .env -v "${PWD}/distributions/":/usr/src/app/distributions/ -v "${PWD}/out/":/usr/src/app/out/ unfor19/cloudfront-auth
# Check for a new ZIP file in PWD/out/, named after your CloudFront Distribution ID, like `E1TU2EGCZDDALR.zip`
Some explanations about the Docker volume mounts
-v "${PWD}/distributions/":/usr/src/app/distributions/ - Contains a sub-directory per CloudFront Distribution Id. Each directory contains the artifacts that will be zipped per distribution. This mount is for debugging purposes, to see what's inside the package. Also, the pem and pub are generated only if they don't exist, so having this mount means you'll use the same pem and pub keys per distribution, instead of generating new ones.-v "${PWD}/out/":/usr/src/app/out/ - Contains the final artifacts ${DISTRIBUTION_ID}.ZIP files. The ZIP file is then uploaded as the Lambda@Edge function code.Clone or fork this repository.
docker build -t cloudfront-auth .
# Copy `env` to `.env`, or pass environment variables with `-e MY_VAR=MY_VALUE`
docker run --rm -it --env-file .env -v "${PWD}/distributions/":/usr/src/app/distributions/ -v "${PWD}/out/":/usr/src/app/out/ cloudfront-auth
E1TU2EGCZDDALR.zip. The ZIP file is a ready-to-deploy Viewer-Request Lambda@Edge Function.TODO: Add code snippets of how to automatically deploy this function as part of CloudFormation/Terraform.
docker build -t cloudfront-auth:dev --target=dev .
# Copy `env` to `.env`, or pass environment variables with `-e MY_VAR=MY_VALUE`
docker run --rm -it --env-file .env -v "$PWD":/usr/src/app/ cloudfront-auth:dev
# Make sure you set environment variables according to the `env` file before executing this command
yarn build:ci
/usr/src/app/distributions and /usr/src/app/outGoogle Apps (G Suite), Microsoft Azure AD, GitHub, OKTA, Auth0, Centrify authentication for CloudFront using Lambda@Edge. The original use case for cloudfront-auth was to serve private S3 content over HTTPS without running a proxy server in EC2 to authenticate requests; but cloudfront-auth can be used authenticate requests of any Cloudfront origin configuration.
Upon successful authentication, a cookie (named TOKEN) with the value of a signed JWT is set and the user redirected back to the originally requested path. Upon each request, Lambda@Edge checks the JWT for validity (signature, expiration date, audience and matching hosted domain) and will redirect the user to configured provider's login when their session has timed out.
If your CloudFront distribution is pointed at a S3 bucket, configure origin access identity so S3 objects can be stored with private permissions. (Origin access identity requires the S3 ACL owner be the account owner. Use our s3-object-owner-monitor Lambda function if writing objects across multiple accounts.)
Enable SSL/HTTPS on your CloudFront distribution; AWS Certificate Manager can be used to provision a no-cost certificate.
Session duration is defined as the number of hours that the JWT is valid for. After session expiration, cloudfront-auth will redirect the user to the configured provider to re-authenticate. RSA keys are used to sign and validate the JWT. If the files id_rsa and id_rsa.pub do not exist they will be automatically generated by the build. To disable all issued JWTs upload a new ZIP using the Lambda Console after deleting the id_rsa and id_rsa.pub files (a new key will be automatically generated).
https://my-cloudfront-site.example.com/_callback./build.sh in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.
Github as the authorization method and enter the values for Client ID, Client Secret, Redirect URI, Session Duration and Organization
zip file found in your distribution folder using the AWS Lambda console and jump to the configuration stephttps://my-cloudfront-site.example.com/_callback./build.sh in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.Google as the authorization method and enter the values for Client ID, Client Secret, Redirect URI, Hosted Domain and Session Durationzip file found in your distribution folder using the AWS Lambda console and jump to the configuration stepSettings -> Keys and make a new key with your desired duration. Click save and copy the value. This will be your client_secretKeys, go to Reply URLs and enter your Cloudfront hostname with your preferred path value for the authorization callback. Example: https://my-cloudfront-site.example.com/_callback./build.sh in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.Microsoft as the authorization method and enter the values for Tenant, Client ID (Application ID), Client Secret (previously created key), Redirect URI and Session Durationzip file found in your distribution folder using the AWS Lambda console and jump to the configuration stepApplications tab.Web application typehttps://{cf-endpoint}.cloudfront.net)https://{cf-endpoint}.cloudfront.net/_callback)./build.sh in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.OKTA as the authorization method and enter the values for Base URL (Org URL), Client ID, Client Secret, Redirect URI, and Session Durationzip file found in your distribution folder using the AWS Lambda console and jump to the configuration stephttps://my-cloudfront-site.example.com/_callback./build.sh in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.AUTH0 as the authorization method and enter the values for Base URL (Auth0 Domain), Client ID, Client Secret, Redirect URI, and Session Durationzip file found in your distribution folder using the AWS Lambda console and jump to the configuration stephttps://my-cloudfront-site.example.com/_callback./build.sh in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.CENTRIFY as the authorization method and enter the values for Base URL (Centrify Resource application URL), Client ID, Client Secret, Redirect URI, and Session Duration (which is available from the Tokens tab).zip file found in your distribution folder using the AWS Lambda console and jump to the configuration stepApplications tab.Native application typehttps://{cf-endpoint}.cloudfront.net)https://{cf-endpoint}.cloudfront.net/_callback)./build.sh in the downloaded directory. NPM will run to download dependencies and a RSA key will be generated.OKTA Native as the authorization method and enter the values for Base URL (Org URL), Client ID, PKCE Code Verifier Length, Redirect URI, and Session Durationzip file found in your distribution folder using the AWS Lambda console and jump to the configuration stepManual Deployment or AWS SAM Deployment
JSON array of email addresses
[ "[email protected]", "[email protected]" ]
Detailed instructions on testing your function can be found in the Wiki.
All contributions are welcome. Please create an issue in order open up communication with the community.
When implementing a new flow or using an already implemented flow, be sure to follow the same style used in build.js. The config.json file should have an object for each request made. For example, openid.index.js converts config.AUTH_REQUEST and config.TOKEN_REQUEST to querystrings for simplified requests (after adding dynamic variables such as state or nonce). For implementations that are not generic (most), endpoints are hardcoded in to the config (or discovery documents).
Be considerate of our limitations. The zipped function can be no more than 1MB in size and execution cannot take longer than 5 seconds, so we must pay close attention to the size of our dependencies and complexity of operations.
Content type
Image
Digest
Size
68.1 MB
Last updated
about 5 years ago
docker pull unfor19/cloudfront-auth