A Presigned URL in S3 allows temporary access to an object in storage without the need to change the object's access permissions. It is a convenient tool for downloading files by third-party users. In this article, we will look at how to create a Presigned URL in two ways: in the Hostman control panel or via AWS CLI.
Presigned URL generation is only available for private buckets. To generate a Presigned URL:
The link will be copied to the clipboard and will remain active for 60 minutes. After this time, an attempt to follow the link will return a 403 error. The control panel does not allow changing the duration for which the link remains active.
You can also generate a link for a specific object version if versioning is enabled on the bucket. To do this, open the object’s Version history and click File link next to the desired version.
You can create a Presigned URL using AWS CLI with the following command:
aws s3 presign s3://<bucket>/<object> --expires-in 60 --endpoint-url https://s3.hostman.com
The --expires-in
parameter is optional. It defines how long the object will be available via the link (in seconds). If the parameter is not specified, the object will be available for 3600 seconds (1 hour).
Standard utilities do not support generating a presigned URL for a version other than the current one. To create a link for a specific object version, you can use custom scripts. For example, the following Python script can be used:
#!/usr/bin/env python3
import argparse
import boto3
parser = argparse.ArgumentParser()
parser.add_argument('--bucket', required=True)
parser.add_argument('--key', required=True)
parser.add_argument('--expires-in', type=int, default=3600)
parser.add_argument('--version-id')
parser.add_argument('--method', default='get_object')
args = parser.parse_args()
client = boto3.client('s3', endpoint_url='https://s3.hostman.com')
params = {'Bucket': args.bucket, 'Key': args.key}
if args.version_id:
params.update({'VersionId': args.version_id})
url = client.generate_presigned_url(args.method, Params=params, ExpiresIn=args.expires_in)
print(url)
Run the script with:
python ./main.py --bucket <bucket-name> --key <object-key> --expires-in 6969 --version-id <object-version>
Where:
--expires
-in is time in seconds until the link expires.--version-id
is the object version (VersionId), which can be obtained, for example, via AWS CLI.The script will take authentication credentials from ~/.aws/credentials
.
You can pre-generate a presigned URL for uploading an object, even if the object does not yet exist in the bucket. Standard utilities like AWS CLI do not support this, but it can be done via an SDK, such as boto3
for Python.
Example script:
import boto3
from botocore.client import Config
# Enter your credentials
AWS_ACCESS_KEY_ID = 'S3 Access Key'
AWS_SECRET_ACCESS_KEY = 'S3 Secret Access Key'
BUCKET_NAME = 'Bucket Name'
OBJECT_KEY = 'example.txt' # name of the future object
EXPIRES_IN = 3600 # link expiration time in seconds
s3 = boto3.client(
's3',
endpoint_url='https://s3.hostman.com',
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY,
config=Config(signature_version='s3v4'),
region_name='us-2'
)
# Generate presigned URL
url = s3.generate_presigned_url(
ClientMethod='put_object',
Params={
'Bucket': BUCKET_NAME,
'Key': OBJECT_KEY,
},
ExpiresIn=EXPIRES_IN
)
print(url)
Note: You do not need to specify Content-Type
when generating the link, as including it may cause an error.
After running the script, a temporary upload link will be generated.
You can upload a file using curl
:
curl -X PUT -T /path/to/file.txt -H "Content-Type: text/plain" "<presigned-url-from-script>"