Topics
You might want to control who has access to the content you serve through CloudFront. For example, you might want to charge your end users for the content, and only give access to those who have paid. This section describes how to restrict end user access to your content.
![]() | Important |
|---|---|
This feature is available only with basic distributions, and not with streaming distributions. |
You can think of your content as being either public or private (i.e., restricted). The following table gives a general description of what each means.
| Type of Content | General Description | General Implementation |
|---|---|---|
|
Public |
You want anyone to be able to access your objects |
You set the Amazon S3 Access Control List (ACL) on the objects
in your bucket to give |
|
Private |
You want to restrict who can access your objects (for example, to control access to a paid download) |
You set the Amazon S3 ACL on your objects so that only you and
CloudFront have You also produce special signed URLs for the particular end users you want to give access to. |
The two initial API versions for CloudFront (2008-06-30 and 2009-04-02) require your content to be public. The 2009-09-09 version (and later) lets you serve public content, private content, or both.
The underlying process of serving private content has two main parts described in the following diagram and table.

![]() |
Securing the content in your bucket so that end users only have access to the content through CloudFront. You remove all public access to the object in your buckets, but
still give CloudFront permission to fetch the objects. To do this,
you create a CloudFront origin access
identity, which is a virtual identity that you give
|
![]() |
Restricting end user access to cached content. You hand out special signed URLs to end users you want to give access to. The URLs contain restrictions limiting access to the private content. |
You can do both parts, or just part 1. If you just do part 1, you still use basic URLs just as you do to serve public content. You don't sign the URLs.
A distribution can serve only one type of content at a given time (the types are shown in the following table). You can switch a distribution from serving one type of content to another just by adding or removing elements from its configuration. Note that when you switch a distribution to serve a different type of content, you must also provide your end users with basic or signed URLs according to how the distribution is configured.
| Type of content | Special configuration elements |
|---|---|
|
Public content |
None |
|
Private content, with signed URLs |
|
|
Private content, with basic URLs |
|
A CloudFront origin access identity is a virtual identity you
use to let CloudFront fetch private content from your bucket. Essentially you create
a CloudFront origin access identity for your AWS account, attach the identity to your
distribution, and then give that identity read permission to your private
objects in Amazon S3. Your distribution can then serve private objects from your bucket
with basic URLs (using signed URLs requires additional work on your part).
You can have up to 100 CloudFront origin access identities, and you can attach each to one or more distributions. You'll probably just have one identity, even if you have multiple distributions. The CloudFront control API provides a set of actions for creating and managing your CloudFront origin access identities. The actions are parallel to those for creating and managing distributions. For more information about the actions, go to Actions on Origin Access Identities in the Amazon CloudFront API Reference.
All your distributions can use the same Amazon S3 bucket if you like. The following diagram and table shows how you might configure multiple distributions to serve different types of content from the same bucket.

