Question

I've written the following code to sign URLS using boto, however, I'm unable to access the signed URLS. Any help would be greatly appreciated.

con = cloudfront.CloudFrontConnection(
    settings.AWS_USER_DETAILS.access_key_id,
    settings.AWS_USER_DETAILS.secret_key_id,
)

identities = con.get_all_origin_access_identity()

if len(identities) < 1:
    oai = con.create_origin_access_identity(
        'cv-oai',
        'OAI signing iOS video requests'
    )
else:
    oai = con.get_all_origin_access_identity()[0]

distro_summary = con.get_all_distributions()[0]
distro_info = con.get_distribution_info(distro_summary.id)

bucket = boto.connect_s3(
    settings.AWS_USER_DETAILS.access_key_id,
    settings.AWS_USER_DETAILS.secret_key_id,
    host='s3-eu-west-1.amazonaws.com'
).get_bucket(u'cv-video')

key_str = video.video_url.split('/')[-1]
key = bucket.get_key(key_str)

key.add_user_grant("READ", oai.s3_user_id)

distro = distro_summary.get_distribution()

# For local testing
if ip_addr == '127.0.0.1':
    ip_addr = None

private_key_string = open(settings.CF_PRIV_KEY_LOC).read()
print private_key_string

signed_url = distro.create_signed_url(
    "https://%s/%s" % (distro_info.domain_name, key_str),
    'APKAI3I3QZ7I73OIQIXA',
    expire_time=int(time.time()) + video.video_length + 5 * 60,
    #valid_after_time=None,
    #ip_address=ip_addr,
    #policy_url=None,
    private_key_string=private_key_string
)

Error:

Update: This is the error received when visiting the URLs generated by the above code. I am unable to find documentation of the CloudFront errors to determine why this might be happening.

<Error>
<Code>InvalidKey</Code>
<Message>Unknown Key</Message>
</Error>

Example URL:

https://d1xvt07pr26drp.cloudfront.net/2iwjz3wn9atqlfw4.mov?Expires=1388705061&Signature=auPWW-X1LzZJkPxJ5YPCqQMatchbAb3BxCWTG5oMY78G6LrH0sZiQL6EKdCX-l3Fi9E475b11uFL~HnxfBUY9QqQH86478QU5BnpmR-U7uEikRs7kTDWOVj4Riv3PHUmjmzlBW8xU7-n9C0m2UZSXedPsYYFdPoWHH0VLlyKk2TzgYydLqu~jtq0iNdmz-C9TOgUCaICiMYi082AVc7bt6xTfVszA9BeAD4KLKnr42raFDLojbA78Q-7bLNA2CiStdT-8BblQOQ5IXUCxYdkw7ak0vp77vER1pCG9cEBkCHD~9dZccyQEGJApO~ax4D5wDtCpeQj3l0pW6kYNUlP8Q__&Key-Pair-Id=APKAI3I3QZ7I73OIQIXA

The key pair is definitely active:

Key Pair is active

There is only one Origin Access Identity and one distribution:

[<boto.cloudfront.identity.OriginAccessIdentitySummary object at 0x10f356110>]
[<boto.cloudfront.distribution.DistributionSummary object at 0x10f356090>]
Was it helpful?

Solution

I had the same issue.

I wondered if couldfront and s3 had not yet been connected logically to the "origin access identity." This is the identity that cloudfront uses to pull content from S3, verifying signatures with the private key pair you specified.

Sure enough, that was the problem. Disable public access to the underlying S3 bucket, then tell AWS to use the appropriate identity, then try your code again.

Here's how from the Web:

From the CloudFront dashboard (https://console.aws.amazon.com/cloudfront/home), click on "Distribution" on the left to see all your distros. Select the one you want, clicking the [i] icon for more information. From there, click on the [Origins] tab and select the radio button next to your bucket. Click it, and an Edit button will appear. Click Edit. Choose "Restrict Bucket Access" in the new panel that appears. The site will prompt you for which access identity to do. Choose the identity you created. Click "Yes, Edit" to save your changes.

Good luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top