Skip to main content

Signing S3 HTTP upload policies via the command line

· 2 min read

When creating HTTP web forms to allow browser-based uploads to an S3 bucket, you need to create and sign upload policies. Now if that statement lost you, then you should read over either of the following introductions to browser-based uploads to S3:

Now, creating an upload policy is quite straight forward, and covered in both links above. However, part of the process requires you to also sign the policy with your AWS secret key. This can be done many ways (indeed, the second link about shows examples for Ruby, Java and Python), but I wanted to be able to sign policies from the command line. This, it turns out, is quite easy using a recent version of OpenSSL. It's done like this:

base64 -w0 policy.txt |
openssl dgst -sha1 -hmac <KEY> -binary |
openssl base64

Easy, huh? Well, it did take me a little while to get the binary / base64 encodings just right. Also, the all important -hmac flag requires a recent version of openssl (0.9.8j is fine, but 0.9.8a is not).

So, here's an example using the policy document shown in the Amazon Simple Storage Service: Browser-Based Uploads using POST Proposal post.

~]$ cat policy.txt
{ "expiration": "2007-12-01T12:00:00.000Z",
"conditions": [
{"bucket": "johnsmith" },
["starts-with", "$key", "user/eric/"],
{"acl": "public-read" },
{"redirect": "http://johnsmith.s3.amazonaws.com/successful_upload.html" },
["starts-with", "$Content-Type", "image/"],
{"x-amz-meta-uuid": "14365123651274"},
["starts-with", "$x-amz-meta-tag", ""],
]
}
~]$ base64 -w0 policy.txt
eyAiZXhwaXJhdGlvbiI...<snip>...ICIiXSwKICBdCn0K
~]$ base64 -w0 policy.txt | openssl dgst -sha1 -hmac 'uV3F3YluFJax1cknvbcGwgjvx4QpvB+leU8dUj2o' -binary | openssl base64
2qCp0odXe7A9IYyUVqn0w2adtCA=
~]$

This process produces the exact same base64-encoded policy and policy signature that the original example arrived at - which is reassuring ;)