# How to Share Links to Files with File Permissions and Presigned URLs Spaces Object Storage is an S3-compatible service for storing and serving large amounts of data. The built-in Spaces CDN minimizes page load times, improves performance, and reduces bandwidth and infrastructure costs. To share links to files in a Spaces bucket, you can set the visibility permissions of individual files: - **Public** permissions let anyone on the internet view the file. - **Private** permissions only allow owners of the bucket to view the file. You can set file permissions when you upload them, and you can change the permissions of files at any time after uploading. By default, file permissions are set to private. Bucket owners can also create [presigned URLs](#presigned-urls) to provide time-bound access to a private file. To share or hide the full list of all files in a bucket, [set the bucket’s file listing permissions](https://docs.digitalocean.com/products/spaces/how-to/set-file-listing-permissions/index.html.md). To grant programmatic access to a bucket, [use Spaces access keys](https://docs.digitalocean.com/products/spaces/how-to/manage-access/index.html.md) with S3-compatible tools, like [AWS SDKs](https://docs.digitalocean.com/products/spaces/how-to/use-aws-sdks/index.html.md) or [Cyberduck](https://docs.digitalocean.com/products/spaces/reference/cyberduck/index.html.md). ## Change File Permissions On the bucket’s **Files** page, you can change an individual file’s permission by opening its **More** menu, clicking **Manage Permissions** to open the **Manage Permissions** window, and then choose **Public** or **Private** and click **Update**. You can also [set metadata](https://docs.digitalocean.com/products/spaces/how-to/set-file-metadata/index.html.md) for multiple files at once by selecting them, opening the **Actions** menu, and choosing **Manage Permissions**. ## Create Presigned URL Bucket owners can give time-bound permission to view a private file by creating a presigned URL for it. The sharing duration can last 1 hour, 6 hours, 1 day, 3 days, or 7 days, and anyone with the link can able to view the private file during that time. A presigned URL for DigitalOcean Spaces has `GET` parameters embedded for headers that begin with `X-Amz-`. These headers define parameters for the URL, like its credentials and expiration date. ### Using the Control Panel To create a presigned URL, from the file’s **More** menu, click **Quick Share**. In the window that opens, choose the sharing duration. The link appears in the **File URL** field and includes a Unix timestamp in the `Expires` parameter. This feature is intended to provide time-bound access to a private resource. The presigned URL for a **Public** file is the same as the file’s public URL and has no expiration date. If you make the file private, the link no longer grants access. ### Using s3cmd To create a presigned URL using `s3cmd`, you can use a command like the following. Substitute the variables for your bucket. ```shell aws s3 presign s3://your-space-name/your-object-key --expires-in 3600 --endpoint-url https://nyc3.digitaloceanspaces.com ``` You can add query parameters to control which resources are available. For example, when generating your presigned URL using the AWS CLI, you can use the `--response-content-type` parameter to specify the `Content-Type` header for the response: ```shell aws s3 presign s3://your-bucket-name/your-object-key --response-content-type text/plain ``` However, `s3cmd` doesn’t support specifying response headers like `Content-Type` when generating presigned URLs, and the AWS CLI doesn’t support specifying the endpoint URL in the `presign` command. You can generate a presigned URL with specific parameters using the DigitalOcean Spaces API and an s3-compatible client library such as Boto3 for Python: ```python import boto3 from botocore.client import Config # Initialize a session using DigitalOcean Spaces session = boto3.session.Session() client = session.client('s3', region_name='nyc3', endpoint_url='https://nyc3.digitaloceanspaces.com', aws_access_key_id='YOUR_ACCESS_KEY', aws_secret_access_key='YOUR_SECRET_KEY') # Generate presigned URL with query parameters url = client.generate_presigned_url(ClientMethod='get_object', Params={ 'Bucket': 'your-space-name', 'Key': 'your-object-key', 'ResponseContentType': 'text/plain', # You can add more parameters if needed, such as 'ResponseContentDisposition': 'attachment; filename=filename.txt' }, ExpiresIn=3600) ``` To add query parameters to an existing presigned URL, you can use `&` to specify the queries at the end of the URL. For example, to serve your resource as `text/plain`, you can append `&response-content-type=text/plain` to the end of the presigned URL.