

# Download and upload objects with presigned URLs
<a name="using-presigned-url"></a>

You can use presigned URLs to grant time-limited access to objects in Amazon S3 without updating your bucket policy. A presigned URL can be entered in a browser or used by a program to download an object. The credentials used by the presigned URL are those of the AWS Identity and Access Management (IAM) principal who generated the URL.

You can also use presigned URLs to allow someone to upload a specific object to your Amazon S3 bucket. This allows an upload without requiring another party to have AWS security credentials or permissions. If an object with the same key already exists in the bucket as specified in the presigned URL, Amazon S3 replaces the existing object with the uploaded object.

You can use the presigned URL multiple times, up to the expiration date and time.

When you create a presigned URL, you must provide your security credentials, and then specify the following: 
+ An Amazon S3 bucket
+ An object key (if downloading this object will be in your Amazon S3 bucket, if uploading this is the file name to be uploaded)
+ An HTTP method (`GET` for downloading objects, `PUT` for uploading, `HEAD` for reading object metadata, etc)
+ An expiration time interval

When using presigned URLs to upload objects, you can verify object integrity using checksums. While presigned URLs created with AWS Signature Version 2 only support MD5 checksums, presigned URLs created with AWS Signature Version 4 support additional checksum algorithms including CRC-64/NVME, CRC32, CRC32C, SHA-1, and SHA-256. To use these additional checksum algorithms, ensure you're using AWS Signature Version 4 and include the appropriate checksum header in your upload request. For more information about object integrity, see [Checking object integrity in Amazon S3](checking-object-integrity.md).

