Yeah I think this would be a great feature. I'm thinking this would be a new s3 subcommand? I've been working on some internal changes to the s3 command code to make it easier to add subcommands. I've been using this to start to refactor the ls
command to fix several of the reported issues with ls
.
Not entirely done yet, but here's what I have so far:
https://github.com/jamesls/aws-cli/compare/s3-ls-permissions#diff-b88a66f4bd148577a9390cb980d7eeb9R321
Yes, this I was looking for. Please, allow to specify expiration not only by duration, but also by a specific datetime. Requiring UTC timezone, ISO format, full seconds, the string ending with "Z" seems to me well usable (e.g. "2014-05-30T00:00:00Z").
In case, you really need to generate tmpurl from command line, I could recommend my command line tool s3tmpgen
Anyway, I would really invite such functionality in AWS CLI, which became valuable tool for my daily work with AWS S3.
+1
+1
I'm looking to use S3 to host code bundles to deployed to Heroku and this would be an awesome feature :)
https://blog.heroku.com/archives/2014/5/22/introducing_the_app_json_application_manifest
+1
+1 would be great to have this in AWS CLI
Just a note for anyone who ends up here, you can do this yourself trivially by reaching down into the boto
library: https://boto.readthedocs.org/en/latest/ref/s3.html#boto.s3.key.Key.generate_url
Thanks for the feedback. I'll take a look at this, I agree that this would be a great feature to add to the AWS CLI.
Thanks, @johnboxall. Boto is certainly an option, though for folks deploying the cli binary without native Python deployments (think Windows users), going that route is just as much work as pulling down the PowerShell SDK and doing things via the .NET SDK. Would still like to see this native in the CLI. :grin:
Just for anyone looking to use boto directly for now until this is added to aws-cli I figured I would add a quick sample instruction. I've now went looking for this a couple of times and would rather have it along with this ticket and @johnboxall comment. This may be extremely obvious for some, but not for non-python devs
On a box which already has python installed
$ python --version
Python 2.7.6
$ sudo pip install boto
$ python
>>> import boto
>>> s3 = boto.connect_s3()
>>> bucket = s3.get_bucket('your-bucket-name')
>>> key = bucket.get_key('the-prefix/the-name-of-the-object.mp4')
>>> key.generate_url(3600)
'https://your-bucket-name.s3.amazonaws.com/the-prefix/the-name-of-the-object.mp4?Signature=CgDfFa45DBXFiMfASxSTpiSuHKM%3D&Expires=1415913273&AWSAccessKeyId=ABCDEDKSY344ACVDG'
Building on @isleshocky77's example... adding arguments and minor error checking:
$ cat boto-get-signed-url.py
#!/usr/bin/python
import boto
import argparse
parser = argparse.ArgumentParser(description='Generate an S3 signed URL')
parser.add_argument('-b', '--bucket', help='bucket name')
parser.add_argument('-k', '--key', help='prefix/key')
parser.add_argument('-s', '--seconds', type=int, help='time in seconds until the URL will expire')
args = parser.parse_args()
s3 = boto.connect_s3()
bucket = s3.get_bucket(args.bucket)
key = bucket.get_key(args.key)
if bucket.get_key(args.key):
print key.generate_url(args.seconds)
else:
print 's3://' + args.bucket + '/' + args.key + ' does not exist'
$ ./boto-get-signed-url.py -b superbucket -k "test" -s 60
https://superbucket.s3.amazonaws.com/test?Signature=n6cO8RH%2FbNwQhuZVNNazo3q04x0%3D&Expires=1416695021&AWSAccessKeyId=AKIEXAMPLEKEYNOTREAL
$ boto-get-signed-url.py --help
usage: boto-get-signed-url.py [-h] [-b BUCKET] [-k KEY] [-s SECONDS]
Generate an S3 signed URL
optional arguments:
-h, --help show this help message and exit
-b BUCKET, --bucket BUCKET
bucket name
-k KEY, --key KEY prefix/key
-s SECONDS, --seconds SECONDS
time in seconds until the URL will expire
Hi all
After another check about status of this issue I made an update to Python package ttr.aws.utils.s3 providing the tool s3tmpgen. The update allows to generate the url not only using https, but (with option an -http
) also http.
Still looking forward to replace this with awscli solution.
:+1:
+1 for s3 signed url to be part of cli
:+1:
+1
I think, I understand, why it takes so long time: things must happen in order and good thing is, it looks like being on the roadmap.
As AWS CLI is based on botocore
, it shall be resolved there first. boto/botocore#291 is asking for it.
Pull request boto/botocore#504 was already merged into branch clients-only
and roadmap (mentioned on README at https://github.com/boto/botocore ) claims, botocore is currently just one step before merging the branch clients-only
into develop (then beta, GA and AWS CLI has "native" tool to provide give functionality for us).
@vlcinsky
Yep once the clients-only branch gets merged into botocore, we will be able to pick up the generation of signed url's in the CLI. Then, the main amount of work that would have to be done on the CLI side is to create a good API that exposes the feature.
https://github.com/boto/botocore/issues/291 was already closed on 23 Jun: "The feature is currently available in botocore."
:+1: would be a handy feature indeed
+1
As @kyleknap noted, one of things to do is to design good API for this feature.
I see following use cases:
The "tmpGET" is really easy as the only output is url and the only input is bucket/key and expiration
date (expiration time).
The "tmpPOST" is much more complex as one has to define a policy for posting.
One question to resolve is, where to put these actions, there seem to be two alternatives:
aws s3
aws s3api
I will not deal today with the more complex "tmpPOST" and will focus on simpler "tmpGET"
aws s3 tmpurl
Such a solution would be rather easy to implement, would help in 80% of real
use situations (publish an object to AWS S3 and provide temporary url to share
with someone).
The concept would build on existing aws s3 ls
with following differences:
--expires
to define date and time at which the url expires or --expires-in
toI am afraid, there is currently no easy way to create tmp url for exact moment in time, so initial
version would offer only the --expires-in
option with default value of 3600 seconds.
It is very easy to create bunch of tmp urls for number of existing objects on AWS S3. It saves the
hurdle with getting exact bucket/key name values.
Disadvantage of this aws s3 ls
based approach is, one cannot create tmp url for an object, which
does not exist yet.
Anyway, this could be resolved later on by aws s3api
solution.
Very nicely put there. Whereas a post is something that would almost certainly be built around some server side handling of the posted data, the get method use cases are usually quite a lot easier. When you say that would cover most use cases, I would strongly agree.
I meant to add though, I don't think the temp URL should have anything to do with locating the files on s3. If somebody wants to generate entire sets of signed URLs, that's logic the cli doesn't need to do more to wrap. The tmpurl primitive is the minimum viable product in my mind .
I've implemented(not fully) pre-sgined URL for s3 objects in my local branch.
https://github.com/quiver/aws-cli/tree/s3-presigned-url
This is a thin-wrapper for botocore.generate_presigned_url
, and it's not production ready yet. As @vlcinsky noted, we need a good API design as AWSCLI
. Once that's fixed I can implement that.
One thing I note is that generate_presigned_url
requires client_method
parameter, which specifies S3 API(e.g. get_object
) to sign for. In my current implementation, it's exposed to the user, but it would be better to be user-friendly, like providing different sub-commands(aws s3 geturl
, aws s3 uploadurl
) or switch options(--type upload
)
$ echo hello world > test.txt
$ aws s3 url s3://BUCKET/test.txt --client-method put_object --expires-in 180
https://BUCKET.s3.amazonaws.com/test.txt?AWSAccessKeyId=AKIAIXXXXXXXXXXXXXXX&Expires=1451449621&Signature=KgwO9lBx942fFvln0JW0NX7mKS0%3D
$ URL=`aws s3 url s3://BUCKET/test.txt --client-method put_object --expires-in 180`
$ curl -D - -X PUT --upload-file test.txt $URL
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
x-amz-id-2: /90B1axPysBg3P8kv8BlR8RoqdO1JfajCN5BM5/TxIT3VjGphKmyGX8EgCQEtCXYhuNkVne5+GM=
x-amz-request-id: 685F03CA6C84FAC0
Date: Wed, 30 Dec 2015 05:18:38 GMT
ETag: "6f5902ac237024bdd0c176cb93063dc4"
Content-Length: 0
Server: AmazonS3
$ aws s3 cp s3://BUCKET/test.txt -
hello world
$ URL=`aws s3 url s3://BUCKET/test.txt --client-method get_object --expires-in 180`
$ curl -D - -X GET $URL
HTTP/1.1 200 OK
x-amz-id-2: WuRokcBm9wnDMaRkD8kNeGijuKEzVp3eagi7JbpPXmmchEljsiP4wZX5w1TaeuK94n2526FGKMI=
x-amz-request-id: 1EBCAA7A691A577D
Date: Wed, 30 Dec 2015 05:20:14 GMT
Last-Modified: Wed, 30 Dec 2015 05:19:15 GMT
ETag: "6f5902ac237024bdd0c176cb93063dc4"
Accept-Ranges: bytes
Content-Type: binary/octet-stream
Content-Length: 12
Server: AmazonS3
hello world
The above python generates a url like: 'https://
When I attempt to curl the file, I get SSL certificate problem: Invalid certificate chain
If I curl with option -k, I can get past this, but I also know that if the url looks like: 'https://s3-
the cert is valid, is there a way to change the url, or some other fix?
Thanks,
Garry
eg: 'https://s3-us-west-1.amazonaws.com/bucket/dir/dir/file'
Update, using boto3 was able to generate the correctly signed url.
+1
Impressive - in 3 years official CLI tool did not get support for signed url implemented, allthough it exists in boto and s3cmd
1+
+1
+1
Any update on this? Surprised this isn't available yet.
+1
I wrote one up as a workaround and works as expected: https://github.com/gdbtek/aws-tools
Hi everyone, thanks for the feedback. This something that is on our backlog. I don't have exact dates yet, but I'll link to this issue once we have a pull request up.
Great! Thanx!
Is it possible to get a presigned url to an entire s3 folder? Including a web interface to navigate through the folder?
@tommeda Not possible. pre-signed url is always related to single stored object. What you talk about is similar to static web site but to control access to it (if based on AWS S3), one has to write some proxy. Few attempts already exists, none seemed to me (researched about a year ago) easy peasy.
You could always generate a webpage that provided an interface to and included pre signed urls for each object, and then put the interface into s3 and return a pre signed url to the interface. Not exactly easy peasy, and the interface would like be usage specific
Most helpful comment
Impressive - in 3 years official CLI tool did not get support for signed url implemented, allthough it exists in boto and s3cmd