![]() |
Distribution 1 is configured for public content (the object has
an Amazon S3 ACL that grants everyone |
![]() |
Distribution 2 is configured to read private content with
signed URLs. This distribution is attached to CloudFront origin
access identity A. The object has an Amazon S3 ACL that grants
|
![]() |
Distribution 3 is configured to read private content with basic
URLs. This distribution is also attached to CloudFront origin
access identity A. The object has an Amazon S3 ACL that grants
|
The following figure and table describe the process for restricting end user access to your content. It's divided into two sections corresponding to the two underlying parts of the process (see Two Parts to Serving Private Content).
The first section (the top row, in blue) covers the tasks required to secure your content in Amazon S3 (i.e., to make your content private but still let CloudFront fetch it). Remember that you can just do the tasks in the first row and stop there if you only want to secure the content in your bucket. The set of tasks ensures there's no interruption in end user access to the content, if you're just reconfiguring a public content distribution to serve private instead of public objects.
The second section (the second row, in yellow) covers the additional tasks required to create signed URLs, which allow you to restrict a particular end user's access to the content.

Process for Serving Private Content
|
1 |
Use the CloudFront control API to create a CloudFront origin access identity. For more information, see Creating a CloudFront Origin Access Identity. |
|
2 |
Use the Amazon S3 API (or your favorite Amazon S3 tool) to
update the ACL on your private objects to give For more information about setting the ACL, see Modifying the ACL on Your Private Content Objects. |
|
3 |
Set up a private content distribution (either create a new one or update an existing distribution). For more information, see Setting Up a Private Content Distribution. |
|
4 |
Use the Amazon S3 API (or your favorite Amazon S3 tool) to
update the ACL on your private objects to remove any
For more information, see Modifying the ACL on Your Private Content Objects. You can stop here if you simply want to serve private content with basic URLs. Continue if you want to use signed URLs. |
|
5 |
Use the AWS web site to create a key pair and download the private key, which you'll use to sign the URLs. For more information about creating your key pair, see Creating a Key Pair. |
|
6 |
Update your private content distribution to specify that the distribution's URLs must be signed, and who can sign them. For more information, see Requiring Signed URLs. |
|
7 |
Create a signed URL to give the end user. For more information, see Creating a Signed URL. |
This section covers the tasks that enable you to secure your content in Amazon S3, and serve that secure content with basic URLs, just as you serve public content.
These tasks are part of the greater process of serving private content. For more information, see Overall Process to Serve Private Content. If you also want to serve content with signed URLs, see Getting Set Up to Use Signed URLs).
You can create a CloudFront origin access identity with a POST on the 2009-12-01/origin-access-identity/cloudfront resource. You must provide a unique caller reference in the request like you do when creating a distribution through the control API. You can optionally provide comments about the identity.
![]() | Note |
|---|---|
The AWS Management Console doesn't yet support the ability to create an origin access identity or to update your distribution to serve private content. |
To create a CloudFront origin access identity
Send a CloudFront control API request that looks similar to the following example.
POST /2009-12-01/origin-access-identity/cloudfront HTTP/1.1 [Required headers] <?xml version="1.0" encoding="UTF-8"?> <CloudFrontOriginAccessIdentityConfig xmlns="http://cloudfront.amazonaws.com/doc/2009-12-01/"> <CallerReference>20091130090000</CallerReference> <Comment>Your comments here</Comment> </CloudFrontOriginAccessIdentityConfig>
You will receive a response that looks similar to the following example.
201 Created
Location: https://cloudfront.amazonaws.com/2009-12-01/origin-access-identity/cloudfront/E74FTE3AJFJ256A
x-amz-request-id: request_id
<?xml version="1.0" encoding="UTF-8"?>
<CloudFrontOriginAccessIdentity xmlns="http://cloudfront.amazonaws.com/doc/2009-12-01/">
<Id>E74FTE3AJFJ256A</Id>
<S3CanonicalUserId>
cd13868f797c227fbea2830611a26fe0a21ba1b826ab4bed9b7771c9a69ba19f
</S3CanonicalUserId>
<CloudFrontOriginAccessIdentityConfig>
<CallerReference>20091130090000</CallerReference>
<Comment>Your comments here</Comment>
</CloudFrontOriginAccessIdentityConfig>
</CloudFrontOriginAccessIdentity>Store the Location header, which contains the URI for your
newly created CloudFront origin access identity; the Id,
which contains the ID you'll use to attach the identity to your
distribution; and the S3CanonicalUserId, which you'll use to
set the Amazon S3 ACL on the object.
A private content distribution looks like a public content distribution, except it
has an OriginAccessIdentity element in the configuration. You must
specify the value for the element using the following format:
origin-access-identity/cloudfront/. ID
To set up a private content distribution
Create a new distribution that includes an
OriginAccessIdentity element (or update an existing
distribution to include the element).
Following is an example request that creates a new private content distribution.
POST /2009-12-01/distribution HTTP/1.1 [Required headers] <?xml version="1.0" encoding="UTF-8"?> <DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2009-12-01/"> <Origin>mybucket.s3.amazonaws.com</Origin> <CallerReference>20091130090000</CallerReference> <Comment>My comments</Comment> <Enabled>true</Enabled> <OriginAccessIdentity>origin-access-identity/cloudfront/E74FTE3AJFJ256A</OriginAccessIdentity> </DistributionConfig>
For more information about updating a distribution, see Updating a Distribution's Configuration.
Once you have a private content distribution, you must grant your CloudFront
origin access identity read access to the private content. You do this by modifying
the Amazon S3 ACL on each of the objects (not on the bucket). In the object's ACL,
you add a grant that gives read permission to the CloudFront origin
access identity's canonical user ID (and not the other ID associated with the
identity). You can use the Amazon S3 API or your favorite Amazon S3 tool to modify
the ACL.
When modifying Amazon S3 ACLs through the Amazon S3 API, you typically first GET the object's ACL, then make your desired changes to the ACL, and finally PUT the modified ACL. For more information about the ACL format and updating an ACL, go to REST Access Control Policy and Access Control Lists in the Amazon Simple Storage Service Developer Guide.
If you've updated a public content distribution to instead serve private content,
make sure to remove any grant in the ACL that gives read permission to
the public.
![]() | Important |
|---|---|
To ensure there's no disruption to end user access to the content, remove this
grant after you've set up the private content distribution
and confirmed its state is |
This section covers the tasks that get you set up to use signed URLs to give restricted access to a private object. You need to perform these tasks only once.
These tasks are part of the overall process of serving private content. For more information, see Overall Process to Serve Private Content.
Signing a URL is the process of creating an RSA digital signature using a special key and a portion of the URL string. This section describes how to get the special key for signing the URLs. What you actually get is a key pair consisting of a private key and a public key. AWS keeps the public key, and you keep the private key (and use it to sign the URLs).
![]() | Important |
|---|---|
The key pair you need is not an X.509 certificate and private key. It's an RSA key pair. If you're an Amazon EC2 user, you probably already have at least one other RSA key pair, which you use to connect to your instances through SSH or Windows Remote Desktop. You can reuse any of your EC2 key pairs with Amazon CloudFront (see the procedure that follows for uploading your public key to the AWS web site). Note that Amazon EC2 doesn't provide you the public key when you create the key pair; however, it's possible to extract the key from the private key or from the EC2 instance. |
If you have a key pair you want to use, you can upload the public key to AWS (you keep the private key). The public key must be an RSA key encoded in PEM format.
To upload your own public key
From the Amazon Web Services web site at http://aws.amazon.com, point to Your Account and click Security Credentials.
Log in to your AWS account.
The Security Credentials page is displayed.
In the Access Credentials section of the page, click the Key Pairs tab.
In the Amazon CloudFront Key Pairs area, click Upload Your Own Key Pair.
Follow the instructions presented to upload your public key.
If you don't already have a key pair, you can have AWS generate a pair and automatically associate the public key with your AWS account.
To have AWS create a key pair for you
From the Amazon Web Services web site at http://aws.amazon.com, point to Your Account and click Security Credentials.
Log in to your AWS account.
The Security Credentials page is displayed.
In the Access Credentials section of the page, click the Key Pairs tab.
In the Amazon CloudFront Key Pairs area, click Create a New Key Pair.
Your new public and private key are generated, along with an ID for the key pair. Amazon keeps the public key and gives you the private key.
From the dialog box, download your private key file to a local directory, and record the corresponding key pair ID.
You should keep your private key file secure. Make sure to set the permissions
on the file so only you can read it. For a Linux/UNIX system, use chmod
600. To set the permission on a Windows system, right-click the file
and set the file's security properties appropriately.
You must configure your private content distribution to specify that the URLs must be signed, and who can sign them. You can let up to five AWS accounts other than your own sign URLs for your distribution's private content. Each AWS account owner you authorize must create and use their own key pair (for more information, see Creating a Key Pair). You include the ID for the signing key in the URL so that AWS can identify the signer.
To specify that URLs must be signed
Add a TrustedSigners element to the distribution's
configuration.
To specify who can sign URLs
Add an empty Self child element to the
TrustedSigners element if you want to sign URLs (we don't
assume this, so you must explicitly give yourself permission).
Add an AwsAccountNumber child element to the
TrustedSigners element for each AWS account (other than
your own) that you want to give signing authority (limit of five). Remove
the dashes from the account number.
The AWS account number is displayed in the top right corner of the account owner's Account Activity page at http://aws.amazon.com (see the example image below).

