Cool trick: time-bombed URLs to an S3 object

Here’s a cool trick you can do with S3: you can generate a URL with an “expires” timestamp that will only be good until that timestamp.
Although there are a number of potential uses for this, I generally do it instead of emailing attachments; many enterprises still impose ridiculously low limits on their employee email accounts (I’m talking like 100MB total), which can quickly be sucked up by large email attachments.

Right now there’s no way to do this from the CLI, but it’s really easy to do in a Python script.

#!/usr/bin/env python

# Create a time-bombed URL from an S3 object
# Parameters: s3_url [timeout]
# timeout defaults to 1 minute if not specified
# requires the boto module</em>

# 2014 Staunch Technologies, LLC
# See http://www.staunchtech.com/?page_id=53 for licensing information

import sys,re

try:
testArg=re.match('s3:\/\/',sys.argv[1])
except:
print ("usage: " + sys.argv[0] + " s3_object ttl_in_sec")
sys.exit(1)
if not testArg:
print "need a valid s3 object as arg"
sys.exit(1)

try:
sys.argv[2]
expTime=int(sys.argv[2])
except:
expTime=60

(bucket,key)=re.split('/',re.sub('^s3:\/\/','',sys.argv[1]),maxsplit=1)

testKey=re.match('\w',key)
if not testKey:
print ("something wrong with this url - I have a key of: " + key + " - bailing")
sys.exit(1)

from boto.s3.connection import S3Connection
# If you're intending to hardcode your credentials rather than have them as variables then you would replace this line with:
# s3=S3Connection('your_aws_key','your_aws_secret')
s3=S3Connection()
url = s3.generate_url(expTime, 'GET', bucket=bucket, key=key)
print ("Generating URL, good for " + str(expTime) + " seconds")
print (url)

Note that the majority of the script is just validation – the magic actually takes place in the last 5 lines or so.
So, if you run this script with parameters of “s3://your-bucket/objectname 3600″ then it will generate a signed URL to download s3://your-bucket/objectname that’s good for an hour. Note that s3://your-bucket/objectname does NOT have to be public for this to work (in fact, if it were public then we wouldn’t need this script in the first place!)

Hope this proves useful to you!