

# Plan your deployment
<a name="plan-your-deployment"></a>

 This section describes the [cost](cost.md), [security](security.md), [Regions](#supported-aws-regions), and other considerations prior to deploying the solution. 

# Cost
<a name="cost"></a>

 You are responsible for the cost of the AWS services used while running this solution. The total cost for running this solution depends on the selected modules used in the solution and input parameters. 

 We recommend creating a [budget](https://docs.aws.amazon.com/cost-management/latest/userguide/budgets-create.html) through [AWS Cost Explorer](https://aws.amazon.com/aws-cost-management/aws-cost-explorer/) to help manage costs. Prices are subject to change. For full details, see the pricing webpage for each [AWS service used in this solution](architecture-details.md#aws-services). 

**Note**  
 Below cost estimates relate only to the elements created during the deployment of the solution. The charges associated with running the video workload on CloudFront, which must be created independently from this solution, are not included in the cost breakdown. 
 Example cost calculations listed below demonstrate incremental costs incurred from newly created components in your account as an output of the solution. 
 The total charges will also include the video delivery pipeline that consist of costs of running media content origin (for example, Amazon S3, AWS Elemental MediaPackage, among others) and delivery to the viewers through Amazon CloudFront. These costs are not specified below as this solution is designed to complement existing video streaming workloads implemented on Amazon CloudFront. 

 **Assumptions** 
+  The following examples provide a cost estimate for video streaming workload with 10 live streaming events per month, 60 mins in duration each, and driving 10,000 concurrent viewers. For each viewer, a playback token is generated once, just before the playout starts. It is assumed that during each event, 10 playback sessions are revoked manually, while 20 of them are detected and blocked as a result of automatic session revocation mechanism. 
+  Signing key is rotated automatically each day. 
+  To calculate the number of CloudFront Function invocations (example): 

  1. Number of viewing sessions 10,000 viewers \$1 10 events = 100,000 sessions

  1. Average viewing duration per session (seconds) 60 minutes \$1 60 = 3600 seconds

  1. Segment length (seconds) 2 seconds and manifest request after 3 consecutive segment requests (3600/2 \$1 3600/(2\$13) \$1100000 = 240M invocations 

## Base module
<a name="base-module-1"></a>

*Cost to validate request tokens and key rotation *


| AWS service  |  **Dimension/month**  |  **Cost [USD]**  | 
| --- | --- | --- | 
|  CloudFront Functions  |  240 million invocations  |  \$124.00  | 
|  Secrets Manager  |  3 secrets API call for 1 in 10 token generation operations Storage per secret per month  |  \$11.25 \$10.40 \$1 number of keys  | 
|  Step Functions  |  Number of transitions during key rotation workflow One rotation per day \$1 30/mo  |  < \$10.01  | 
|  Lambda  |  Lambda related costs during key rotation process One rotation per day \$1 30/mo  |  < \$10.01  | 
|  Total monthly cost:  |  \$1\$125.65 / month | 

**Note**  
 This solution uses [secrets key caching implemented in token generation method for Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/retrieving-secrets.html) to reduce API calls and cost 

## Session revocation
<a name="session-revocation"></a>

 **(Part of base module but it’s optional to use it)** 

*Cost to block compromised playback sessions* 


| AWS service  |  **Dimension/month**  |  **Cost [USD]**  | 
| --- | --- | --- | 
|  AWS WAF  |  Web ACL \$1 Rule Group \$1 Rules (\$1it is assumed no WebACL was not used before for video delivery and AWS WAF is associated with CloudFront solely for session revocation purpose)  |  \$16.14  | 
|  AWS WAF  |  Requests – 240 million (\$1it is assumed no web ACL was not used before for video delivery and AWS WAF is associated with CloudFront solely for session revocation purpose)  |  \$1144.00  | 
|  Total monthly cost:  |  \$1\$1150.14 / month  | 

## API Module
<a name="api-module-1"></a>

 **(Part of core module but it’s optional to use it)** 

*Cost to generate 100,000 of playback tokens per month *


| AWS service  |  **Dimension/month**  |  **Cost [USD]**  | 
| --- | --- | --- | 
|  API Gateway  |  100,000 API calls  |  \$10.10  | 
|  DynamoDB  |  50,000 Read Request Units Assume 1 request = .5 RRU  |  \$10.01  | 
|  CloudFront (fronting API Gateway) (Data Transfer \$1 Request charges)  |  100,000 HTTP requests with \$11kB response  |  \$10.11  | 
|  Lambda@Edge  |  100,000 function invocations  |  \$10.60  | 
|  Lambda  |  100,000 function invocations  |  \$10.20  | 
|  Total monthly cost:  |  \$1\$10.48 / month  | 

**Note**  
 Cost for API calls to Secrets Manager already included in Base module 

## Auto session-revocation
<a name="auto-session-revocation"></a>

 **(In addition to session revocation costs)** 

*Cost to run auto revocation pipeline*


| AWS service  |  **Dimension/month**  |  **Cost [USD]**  | 
| --- | --- | --- | 
|  Step Functions  |  Number of transitions during session scanning and updating workflow  |  \$10.14  | 
|  Athena  |  CloudFront Access Logs Data Scanned\$1 - 1545GB \$1 (single 1hr playback session produces \$1270KB log data)  |  \$17.54  | 
|  AWS WAF  |  Additional rules inserted into Rule Group from Session Revocation  |  \$10.27  | 
|  Total monthly cost:  |  \$17.95 / month  | 

## Metrics monitoring
<a name="metrics-monitoring"></a>

 *Cost of running the solution’s dashboard*


| AWS service  |  **Dimension/month**  |  **Cost [USD]**  | 
| --- | --- | --- | 
|  CloudWatch - Dashboard  |  Fixed cost for CloudWatch Dashboard  |  \$15.00  | 
|  CloudWatch Logs Insights – Data Scanned  |  Token verification results widget built on CloudWatch Logs insights – 72GB data scanned  |  \$10.36  | 
|  Total monthly cost:  |  \$1\$15.36 / month  | 

 If you choose to deploy the demo website (which we recommend deactivating after you launch the solution in a production environment), the solution automatically deploys Amazon S3 bucket for storing the static website assets in your account, and use the same CloudFront distribution created in front of API Gateway endpoint. You are responsible for the incurred variable charges from these services. 

# Security
<a name="security"></a>

 When you build systems on AWS infrastructure, security responsibilities are shared between you and AWS. This [shared responsibility model](https://aws.amazon.com/compliance/shared-responsibility-model/) reduces your operational burden because AWS operates, manages, and controls the components including the host operating system, the virtualization layer, and the physical security of the facilities in which the services operate. For more information about AWS security, visit [AWS Cloud Security](https://aws.amazon.com/security/). 

## IAM roles
<a name="iam-roles"></a>

 IAM roles allow customers to assign granular access policies and permissions to services and users on the AWS Cloud. This solution creates IAM roles associated with resources that needs to perform specific actions outlined in previous sections. Permissions defined in the policies created in the solution align with the principle of least privilege access, granting just those permissions that a specific component needs to fulfil its tasks fully. As one of the elements of the architecture is the solution’s library that can be run outside of AWS environment, we recommend using a specific role with the right set of permission to perform the actions against AWS services implemented in the library. You can find a reference to that role in the output section of the deployed CloudFormation stack under the **RoleArn** key. 

## Amazon CloudFront
<a name="amazon-cloudfront"></a>

 This solution deploys a demo website [hosted](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) in an Amazon S3 bucket. To help reduce latency and improve security, this solution includes an Amazon CloudFront distribution with an origin access identity, which is a CloudFront user that provides public access to the solution’s website S3 bucket contents. For more information, refer to [Restricting Access to Amazon S3 Content by Using an Origin Access Identity](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html) in the *Amazon CloudFront Developer Guide*. The same CloudFront distribution also interacts with API Gateway endpoint created for managing the access tokens. To maintain good security posture, API Gateway is configured to require AWS IAM authorization for invocation. Therefore, Lambda@Edge function with appropriate IAM permissions is used to sign CloudFront sourced requests. To further improve security of the demo website exposed to the user, a response header policy is attached in the configuration with a set of security headers returned to the viewer, **Strict-Transport-Security**, **X-XSS-Protection**, **X-Content-Type-Options**, **Referrer-Policy**, **X-Frame-Options**, **Content-Security-Policy**. 

## Solution’s code library
<a name="solutions-code-library"></a>

 The Secure Media Delivery at the Edge on AWS solution comes with a NodeJS library that was developed to make it easier to integrate solution into your Playback API workflow when adding token generation in it. Functions implemented in this library are built around API calls, made directly against AWS resources – API Gateway endpoint for token-related actions and DynamoDB table to submit the playback sessions that you want to be blocked. To make the API calls for AWS services work, IAM identity with right permission must be assumed when library’s code is run. When run in an AWS environment, you can simply utilize the roles assumed in the context in which library code is initiated – for example, execution role of Lambda functions defined in API module:` [Stack Name]_Generate Token` and `[Stack Name]_SaveManualSession`. If you choose to run your `Playback` API utilizing library provided functions outside an AWS environment, you must still assume the role using a standard approach of credential file, named profiles, or assuming role temporary through AWS Security Token Service; refer to [Setting Credentials in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/setting-credentials-node.html). When you interact with the solution classes’, you have an option to refer to a specific profile or Amazon Resource Name (ARN) reference of the role that must be assumed when underlying API calls are made. In this use case, we recommend providing ARN identifier of the dedicated role created specifically for the solution’s library, as it has precisely defined permissions that allow only appropriate actions against specific resources created in the stack. You can find a reference to that role in the output section of deployed CloudFormation stack under **RoleArn** key. 

## Signing key protection
<a name="signing-key-protection"></a>

 AWS Secrets Manager is a managed service to securely store and share the secrets based on the IAM defined permissions. A token-based access control mechanism, like the one used in this solution, works on the basis of generating and validating cryptographically created signature, which require a secret key to perform both tasks. AWS Secrets Manager stores the keys used in this solution. The keys are made available only to CloudFront Function and solution library methods, however they are distributed in a different way. CloudFront Functions receive updates with details about the new keys in a push model, when key rotation workflow generates and edits the keys known to CloudFront Function. Solution’s library methods obtain the keys in the pull model by reaching out to AWS Secrets Manager to retrieve the keys when needed. Standard IAM based access model applies where the credentials or role used in the library must translate to appropriate IAM permissions that grant access to the secrets in the deployed stack. This solution has been designed in a way that you do not have to manually define and set keys, instead automation included in the base module addresses that. We recommend leveraging the key rotation mechanism available in the solution to update the signing keys regularly to avoid using the same key for a prolonged period of time. 

## API Gateway
<a name="api-gateway"></a>

 HTTP API Gateway is configured to require AWS IAM authorization before the target Lambda functions responsible for token activities are invoked. Therefore, anonymous viewers without appropriate IAM permissions will not be able to make API calls. To successfully integrate other services with the API Gateway endpoint created in the solution, explicit IAM permissions must be granted to the corresponding user or role, allowing to invoke deployed API resource. 

# CloudFront prerequisites
<a name="cloudfront-prerequisites"></a>

 The Secure Media Delivery at the Edge on AWS solution has been designed to enhance the security of an existing video streaming workload that already utilizes CloudFront for content distribution to the viewers. As you prepare to integrate the solution into your architecture, the following requirements and preceding steps must be reviewed before activating the solution for your workloads. 

 **At the video origin level:** 

 The only requirement that must be met in terms of configuration of your video at origin which produces media segments and corresponding manifest files is to ensure that all media objects that need to be protected by secure tokens, are referenced in the video manifest with a relative rather than absolute path. This solution operates on the basis of inserting a token at the beginning of the playback URL path and the assertion that client’s player will repeat the token when subsequent elements that need to be processed are relative to the same root of the path, which is an inserted viewer token. Most of the video originating services compose the media manifest in that way. Once you confirm this also applies for your workload, proceed with the next steps to integrate the solution. If all or some of the objects in the manifest use absolute paths, which would override the token part when player makes a request for it, you must change your video origin configuration to replace absolute paths with relative paths. If this is not possible for all the objects, you can also exclude these specific objects from token validation step with the right adjustments in the CloudFront distribution configuration. 

 **At the CloudFront distribution level:** 

 In the existing CloudFront distributions used for the delivery of original video content, you must verify the following before you integrate this solution. 
+  Do the path patterns defined in cache behaviors match request URLs after you start inserting the access tokens? Comparing the URL path for the same object before and after secure tokens are added, you will find that a token appears as abstracted top-level directory in the URL path referencing video objects. 
  +  Before adding token: https://d1234.cloudfront.net/video\$1path\$1top\$1dir/video\$1path\$1subdir/object 
  +  After adding the token: https://d1234.cloudfront.net/**token**/video\$1path\$1top\$1dir/video\$1path\$1subdir/object 

 When verified against CloudFront distribution configuration, make sure that after token insertion appropriate cache behaviors match modified URL path including unique token values. Cache behavior requires the use of a wildcard at the beginning of the URL path pattern to match the arbitrary token value included in each request. In a common configuration in which you separate cache behavior for manifest files and video segments would like this: 

![\[Screenshot of cache behavior - wildcard .\]](http://docs.aws.amazon.com/solutions/latest/secure-media-delivery-at-the-edge-on-aws/images/image8.png)


 That configuration requires no changes in the path pattern definition as preceding wildcard covers additional path component introduced by token presence. However, if you have more explicit path pattern definitions (for example, when you run multiple streaming channels), your cache behaviors configuration may resemble this: 

![\[Screenshot of cache behavior – explicit path pattern.\]](http://docs.aws.amazon.com/solutions/latest/secure-media-delivery-at-the-edge-on-aws/images/image9.png)


 In that scenario, requests originated from the viewers with token included will not match with any of the listed cache behaviors as it starts with a fixed path pattern that does not accommodate part of an arbitrary token value at the beginning of the path. To change that, referenced path patterns can be modified as follows: 

![\[Screenshot of cache behavior – non-fixed path pattern.\]](http://docs.aws.amazon.com/solutions/latest/secure-media-delivery-at-the-edge-on-aws/images/image10.png)

+  Because the token validation logic is operated by CloudFront Functions code generated as one of the solution resources, before that function can be associated with viewer request triggers for the appropriate cache behaviors, you must make sure there is no Lambda@Edge function associated with either viewer request or viewer response triggers for the same set of cache behaviors. It is not possible to combine Lambda@Edge and CloudFront Functions associations for the same cache behavior. 
+  If you plan to leverage the session revocation feature offered by the solution, an AWS WAF web ACL must be created first and associated with the CloudFront distribution that will be integrated with the solution. If you run multiple CloudFront distributions that require token-based protection and session revocation capability, we recommend you run multiple stacks of the solution and associate created WAF rule group with separate AWS WAF web ACL dedicated for each distribution. This ensures efficient use of WAF Capacity Units (WCU) as each rule group will only store the sessions that are in use for a given distribution. 
+  Integrating your video streaming CloudFront distribution with auto session revocation requires additional steps to make the detail about all the incoming request accessible for Athena to distill suspicious sessions. Activating CloudFront access logs is the first step which delivers log files to the S3 bucket of your choice. For Athena to be able to run queries against these log files it needs additional metadata that will instruct how to parse and interpret log files, and also how to map column names to specific fields. You must define that information by creating database and table definitions in AWS Glue Data catalog. Refer to [Querying Amazon CloudFront logs](https://docs.aws.amazon.com/athena/latest/ug/cloudfront-logs.html) for a basic use case and additional information. 

## Supported AWS Regions
<a name="supported-aws-regions"></a>

 This solution can be launched in any AWS Region of your choice in which regional resources will be created: 
+  Secrets in Secrets Manager 
+  Step Functions workflows 
+  Lambda functions 
+  Dynamo DB tables 

 Note that because automatic session revocation module is deployed as a separate CloudFormation stack, you can deploy it in a different Region as the main stack. This can be beneficial in terms of reducing the costs arising from cross region Athena queries. Refer to [Querying across regions](https://docs.aws.amazon.com/athena/latest/ug/querying-across-regions.html) for additional Amazon S3 data transfer. 

 No matter in what target Region you deploy the main stack, which includes the core components of the solution, a dependency with US East (N. Virginia) (us-east-1) Region will exist as some of the components must be defined in that region. This is because those components can be associated with the CloudFront distribution which is a global service. These components are WAF rule group and Lambda@Edge function for signing requests towards API Gateway. Both of these resources are created through custom resource logic synthesized in the main CloudFormation stack deployed in the target region. 

# Supported formats
<a name="supported-formats"></a>

 This solution works with the video streaming workloads that use the most common adaptive bitrate streaming formats for distributing their video assets: HTTP Live Streaming (HLS), Dynamic Adaptive Streaming over HTTP (DASH), and Common Media Application Format (CMAF) which breaks down continuous video stream into discrete video and audio segments, suitable for Content Delivery Network (CDN) caching. Customers can use any media originating service which publishes video content in one or more of the mentioned formats, for example, Elemental MediaPackage, Elemental MediaStore, Amazon S3, or an external video packaging service. 

# Revise origin request policies
<a name="revise-origin-request-policies"></a>

 This solution provides you the ability to select a specific cache behavior in CloudFront configuration where token validation needs to be applied. Token validation logic takes viewer specific attributes, exposed at runtime through event object, to validate if the viewer using this token is in fact the viewer this token is for. This form of viewer uniqueness is achieved by including the token viewer specific attributes, some of them relating to the viewer’s location, like country or region. Viewer location information is available only through CloudFront generated headers that token validation code has to pull that information from. However, that category of headers will only appear in the event object when these specific headers are specified either in cache or origin request policies. To prevent negative impact on cache hit ratio, rather than using cache policies we recommend that you add the two specific geolocation headers in each origin request policy that is associated with token protected cache behaviors. In the origin request policy definition, include both `CloudFront-Viewer-Country` and `CloudFront-Viewer-Country-Region` in the headers section. 

![\[Screenshot of origin request policy - geolocation headers.\]](http://docs.aws.amazon.com/solutions/latest/secure-media-delivery-at-the-edge-on-aws/images/image11.png)


# Auto session revocation
<a name="auto-session-revocation-1"></a>

 Before you begin to use and deploy auto session revocation module in your architecture, review the following considerations to ensure the entire process is accurate and efficient. 
+  **Access log retentions** – Video streaming use cases at a large scale, inevitable will drive large amount of traffic. In turn, these will produce large volume of log entries which feed the auto session revocation analysis. Therefore, to optimize for costs we recommend looking into S3 lifecycle configuration options to expire and remove dated log files that do not provide actionable insights any more. This will not only save the costs of S3 storage but also amount of data that needs to be scanned by Amazon Athena which is one of the main cost components of this service. 
+  Another technique to reduce the cost associated with the size of data scanned by Amazon Athena is to employ log partitioning method to segregate the log files being produced in the supporting folder hierarchy that organize the files per year, month, day, and hour. This is because when you run Athena query, only the recent log entries represent the present usage of various playback sessions, usually up to tens of minutes at most. By limiting lookback period from the current time, you only dedicate the available resources to inspect current traffic and to block ongoing playback sessions rather the ones which were only active before. With partitioned log files, SQL query can take advantage of that by limiting the scope of the target files to a specific time period and vastly minimize the amount of data that is scanned. We recommend reviewing one of the possible solutions for partitioning CloudFront Logs as described in [Analyze your Amazon CloudFront access logs at scale](https://aws.amazon.com/blogs/big-data/analyze-your-amazon-cloudfront-access-logs-at-scale/). Auto session revocation module supports boot partitioned and non-partitioned log structure. 
+  One of the key dimensions of determining which sessions have been compromised, is the request rate corresponding to a given session relative to the median value. The assumption behind it is that when you issue an individual playback session you should observe approximately the same levels of request rates oscillating around median for each viewer. If playback session and corresponding access token is reused by multiple viewers, this would stand out as abnormal request rate, and the suspicion score increases as more viewers would share the same token and session ID. This assumption holds true when the video assets delivered through the target CloudFront distribution theoretically prompts the same request rate across legitimate viewers. If the request rate differs between video assets or renditions for the same content, the resulting median value will not be representative reference point and this can lead to identifying some legitimate session ID as compromised incorrectly. To avoid that effect, it is important to verify your assets have the same characteristic in terms of segment length and that you do not see significant differences in request rate from various clients. If you have video assets of varying characteristics, but you want to leverage auto session revocation mechanism, you can either turn off tracking request rates as one of the score components, or spread your video assets delivery across multiple CloudFront distributions according to their characteristic, and run separate auto session revocation pipelines for each. Note that tracking request rates in log processing pipeline aggregates multiple byte range requests against the same object. This means that the video clients requesting full segments will yield the same request rate result as the clients downloading the same segments partially with multiple range request. 

# Large viewership spikes
<a name="large-viewership-spikes"></a>

 The Secure Media Delivery at the Edge on AWS solution has been designed to support workloads of various scale including streaming services that draw very high viewership levels by using highly scalable components in processing the access tokens and processing log entries. One of the scaling factors is also ability to generate the tokens at the rate of viewers requesting playback URLs, and with the ability to scale underpinning resources to produce and serve access tokens back. In the design of this solution, access token is generated only once for each playback session and repeated by the same viewer for subsequent requests which vastly reduces the load at the playback API stage provided that new playback sessions spread over time. However, it is still possible that during specific periods of time, the load on playback API resulting from new playback requests and resulting number of parallel processes producing the tokens can exceed the available limits or underlying resource capacity. A typical example would be highly popular live streaming event, starting at a precise moment in time leading to excessive number of requests from new viewers starting the stream almost simultaneously. If your workload experiences this type of event pattern or simply serves very high number of new viewers in a steady state operation, make sure the underlying compute assets are able to scale appropriately to serve expected number of new viewers. In the reference architecture, the API module is capable of running multiple concurrent processes responsible for generating the token and supplying playback URL with the token in response. This is possible by the use of the standard scaling model of Lambda. You should monitor the concurrency metric in the region where the solution was deployed and request an increase if you are approaching this limit, or when you anticipate an upcoming event can drive exceedingly high viewership level. For the sudden spikes of playback API requests, you must also account for the rate at which Lambda concurrency can raise, which is 500 per minute. If this proves to be insufficient for the type of events you serve, consider using [Lambda provisioned concurrency](https://docs.aws.amazon.com/lambda/latest/dg/provisioned-concurrency.html) to improve the ability to absorb rapid increase of new viewers. 

 The other aspect of scalability in the process of generating the tokens are the limits on API calls for AWS Secrets Manager. Note that in default implementation, a solution’s library method reaches out to Secrets Manager to obtain the signing keys required to issue a token. In the region where secrets are stored, API rate quota exists which limits the number of **GetSecretValue** calls made from solution’s library method and equals to 5000 transactions per second. This does not indicate that the maximum token generation rate is at the same level. In the solution’s library implementation of managing the secrets, a local memoization technique is used to cache the secrets retrieved in the context of running process. You need to specify for how long a secret should be cached in memory so that it can be reused by the same threads initiated in the scope of the same process. For this reason, to enhance reusability of the once retrieved key, we recommend producing the tokens by using long running process to serve the requests and asynchronous threads that could share the same object holding the keys. This will effectively reduce the number of API calls towards Secrets Manager. For large-scale events that need to run a large number of parallel processes, to the point when Secrets Manager API calls limit can become a concern, it is possible to define custom key retrieval function that would introduce another layer of caching. For instance, you can create a dedicated function which would retrieve original key from AWS Secrets Manager but also store it in a shared space between the processes, for instance using in-memory data store like Amazon ElasticCache. 

# Alternative approaches to carry the token
<a name="alternative-approaches-to-carry-the-token"></a>

 The default and suggested method for including the token persistently throughout the viewer playback time is to use URL path. By inserting the token at the beginning of the playback URL which makes a reference point for the player for subsequent requests, it makes the solution more universally supported as it uses the most fundamental mechanism of HTTP delivery, and minimizes implementation efforts as this mechanism is transparent from the video origin standpoint. However, if this approach is not viable for your specific use case, you can choose a different way of attaching the token with the requests which does not have to rely on the URL path. Cookies, custom headers, query string parameters are potential other carriers for the token and using the solution’s library it is possible to generate a plain token that would normally appear in URL path in default mode. However, this involves customization of CloudFront Functions code to look up and parse the token and session ID in a place other than the URL path, by modifying the source code appropriately. The rest of the token validation logic would remain unchanged regardless of how the token is attached with the request. You must ensure token stickiness so that with a different approach to carry the token, this token is repeated in the future requests made by the same client for the protected objects. 

# Quotas
<a name="quotas"></a>

 Service quotas, also referred to as limits, are the maximum number of service resources or operations for your AWS account. 

## Quotas for AWS services in this solution
<a name="quotas-for-aws-services-in-this-solution"></a>

 Make sure you have sufficient quota for each of the [services implemented in this solution](architecture-details.md#aws-services). For more information, see [AWS service quotas](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html). 

 Use the following links to go to the page for that service. To view the service quotas for all AWS services in the documentation without switching pages, view the information in the [Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/aws-general.pdf#aws-service-information) page in the PDF instead. 

 As you evaluate the deployment of the Secure Media Delivery at the Edge on AWS solution, one limit that should be accounted for is WCU capacity of the web ACL used with CloudFront, and when session revocation module is to be launched. The default WCU limit for AWS WAF web ACL equals to 1500 WCU which is a shared capacity for the customer defined and managed WAF Rules, as well as the rule group created in the main module of the solution. For any rule group created, its WCU limit must be declared at the time of its creation and the value you specify at this stage is what gets consumed from web ACL general WCU limit. Rule group WCU limit cannot be modified after creation, therefore you must plan in advance how much WCU you want to allocate for session revocation rule group (recall that a rule to block a single session is worth 2 WCU). The limit you plan to apply for the rule group when launching the solution cannot exceed WCU headroom left in the web ACL that the rule group will be attached to. If there is not enough headroom left for the size of the rule group you plan to create when launching the solution, request WCU limit increase for that target web ACL to increase available WCU headroom. 