**Topics**
+ [

## Who can create a presigned URL
](#who-presigned-url)
+ [

## Expiration time for presigned URLs
](#PresignedUrl-Expiration)
+ [

## Limiting presigned URL capabilities
](#PresignedUrlUploadObject-LimitCapabilities)
+ [

## Frequently asked questions for presigned URLs
](#PresignedUrlFAQ)
+ [

# Sharing objects with presigned URLs
](ShareObjectPreSignedURL.md)
+ [

# Uploading objects with presigned URLs
](PresignedUrlUploadObject.md)

## Who can create a presigned URL
<a name="who-presigned-url"></a>

Anyone with valid security credentials can create a presigned URL. But for someone to successfully access an object, the presigned URL must be created by someone who has permission to perform the operation that the presigned URL is based upon.

The following are the types of credentials that you can use to create a presigned URL:
+ **IAM user** – Valid up to 7 days when you're using AWS Signature Version 4.

  To create a presigned URL that's valid for up to 7 days, first delegate IAM user credentials (the access key and secret key) to the method you're using to create the presigned URL.
+ **Temporary security credentials** – Can't be valid for longer than the credentials themselves. These credentials include:
  + **IAM role credentials** – The presigned URL expires when the role session expires, even if you specify a longer expiration time.
  + **IAM role credentials used by Amazon EC2 instances** – Valid for the duration of the role credentials (typically 6 hours).
  + **AWS Security Token Service credentials** – Valid only for the duration of the temporary credentials.

**Note**  
If you created a presigned URL using a temporary credential, the URL expires when the credential expires. In general, a presigned URL expires when the credential you used to create it is revoked, deleted, or deactivated. This is true even if the URL was created with a later expiration time. For temporary security credentials lifetimes, see [Comparing AWS STS API operations](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html#stsapi_comparison) in the *IAM User Guide*.

## Expiration time for presigned URLs
<a name="PresignedUrl-Expiration"></a>

A presigned URL remains valid for the period of time specified when the URL is generated. If you create a presigned URL with the Amazon S3 console, the expiration time can be set between 1 minute and 12 hours. If you use the AWS CLI or AWS SDKs, the expiration time can be set as high as 7 days.

If you created a presigned URL by using a temporary token, then the URL expires when the token expires. In general, a presigned URL expires when the credential you used to create it is revoked, deleted, or deactivated. This is true even if the URL was created with a later expiration time. For more information about how the credentials you use affect the expiration time, see [Who can create a presigned URL](#who-presigned-url).

Amazon S3 checks the expiration date and time of a signed URL at the time of the HTTP request. For example, if a client begins to download a large file immediately before the expiration time, the download continues even if the expiration time passes during the download. However, if the connection drops and the client tries to restart the download after the expiration time passes, the download fails.

## Limiting presigned URL capabilities
<a name="PresignedUrlUploadObject-LimitCapabilities"></a>

The capabilities of a presigned URL are limited by the permissions of the user who created it. In essence, presigned URLs are bearer tokens that grant access to those who possess them. As such, we recommend that you protect them appropriately. The following are some methods that you can use to restrict the use of your presigned URLs. 

**AWS Signature Version 4 (SigV4)**  
To enforce specific behavior when presigned URL requests are authenticated by using AWS Signature Version 4 (SigV4), you can use condition keys in bucket policies and access point policies. For example, the following bucket policy uses the `s3:signatureAge` condition to deny any Amazon S3 presigned URL request on objects in the *amzn-s3-demo-bucket* bucket if the signature is more than 10 minutes old. To use this example, replace the *`user input placeholders`* with your own information.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "Deny a presigned URL request if the signature is more than 10 min old",
            "Effect": "Deny",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
            "Condition": {
                "NumericGreaterThan": {
                    "s3:signatureAge": "600000"
                }
            }
        }
    ]
}
```

------

For more information about policy keys related AWS Signature Version 4, see [AWS Signature Version 4 Authentication](https://docs.aws.amazon.com/AmazonS3/latest/API/bucket-policy-s3-sigv4-conditions.html) in the *Amazon Simple Storage Service API Reference*.

**Network path restriction**  
If you want to restrict the use of presigned URLs and all Amazon S3 access to particular network paths, you can write AWS Identity and Access Management (IAM) policies. You can set these policies on the IAM principal that makes the call, the Amazon S3 bucket, or both. 

A network-path restriction on the IAM principal requires the user of those credentials to make requests from the specified network. A restriction on the bucket or access point requires that all requests to that resource originate from the specified network. These restrictions also apply outside of the presigned URL scenario.

The IAM global condition key that you use depends on the type of endpoint. If you're using the public endpoint for Amazon S3, use `aws:SourceIp`. If you're using a virtual private cloud (VPC) endpoint to Amazon S3, use `aws:SourceVpc` or `aws:SourceVpce`.

The following IAM policy statement requires the principal to access AWS only from the specified network range. With this policy statement, all access must originate from that range. This includes the case of someone who's using a presigned URL for Amazon S3. To use this example, replace the *`user input placeholders`* with your own information.

```
{
    "Sid": "NetworkRestrictionForIAMPrincipal",
    "Effect": "Deny",
    "Action": "*",
    "Resource": "*",
    "Condition": {
        "NotIpAddressIfExists": {"aws:SourceIp": "IP-address-range"},
        "BoolIfExists": {"aws:ViaAWSService": "false"}
    }
}
```

## Frequently asked questions for presigned URLs
<a name="PresignedUrlFAQ"></a>

**Q: Why do my presigned URLs expire earlier than the configured expiration time?**  
Presigned URLs remain valid only while their underlying credentials are valid. A presigned URL expires at either its configured expiration time or when its associated credentials expire, whichever occurs first. For Amazon Elastic Container Service tasks or containers, role credentials typically rotate every 1-6 hours. When using AWS Security Token Service (AWS STS) AssumeRole, the presigned URL expires when the role session ends, which by default is 1 hour. For Amazon EC2 instance profiles, metadata credentials rotate periodically with a maximum validity period of approximately 6 hours.

**Q: Why am I getting a 403 Forbidden error when accessing a presigned URL?**  
Before generating a presigned URL, verify that you have the correct permissions configured. The IAM user or role generating the URL must have the required permissions, such as `s3:GetObject`, for the specific operation. Additionally, check that the Amazon S3 bucket policy doesn't explicitly deny access to the object.

**Q: I'm getting `SignatureDoesNotMatch` errors. How do I fix this?**  
If you encounter `SignatureDoesNotMatch` errors when using Amazon S3 presigned URLs, consider several common causes. First, ensure that your system clock is synchronized with a Network Time Protocol (NTP) server, as even small time drifts can invalidate signatures. Next, be aware that some corporate proxies might modify headers or query strings, potentially causing signature mismatches. To troubleshoot, try testing without the proxy. Finally, verify that all request parameters—including the HTTP method, headers, and query string—match exactly between URL generation and usage. Addressing these issues can often resolve `SignatureDoesNotMatch` errors.

**Q: I'm getting `ExpiredToken` errors. What should I do?**  
When you receive `ExpiredToken` errors while using presigned URLs, it indicates that the AWS credentials used to generate the URL are no longer valid. To resolve this issue, refresh your AWS credentials before generating new presigned URLs. For long-running applications, we recommend implementing credential refresh logic to maintain continuous access. Where appropriate, you can use longer-lived credentials or implement token refresh mechanisms. If you're using AWS Security Token Service (AWS STS) AssumeRole, verify that your configured session duration meets your use case requirements. Remember that presigned URLs remain valid only for the duration of their underlying credentials, so implementing proper credential management is essential.

# Sharing objects with presigned URLs
<a name="ShareObjectPreSignedURL"></a>

By default, all Amazon S3 objects are private, only the object owner has permission to access them. However, the object owner may share objects with others by creating a presigned URL. A presigned URL uses security credentials to grant time-limited permission to download objects. The URL can be entered in a browser or used by a program to download the object. The credentials used by the presigned URL are those of the AWS user who generated the URL.

For general information about presigned URLs, see [Download and upload objects with presigned URLs](using-presigned-url.md).

You can create a presigned URL for sharing an object without writing any code by using the Amazon S3 console, AWS Explorer for Visual Studio (Windows), or AWS Toolkit for Visual Studio Code. You can also generate a presigned URL programmatically by using the AWS Command Line Interface (AWS CLI) or the AWS SDKs.

## Using the S3 console
<a name="generating-presigned-url"></a>

 You can use the Amazon S3 console to generate a presigned URL for sharing an object up to 5 TB by following these steps. When using the console the maximum expiration time for a presigned URL is 12 hours from the time of creation.

**To generate a presigned URL by using the Amazon S3 console**

1. Sign in to the AWS Management Console and open the Amazon S3 console at [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/).

1. In the left navigation pane, choose **General purpose buckets**.

1. In the **General purpose buckets** list, choose the name of the general purpose bucket that contains the object that you want a presigned URL for.

1. In the **Objects** list, select the object that you want to create a presigned URL for.

1. On the **Object actions** menu, choose **Share with a presigned URL**.

1. Specify how long you want the presigned URL to be valid.

1. Choose **Create presigned URL**.

1. When a confirmation appears, the URL is automatically copied to your clipboard. You will see a button to copy the presigned URL if you need to copy it again.

## Using the AWS CLI
<a name="ShareObjectPresignedCLI"></a>

The following example AWS CLI command generates a presigned URL for sharing an object from an Amazon S3 bucket. When you use the AWS CLI, the maximum expiration time for a presigned URL is 7 days from the time of creation. To use this example, replace the *`user input placeholders`* with your own information.

```
aws s3 presign s3://amzn-s3-demo-bucket/mydoc.txt --expires-in 604800
```

The `--expires-in` parameter specifies the expiration time in seconds.



**Note**  
For all AWS Regions launched after March 20, 2019 you need to specify the `endpoint-url` and `AWS Region` with the request. For a list of all the Amazon S3 Regions and endpoints, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*.

```
aws s3 presign s3://amzn-s3-demo-bucket/mydoc.txt --expires-in 604800 --region af-south-1 --endpoint-url https://s3.af-south-1.amazonaws.com
```



For more information, see [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/presign.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/presign.html) in the *AWS CLI Command Reference*.

## Using the AWS SDKs
<a name="ShareObjectPreSignedURLSDK"></a>

You can generate a presigned URL programmatically by using the AWS SDKs.

------
#### [ Python ]

 The following Python script generates a `GET` presigned URL for sharing an object.

1. Copy the contents of the script and save it as “*get-only-url.py*” file. To use the following examples, replace the *user input placeholders* with your own information (such as your file name). 

   ```
   import argparse
   import boto3
   from botocore.exceptions import ClientError
   
   def generate_presigned_url(s3_client, client_method, method_parameters, expires_in):
       """
       Generate a presigned Amazon S3 URL that can be used to perform an action.
       
       :param s3_client: A Boto3 Amazon S3 client.
       :param client_method: The name of the client method that the URL performs.
       :param method_parameters: The parameters of the specified client method.
       :param expires_in: The number of seconds the presigned URL is valid for.
       :return: The presigned URL.
       """
       try:
           url = s3_client.generate_presigned_url(
               ClientMethod=client_method,
               Params=method_parameters,
               ExpiresIn=expires_in
           )
       except ClientError:
           print(f"Couldn't get a presigned URL for client method '{client_method}'.")
           raise
       return url
   
   def main():
       parser = argparse.ArgumentParser()
       parser.add_argument("bucket", help="The name of the bucket.")
       parser.add_argument(
           "key", help="The key (path and filename) in the S3 bucket.",
       )
       args = parser.parse_args()
       
       # By default, this will use credentials from ~/.aws/credentials
       s3_client = boto3.client("s3")
       
       # The presigned URL is specified to expire in 1000 seconds
       url = generate_presigned_url(
           s3_client, 
           "get_object", 
           {"Bucket": args.bucket, "Key": args.key}, 
           1000
       )
       print(f"Generated GET presigned URL: {url}")
   
   if __name__ == "__main__":
       main()
   ```

1. To generate a `GET` presigned URL for sharing a file, run the following script with your bucket name and desired object path. 

    The following command uses example values. Replace the *user input placeholders* with your own information.

   ```
   python get-only-url.py amzn-s3-demo-bucket <object-path>
   ```

   The script will output a `GET` presigned URL:

   ```
   Generated GET presigned URL: https://amzn-s3-demo-bucket.s3.amazonaws.com/object.txt?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=vjbyNxybdZaMmLa%2ByT372YEAiv4%3D&Expires=1741978496
   ```

1. You can download the file using the generated presigned URL with curl:

   ```
   curl -X GET "generated-presigned-url" -o "path/to/save/file" 
   ```

For more examples of using the AWS SDKs to generate a presigned URL for sharing an object, see [Create a presigned URL for Amazon S3 by using an AWS SDK](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_Scenario_PresignedUrl_section.html). 

**Note**  
For all AWS Regions launched after March 20, 2019 you need to specify the `endpoint-url` and `AWS Region` with the request. For a list of all the Amazon S3 Regions and endpoints, see [Regions and Endpoints](https://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region) in the *AWS General Reference*.

**Note**  
When using the AWS SDKs, the Tagging attribute must be a header and not a query parameter. All other attributes can be passed as a parameter for the presigned URL. 

------

## Using the AWS Toolkit for Visual Studio (Windows)
<a name="ShareObjectPreSignedURLVSExplorer"></a>

**Note**  
At this time, the AWS Toolkit for Visual Studio does not support Visual Studio for Mac.

1. Install the AWS Toolkit for Visual Studio using the following instructions, [Installing and setting up the Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/setup.html) in the *AWS Toolkit for Visual Studio User Guide*.

1. Connect to AWS using the following steps, [Connecting to AWS](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/connect.html) in the *AWS Toolkit for Visual Studio User Guide*.

1. In the left side panel labeled **AWS Explorer**, double-click the bucket containing your object.

1. Right-click the object you wish to have a presigned URL generated for and select **Create Pre-Signed URL...**.

1. In the pop-up window, set the expiration date and time for your presigned URL.

1. The **Object Key**, should pre-populate based on the object you selected.

1. Choose **GET** to specify that this presigned URL will be used for downloading an object.

1. Choose the **Generate** button.

1. To copy the URL to the clipboard, choose **Copy**.

1. To use the generated presigned URL, paste the URL into any browser.

## Using AWS Toolkit for Visual Studio Code
<a name="ShareObjectPreSignedURLVSCode"></a>

If you're using Visual Studio Code, you can generate a presigned URL to share an object without writing any code by using AWS Toolkit for Visual Studio Code. For general information, see [AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html) in the *AWS Toolkit for Visual Studio Code User Guide*. 

For instructions on how to install the AWS Toolkit for Visual Studio Code, see [Installing the AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html) in the *AWS Toolkit for Visual Studio Code User Guide*.

1. Connect to AWS using the following steps, [Connecting to AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/connect.html) in the *AWS Toolkit for Visual Studio Code User Guide*.

1. Select the AWS logo on the left panel in Visual Studio Code.

1. Under **EXPLORER**, select **S3**.

1. Choose a bucket and file and open the context menu (right-click).

1. Choose **Generate presigned URL**, and then set the expiration time (in minutes).

1. Press Enter, and the presigned URL will be copied to your clipboard.

# Uploading objects with presigned URLs
<a name="PresignedUrlUploadObject"></a>



You may use presigned URLs to allow someone to upload an object to your Amazon S3 bucket. Using a presigned URL will allow an upload without requiring another party to have AWS security credentials or permissions. A presigned URL is limited by the permissions of the user who creates it. That is, if you receive a presigned URL to upload an object, you can upload an object only if the creator of the URL has the necessary permissions to upload that object.

When someone uses the URL to upload an object, Amazon S3 creates the object in the specified bucket. If an object with the same key that is specified in the presigned URL already exists in the bucket, Amazon S3 replaces the existing object with the uploaded object. After upload, the bucket owner will own the object.

For general information about presigned URLs, see [Download and upload objects with presigned URLs](using-presigned-url.md).

You can create a presigned URL for uploading an object without writing any code by using AWS Explorer for Visual Studio. You can also generate a presigned URL programmatically by using the AWS SDKs.

**Note**  
At this time, the AWS Toolkit for Visual Studio doesn't support Visual Studio for Mac.

## Using the AWS Toolkit for Visual Studio (Windows)
<a name="upload-object-presignedurl-vsexplorer"></a>

1. Install the AWS Toolkit for Visual Studio using the following instructions, [Installing and setting up the Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/setup.html) in the *AWS Toolkit for Visual Studio User Guide*.

1. Connect to AWS using the following steps, [Connecting to AWS](https://docs.aws.amazon.com/AWSToolkitVS/latest/UserGuide/connect.html) in the *AWS Toolkit for Visual Studio User Guide*.

1. In the left side panel labeled **AWS Explorer**, right-click the bucket you wish to have an object uploaded to.

1. Choose **Create Pre-Signed URL...**.

1. In the pop-up window, set the expiration date and time for your presigned URL.

1. For **Object Key**, set the name of the file to be uploaded. The file you're uploading must match this name exactly. If an object with the same object key already exists in the bucket, Amazon S3 will replace the existing object with the newly uploaded object. 

1. Choose **PUT** to specify that this presigned URL will be used for uploading an object.

1. Choose the **Generate** button.

1. To copy the URL to the clipboard, choose **Copy**.

1. To use this URL you can send a PUT request with the `curl` command. Include the full path to your file and the presigned URL itself. 

   ```
   curl -X PUT -T "/path/to/file" "presigned URL"
   ```

## Using the AWS SDKs to generate a `PUT` presigned URL for uploading a file
<a name="presigned-urls-upload-sdk"></a>

 You can generate a presigned URL that can perform an S3 action for a limited time. 

**Note**  
If you use the AWS CLI or AWS SDKs, the expiration time for presigned URLs can be set as high as 7 days. For more information, see [Expiration time for presigned URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html#PresignedUrl-Expiration).

------
#### [ Python ]

 The following Python script generates a `PUT` presigned URL for uploading an object to an S3 general purpose bucket. 

1. Copy the contents of the script and save it as “*put-only-url.py*” file. To use the following examples, replace the *user input placeholders* with your own information (such as your file name). 

   ```
   import argparse
   import boto3
   from botocore.exceptions import ClientError
   
   def generate_presigned_url(s3_client, client_method, method_parameters, expires_in):
       """
       Generate a presigned Amazon S3 URL that can be used to perform an action.
       
       :param s3_client: A Boto3 Amazon S3 client.
       :param client_method: The name of the client method that the URL performs.
       :param method_parameters: The parameters of the specified client method.
       :param expires_in: The number of seconds the presigned URL is valid for.
       :return: The presigned URL.
       """
       try:
           url = s3_client.generate_presigned_url(
               ClientMethod=client_method,
               Params=method_parameters,
               ExpiresIn=expires_in
           )
       except ClientError:
           print(f"Couldn't get a presigned URL for client method '{client_method}'.")
           raise
       return url
   
   def main():
       parser = argparse.ArgumentParser()
       parser.add_argument("bucket", help="The name of the bucket.")
       parser.add_argument(
           "key", help="The key (path and filename) in the S3 bucket.",
       )
       parser.add_argument(
           "--region", help="The AWS region where the bucket is located.", default="us-east-1"
       )
       parser.add_argument(
           "--content-type", help="The content type of the file to upload.", default="application/octet-stream"
       )
       args = parser.parse_args()
       
       # Create S3 client with explicit region configuration
       s3_client = boto3.client("s3", region_name=args.region)
       
       # Optionally set signature version if needed for older S3 regions
       # s3_client.meta.config.signature_version = 's3v4'
       
       # The presigned URL is specified to expire in 1000 seconds
       url = generate_presigned_url(
           s3_client, 
           "put_object", 
           {
               "Bucket": args.bucket, 
               "Key": args.key,
               "ContentType": args.content_type  # Specify content type
           }, 
           1000
       )
       print(f"Generated PUT presigned URL: {url}")
   
   if __name__ == "__main__":
       main()
   ```

1. To generate a `PUT` presigned URL for uploading a file, run the following script with your bucket name and desired object path. 

    The following command uses example values. Replace the *user input placeholders* with your own information.

   ```
   python put-only-url.py amzn-s3-demo-bucket <object-path> --region us-east-1 --content-type application/octet-stream
   ```

   The script will output a `PUT` presigned URL:

   ```
   Generated PUT presigned URL: https://amzn-s3-demo-bucket.s3.amazonaws.com/object.txt?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=vjbyNxybdZaMmLa%2ByT372YEAiv4%3D&Expires=1741978496
   ```

1. You can now upload the file using the generated presigned URL with curl. Make sure to include the same content type that was used when generating the URL:

   ```
   curl -X PUT -T "path/to/your/local/file" -H "Content-Type: application/octet-stream" "generated-presigned-url"
   ```

   If you specified a different content type when generating the URL, make sure to use that same content type in the curl command.

For more examples of using the AWS SDKs to generate a presigned URL for uploading an object, see [Create a presigned URL for Amazon S3 by using an AWS SDK](https://docs.aws.amazon.com/AmazonS3/latest/API/s3_example_s3_Scenario_PresignedUrl_section.html).

**Troubleshooting SignatureDoesNotMatch errors**  
If you encounter a `SignatureDoesNotMatch` error when using presigned URLs, check the following:  
Verify your system time is synchronized with a reliable time server
Ensure you're using the URL exactly as generated, without any modifications
Check if the URL has expired and generate a new one if needed
Make sure the content type in your upload request matches the content type specified when generating the URL
Confirm you're using the correct region for the bucket
When using curl, enclose the URL in quotes to properly handle special characters

------