Following is an example request that creates a private content distribution, and authorizes you and two other AWS accounts to create signed URLs for the distribution.
POST /2009-12-01/distribution HTTP/1.1
[Required headers]
<?xml version="1.0" encoding="UTF-8"?>
<DistributionConfig xmlns="http://cloudfront.amazonaws.com/doc/2009-12-01/">
<Origin>mybucket.s3.amazonaws.com</Origin>
<CallerReference>20091130090000</CallerReference>
<Comment>My comments</Comment>
<Enabled>true</Enabled>
<OriginAccessIdentity>origin-access-identity/cloudfront/E127G7VVVYK51Z</OriginAccessIdentity>
<TrustedSigners>
<Self/>
<AwsAccountNumber>123499998765</AwsAccountNumber>
<AwsAccountNumber>098711114567</AwsAccountNumber>
</TrustedSigners>
</DistributionConfig>Once you've specified the trusted signers, you should check to see which of them are active. For a trusted signer to be active, both of the following must be true:
The AWS account has at least one active key pair (you can set a key pair to inactive when you rotate your keys; for more information, go to Access Credential Rotation)
CloudFront is aware of the active key pair (after you create a key pair, there can be a short period of time before CloudFront is aware the key pair exists)
To determine the active trusted signers for a distribution,
get the distribution's information (not just the configuration, but the entire
distribution). The response includes an ActiveTrustedSigners element
that lists the ID of each active key pair associated with each trusted signer's AWS
account. If a trusted signer doesn't have an active key pair that CloudFront is
aware of, that signer doesn't have a KeyPairId element listed for
it.
The following example response shows that you yourself have two active key pairs,
and the AWS account with ID 123499998765 has one active key pair. However, the third
trusted signer (with account ID 09871114567) doesn't yet have an active key pair (no
KeyPairId appears for that signer) and so can't create working
signatures.
200 OK
ETag: E2QWRUHAPOMQZL
x-amz-request-id: request_id
<Distribution xmlns="http://cloudfront.amazonaws.com/doc/2009-12-01/">
<Id>EDFDVBD632BHDS5</Id>
<Status>Deployed</Status>
<LastModifiedTime>2009-11-19T19:37:58Z</LastModifiedTime>
<DomainName>d604721fxaaqy9.cloudfront.net</DomainName>
<ActiveTrustedSigners>
<Signer>
<Self/>
<KeyPairId>APKAI72T5DYBXZDKA7TA</KeyPairId>
<KeyPairId>APKAU72D8DYNXZDKA8DP</KeyPairId>
</Signer>
<Signer>
<AwsAccountNumber>123499998765</AwsAccountNumber>
<KeyPairId>APKA9ONS7QCOWWZU7BP6</KeyPairId>
</Signer>
<Signer>
<AwsAccountNumber>098711114567</AwsAccountNumber>
</Signer>
</ActiveTrustedSigners>
<DistributionConfig>
<Origin>mybucket.s3.amazonaws.com</Origin>
<CallerReference>20091130090000</CallerReference>
<Comment>My comments</Comment>
<Enabled>true</Enabled>
<OriginAccessIdentity>E74FTE3AJFJ256A</OriginAccessIdentity>
<TrustedSigners>
<Self/>
<AwsAccountNumber>123499998765</AwsAccountNumber>
<AwsAccountNumber>098711114567</AwsAccountNumber>
</TrustedSigners>
</DistributionConfig>
</Distribution>The final task is to create the signed URL to give to the end user.
Signed means that the URL includes a Signature query parameter with an RSA digital signature.
To create a signed URL
Create the string to sign (for more information, see the remainder of this section).
Create an RSA-SHA1 digital signature of the string, using the private key from your key pair (for more information about the key, see Creating a Key Pair).
Make the signature URL safe (for more information, see the remainder of this section).
Include the URL-safe version of the signature as the value of the
Signature query parameter in the URL.
Include any other required query parameters (for more information, see the remainder of this section).
The main part of this section covers how to correctly create the string that you sign. The string itself is actually a policy, which is a short JSON document in UTF-8 format that lists the restrictions you want to place on access to the private content. When the end user clicks the URL, CloudFront evaluates the contents of the policy to determine if the end user should be allowed access to the object specified by the URL. There are two types of policies you can use: canned or custom. The following table describes the difference between them.
| Type of Policy | Description |
|---|---|
|
Canned |
Lets you restrict access to a single URL based only on expiration time. You don't include the policy in the URL itself, so a canned policy results in a shorter URL. Because you don't include the policy in the URL, CloudFront constructs a canned policy based on information in the URL itself, and uses that canned policy to both validate the signature and determine if the end user has access to the content. For more information about using a canned policy, see Canned Policy. |
|
Custom |
Lets you restrict access to one or more objects based on multiple criteria: end user IP address, a start time for access, and an expiration time for access. You must include the policy in the URL itself, so a custom policy results in a longer URL than a canned policy. CloudFront uses the included policy to both validate the signature and determine if the end user has access to the content. For more information, see Custom Policy. |
A signed URL that uses a canned policy consists of a regular CloudFront URL, plus the three special query parameters listed in the following table.
| Parameter | Description | Required |
|---|---|---|
|
|
The expiration time of the URL, in epoch or UNIX time (number of seconds since January 1, 1970; e.g., 1258237200.). Type: String |
Yes |
|
|
A URL-safe version of the signature. Type: String | Yes |
|
|
The key ID of the signing private key. Type: String | Yes |
![]() | Note |
|---|---|
We remove all query parameters (including those required for signed URLs) before recording the URL in the CloudFront access logs. For more information about access logs, see Access Logs. |
The Signature value is an RSA-SHA1 digital signature of the
following JSON policy, with the RESOURCE and EXPIRES
values replaced as described in the table that follows.
{"Statement":[{"Resource":"RESOURCE","Condition":{"DateLessThan":{"AWS:EpochTime":EXPIRES}}}]}![]() | Important |
|---|---|
For the signature you include in the URL to match the signature
CloudFront constructs based on the canned policy, you must make sure the
policy you construct looks exactly like the preceding policy. That is, you must
use your own valid values for |
The following table describes the values to substitute in the policy.
| Value in Policy | Substitute with... |
|---|---|
|
|
The URL with all the CloudFront query parameters removed
(the parameters are For example, if your full URL is: http://d604721fxaaqy9.cloudfront.net/download/horizon.jpg?large=yes&license=yes&Expires=1258237200&Signature=
The value for http://d604721fxaaqy9.cloudfront.net/download/horizon.jpg?large=yes&license=yes If there are no query parameters, don't include the question mark in the value. Make sure to put the value inside quotation marks in the policy. |
|
|
The value of the |
The signature is an RSA-SHA1 digital signature of the policy (with all white space and line feeds removed), using the private key from your key pair.
Signature (Policy) = RSA_Sign(SHA1, Policy, PrivateKey)
![]() | Important |
|---|---|
CloudFront uses an RSA-SHA1 signature, and not an HMAC-SHA1 signature, which is the type Amazon S3 and many other AWS products use. A common mistake is to implement HMAC-SHA1 instead of an RSA-SHA1 in your code for creating signatures for private content. |
Use the following translation to make the signature URL safe before including it in the URL.
Url-Safe (m) = CharReplace( Base64(m), "+=/", "-_~" )
For an example of a complete URL that uses a canned policy, see Signed URL Examples.
A signed URL that uses a custom policy consists of a regular CloudFront URL,
plus the three special query parameters listed in the following table. Notice that
no Expires parameter is required (as with canned policies);
instead a Policy parameter is required. The presence of the
Policy parameter in the URL tells CloudFront that
you're using a custom policy instead of a canned policy.
| Parameter | Description | Required |
|---|---|---|
|
|
A URL-safe version of the policy. Type: String |
Yes |
|
|
A URL-safe version of the signature Type: String | Yes |
|
|
The key ID of the signing private key. Type: String | Yes |
![]() | Note |
|---|---|
We remove all query parameters (including those required for signed URLs) before recording the URL in the CloudFront access logs. For more information about access logs, see Access Logs. |
The policy you use to create the signature is a simple JSON document in UTF-8 format that specifies the resource and any conditions for accessing the resource. Use the policy format shown in the following example and the parameters listed in the following table.
Following is an example policy that allows access to the game_download.zip object if the end user's IP address is within the 145.168.143.0/24 IP address range, and if the end user's request for the object comes in before 11/14/2009 at 10:20 p.m. (specified in epoch time in seconds).
Example Policy Custom Policy
{
"Statement": [{
"Resource":"http://d604721fxaaqy9.cloudfront.net/game_download.zip",
"Condition":{
"IpAddress":{"AWS:SourceIp":"145.168.143.0/24"},
"DateLessThan":{"AWS:EpochTime":1258237200}
}
}]
}![]() | Note |
|---|---|
If you're familiar with Amazon S3 browser-based POSTs, the policy format you use there differs from the policy format you use here for CloudFront private objects. If you're familiar with Amazon SQS access control, you might be familiar with the access policy language Amazon SQS uses. CloudFront uses the same format for its policies, but limits how you can use the language to only the specific cases shown here. |
The following table describes the parameters you can specify in the policy.
| Parameter | Description | Required |
|---|---|---|
|
|
The URL to the cached object itself. This is the CloudFront URL (using the CloudFront domain name), not the URL to the object in the Amazon S3 bucket. The value must include the Omitting this parameter gives the end user access to all the objects belonging to any distribution associated with the key pair used to sign the URL. |
Optional |
|
|
This is the only required parameter. It specifies an
expiration date and time for the URL, using the format
|
Required |
|
|
Specifies an optional start date and time for the URL,
using the format
| Optional |
|
|
Specifies the IP address of the client making the GET
request, using the format
It must be in the standard CIDR format (for example, 10.52.176.0/24). For more information, go to RFC 4632. You can specify only a single value for the condition. For example, you can't set up the policy to allow access if the client's IP address is in one of two different ranges. To allow access to all IP addresses, omit this parameter. |
Optional |
The parameter names must be specified in the policy exactly as shown in the
preceding table (no abbreviations like datelt for
DateLessThan are accepted). The order of the parameters in the
policy doesn't matter. Make sure you specify the conditions
(DateLessthan, DateGreaterThan, and
IpAddress) as part of the Condition section in the
policy.
The square brackets that enclose the statement's contents (as shown in the preceding example policy) are required for the policy to be considered valid.
For additional policy examples, see Signed URL Examples.
You calculate the Signature query parameter using an
RSA-SHA1 digital signature of the raw policy (the policy must be in UTF-8 format
before signing).
Signature (RawPolicy) = RSA_Sign(SHA1, RawPolicy, PrivateKey)
![]() | Important |
|---|---|
CloudFront uses an RSA-SHA1 signature, and not an HMAC-SHA1 signature, which is the type Amazon S3 and many other AWS products use. A common mistake is to implement HMAC-SHA1 instead of an RSA-SHA1 in your code for creating signatures for private content. |
No special canonicalization of the policy is required. Signing the policy is straightforward and extensible, should we add additional policy conditions that you can use.
Use the following translation to make the policy and the signature URL safe.
Url-Safe (m) = CharReplace( Base64(m), "+=/", "-_~" )
This section gives example signatures based on example credentials and policies.
The examples in this section use the (non-working) credentials in the following table.
![]() | Tip |
|---|---|
To make it easier to test your own code, you can get a soft copy of the example credentials (zipped up in the CloudFront_PrivateContent_SignatureExamples.zip file). |
| Credential | Value |
|---|---|
|
Public Key |
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA7ki9gI/lRygIoOjV1yymgx6F YFlzJ+z1ATMaLo57nL57AavWhb68HYY8EA0GJU9xQdMVaHBogF3eiCWYXSUZCWM/ +M5+ZcdQraRRScucmn6g4EvY2K4W2pxbqH8vmUikPxir41EeBPLjMOzKvbzzQy9e /zzIQVREKSp/7y1mywIDAQAB -----END PUBLIC KEY----- |
|
Private Key |
-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDA7ki9gI/lRygIoOjV1yymgx6FYFlzJ+z1ATMaLo57nL57AavW hb68HYY8EA0GJU9xQdMVaHBogF3eiCWYXSUZCWM/+M5+ZcdQraRRScucmn6g4EvY 2K4W2pxbqH8vmUikPxir41EeBPLjMOzKvbzzQy9e/zzIQVREKSp/7y1mywIDAQAB AoGABc7mp7XYHynuPZxChjWNJZIq+A73gm0ASDv6At7F8Vi9r0xUlQe/v0AQS3yc N8QlyR4XMbzMLYk3yjxFDXo4ZKQtOGzLGteCU2srANiLv26/imXA8FVidZftTAtL viWQZBVPTeYIA69ATUYPEq0a5u5wjGyUOij9OWyuy01mbPkCQQDluYoNpPOekQ0Z WrPgJ5rxc8f6zG37ZVoDBiexqtVShIF5W3xYuWhW5kYb0hliYfkq15cS7t9m95h3 1QJf/xI/AkEA1v9l/WN1a1N3rOK4VGoCokx7kR2SyTMSbZgF9IWJNOugR/WZw7HT njipO3c9dy1Ms9pUKwUF46d7049ck8HwdQJARgrSKuLWXMyBH+/l1Dx/I4tXuAJI rlPyo+VmiOc7b5NzHptkSHEPfR9s1OK0VqjknclqCJ3Ig86OMEtEFBzjZQJBAKYz 470hcPkaGk7tKYAgP48FvxRsnzeooptURW5E+M+PQ2W9iDPPOX9739+Xi02hGEWF B0IGbQoTRFdE4VVcPK0CQQCeS84lODlC0Y2BZv2JxW3Osv/WkUQ4dslfAQl1T303 7uwwr7XTroMv8dIFQIPreoPhRKmd/SbJzbiKfS/4QDhU -----END RSA PRIVATE KEY----- |
|
Key-Pair-Id |
PK123456789754 |
Using the OpenSSL package, you can calculate the query parameters as shown in the following examples. For information about OpenSSL, go to http://www.openssl.org.
The following command creates the URL-safe Policy
value.
% cat policy | openssl base64 | tr '+=/' '-_~'
The following command creates the URL-safe Signature
value.
% cat policy | openssl sha1 -sign private-key.pem | openssl base64 | tr '+=/' '-_~'
Example Canned Policy
This example gives any end user holding the URL access to http://d604721fxaaqy9.cloudfront.net/horizon.jpg before Sat, 14
Nov 2009 22:20:00 GMT.
Following is the original URL.
http://d604721fxaaqy9.cloudfront.net/horizon.jpg?large=yes&license=yes
Following is the policy to sign (if you copy and paste it, make sure to remove any white space or line feeds).
{"Statement":[{"Resource":"http://d604721fxaaqy9.cloudfront.net/horizon.jpg?large=yes&license=yes","Condition":{"DateLessThan":{"AWS:EpochTime":1258237200}}}]}Following is the URL-safe signature.
Signature = Nql641NHEUkUaXQHZINK1FZ~SYeUSoBJMxjdgqrzIdzV2gyEXPDNv0pYdWJkflDKJ3xIu7lbwRpSkG98NBlgPi4ZJpRRnVX4kXAJK6tdNx6FucDB7OVqzcxkxHsGFd8VCG1BkC-Afh9~lOCMIYHIaiOB6~5jt9w2EOwi6sIIqrg_
Following is the full URL for the end user.
http://d604721fxaaqy9.cloudfront.net/horizon.jpg?large=yes&license=yes&Expires=1258237200&Signature=Nql641NHEUkUaXQHZINK1FZ~SYeUSoBJMxjdgqrzIdzV2gyEXPDNv0pYdWJkflDKJ3xIu7lbwRpSkG98NBlgPi4ZJpRRnVX4kXAJK6tdNx6FucDB7OVqzcxkxHsGFd8VCG1BkC-Afh9~lOCMIYHIaiOB6~5jt9w2EOwi6sIIqrg_&Key-Pair-Id=PK123456789754
Example Custom Policy 1
The following custom policy grants the network 145.168.143.0/24 access to all
the objects in the training directory before Sat, 14 Nov
2009 22:20:00 GMT.
Following is the original URL. It specifies a particular object (training/orientation.avi), even though the policy covers multiple objects.
http://d604721fxaaqy9.cloudfront.net/training/orientation.avi
Following is the raw policy to sign.
![]() | Tip |
|---|---|
To make it easier to test your own code, you can get a soft copy of the following policy (zipped up in the CloudFront_PrivateContent_SignatureExamples.zip file). Note that the string used to calculate the signature includes the white space and line feeds shown in the policy. |
RawPolicy =
{
"Statement": [{
"Resource":"http://d604721fxaaqy9.cloudfront.net/training/*",
"Condition":{
"IpAddress":{"AWS:SourceIp":"145.168.143.0/24"},
"DateLessThan":{"AWS:EpochTime":1258237200}
}
}]
}Following is the URL-safe policy.
Policy = eyAKICAgIlN0YXRlbWVudCI6IFt7IAogICAgICAiUmVzb3VyY2UiOiJodHRwOi8vZDYwNDcyMWZ4YWFxeTkuY2xvdWRmcm9udC5uZXQvdHJhaW5pbmcvKiIsIAogICAgICAiQ29uZGl0aW9uIjp7IAogICAgICAgICAiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjE0NS4xNjguMTQzLjAvMjQifSwgCiAgICAgICAgICJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI1ODIzNzIwMH0gICAgICAKICAgICAgfSAKICAgfV0gCn0K
Following is the URL-safe signature.
Signature = cPFtRKvUfYNYmxek6ZNs6vgKEZP6G3Cb4cyVt~FjqbHOnMdxdT7eT6pYmhHYzuDsFH4Jpsctke2Ux6PCXcKxUcTIm8SO4b29~1QvhMl-CIojki3Hd3~Unxjw7Cpo1qRjtvrimW0DPZBZYHFZtiZXsaPt87yBP9GWnTQoaVysMxQ_
Following is the full URL for the end user.
http://d604721fxaaqy9.cloudfront.net/training/orientation.avi?Policy=eyAKICAgIlN0YXRlbWVudCI6IFt7IAogICAgICAiUmVzb3VyY2UiOiJodHRwOi8vZDYwNDcyMWZ4YWFxeTkuY2xvdWRmcm9udC5uZXQvdHJhaW5pbmcvKiIsIAogICAgICAiQ29uZGl0aW9uIjp7IAogICAgICAgICAiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjE0NS4xNjguMTQzLjAvMjQifSwgCiAgICAgICAgICJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI1ODIzNzIwMH0gICAgICAKICAgICAgfSAKICAgfV0gCn0K&Signature=cPFtRKvUfYNYmxek6ZNs6vgKEZP6G3Cb4cyVt~FjqbHOnMdxdT7eT6pYmhHYzuDsFH4Jpsctke2Ux6PCXcKxUcTIm8SO4b29~1QvhMl-CIojki3Hd3~Unxjw7Cpo1qRjtvrimW0DPZBZYHFZtiZXsaPt87yBP9GWnTQoaVysMxQ_&Key-Pair-Id=PK123456789754
Example Custom Policy 2
The following custom policy grants the IP address 216.98.35.1/32 access to all the objects belonging to any distribution that the specified key pair ID is associated with. The objects are available only between Thu, 30 Apr 2009 06:43:10 GMT and Fri, 16 Oct 2009 06:31:56 GMT.
Following is the original URL. It specifies a particular object (downloads/pictures.tgz), even though the policy covers potentially many.
http://d84l721fxaaqy9.cloudfront.net/downloads/pictures.tgz
Following is the raw policy to sign.
![]() | Tip |
|---|---|
To make it easier to test your own code, you can get a soft copy of the following policy (zipped up in the CloudFront_PrivateContent_SignatureExamples.zip file). Note that the string used to calculate the signature includes the white space and line feeds shown in the policy. |
RawPolicy =
{
"Statement": [{
"Resource":"http://*",
"Condition":{
"IpAddress":{"AWS:SourceIp":"216.98.35.1/32"},
"DateGreaterThan":{"AWS:EpochTime":1241073790},
"DateLessThan":{"AWS:EpochTime":1255674716}
}
}]
}Following is the URL-safe policy.
Policy = eyAKICAgIlN0YXRlbWVudCI6IFt7IAogICAgICAiUmVzb3VyY2UiOiJodHRwOi8vKiIsIAogICAgICAiQ29uZGl0aW9uIjp7IAogICAgICAgICAiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjIxNi45OC4zNS4xLzMyIn0sCiAgICAgICAgICJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI0MTA3Mzc5MH0sCiAgICAgICAgICJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI1NTY3NDcxNn0KICAgICAgfSAKICAgfV0gCn0K
Following is the URL-safe signature.
Signature = rc~5Qbbm8EJXjUTQ6Cn0LAxR72g1DOPrTmdtfbWVVgQNw0q~KHUAmBa2Zv1Wjj8dDET4XSL~Myh44CLQdu4dOH~N9huH7QfPSR~O4tIOS1WWcP~2JmtVPoQyLlEc8YHRCuN3nVNZJ0m4EZcXXNAS-0x6Zco2SYx~hywTRxWR~5Q_
Following is the full URL for the end user.
http://d84l721fxaaqy9.cloudfront.net/downloads/pictures.tgz?Policy=eyAKICAgIlN0YXRlbWVudCI6IFt7IAogICAgICAiUmVzb3VyY2UiOiJodHRwOi8vKiIsIAogICAgICAiQ29uZGl0aW9uIjp7IAogICAgICAgICAiSXBBZGRyZXNzIjp7IkFXUzpTb3VyY2VJcCI6IjIxNi45OC4zNS4xLzMyIn0sCiAgICAgICAgICJEYXRlR3JlYXRlclRoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI0MTA3Mzc5MH0sCiAgICAgICAgICJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTI1NTY3NDcxNn0KICAgICAgfSAKICAgfV0gCn0K&Signature=rc~5Qbbm8EJXjUTQ6Cn0LAxR72g1DOPrTmdtfbWVVgQNw0q~KHUAmBa2Zv1Wjj8dDET4XSL~Myh44CLQdu4dOH~N9huH7QfPSR~O4tIOS1WWcP~2JmtVPoQyLlEc8YHRCuN3nVNZJ0m4EZcXXNAS-0x6Zco2SYx~hywTRxWR~5Q_&Key-Pair-Id=PK123456789754
To help you correctly generate your signatures, we've provided a tool called
cfsign.pl that you can use to create and decode signed
URLs. To get the tool, go to Amazon CloudFront Signed URLs Helper Tool.