View Source Signed URLs
Signed URLs provide temporary, secure access to objects in cloud storage without requiring authentication. This guide explains how to generate and use signed URLs with Buckets.
What are Signed URLs?
Signed URLs are time-limited URLs that grant temporary access to private objects. They include:
- The object location
- Expiration time
- Cryptographic signature
- Optional permissions (read/write)
Basic Usage
Generating Download URLs
# Generate a signed URL for downloads (default: 1 hour)
{:ok, signed_url} = MyApp.Cloud.url(object)
# Access the URL string
download_url = signed_url.url
# Or use String protocol
download_url = to_string(signed_url)
Custom Expiration
# Expires in 5 minutes
{:ok, signed_url} = MyApp.Cloud.url(object, expires_in: 300)
# Expires in 24 hours
{:ok, signed_url} = MyApp.Cloud.url(object, expires_in: 86400)
# Expires in 7 days (maximum for S3)
{:ok, signed_url} = MyApp.Cloud.url(object, expires_in: 604800)
Upload URLs
Generate URLs for direct uploads:
# Create a placeholder object
object = Buckets.Object.new(
Ecto.UUID.generate(),
"document.pdf",
location: {"uploads/documents/document.pdf", MyApp.Cloud}
)
# Generate upload URL
{:ok, upload_url} = MyApp.Cloud.url(object,
expires_in: 3600,
for_upload: true
)
Use Cases
Secure File Downloads
defmodule MyAppWeb.DocumentController do
def download(conn, %{"id" => id}) do
document = Documents.get!(id)
# Load object from storage location
object = Buckets.Object.new(
document.id,
document.filename,
location: {document.storage_path, MyApp.Cloud}
)
# Generate temporary download URL
{:ok, signed_url} = MyApp.Cloud.url(object, expires_in: 300)
# Redirect to signed URL
redirect(conn, external: signed_url.url)
end
end
Email Attachments
defmodule MyApp.Mailer do
def invoice_email(user, invoice) do
# Generate URL valid for 7 days
{:ok, download_url} = MyApp.Cloud.url(invoice.document,
expires_in: 604800
)
new()
|> to(user.email)
|> subject("Your Invoice")
|> html_body("""
<p>Your invoice is ready!</p>
<p><a href="#{download_url}">Download Invoice</a></p>
<p>This link expires in 7 days.</p>
""")
|> deliver()
end
end
API Responses
defmodule MyAppWeb.API.FileController do
def show(conn, %{"id" => id}) do
file = Files.get!(id)
# Generate short-lived URL
{:ok, signed_url} = MyApp.Cloud.url(file.object,
expires_in: 600 # 10 minutes
)
json(conn, %{
id: file.id,
filename: file.filename,
size: file.size,
content_type: file.content_type,
download_url: signed_url.url,
expires_at: DateTime.add(DateTime.utc_now(), 600)
})
end
end