Mastering S3 Presigned URLs
with Backblaze
Generate secure, time-limited access to private storage objects with S3-compatible APIs. Learn implementation, best practices, and cost optimization.
S3 presigned URLs are cryptographically signed, time-limited links that grant temporary access to private objects in cloud storage. They're essential for secure file sharing without exposing credentials or making buckets public.
With Backblaze B2's S3-Compatible API, you get all the power of AWS S3 presigned URLs at a fraction of the costβup to 80% cheaper! This guide covers implementation, security, and includes a memorable football analogy (Newcastle 2-1 Man City) to help you understand access control.
What is a Presigned URL? π
A presigned URL is a special web address that includes authentication information in the URL itself. It allows anyone with the link to access a private object without needing AWS credentials or authentication headers.
The signature encodes:
- βWho issued it: Your access key ID
- βWhat operation: GET (download), PUT (upload), DELETE, etc.
- βWhich object: Bucket name and object key/path
- βWhen it expires: Unix timestamp for expiration
Key Benefit: Both AWS S3 and Backblaze B2 S3-Compatible APIs support presigned URLs, making them ideal for secure, credential-free data transfers across platforms.
Why Choose Backblaze? π°
S3 Compatible
Drop-in replacement for AWS S3. Use standard SDKs (boto3, AWS SDK) with just endpoint changes.
Massive Savings
Up to 80% cheaper storage and egress costs compared to AWS S3. Free egress with Bandwidth Alliance.
Enterprise Security
Same security model as AWS. Encrypted transfers, time-limited access, and cryptographic signatures.
Implementation Guide π
Create Application Key
Navigate to Backblaze console β App Keys β Create new key. Select S3 Compatible API and note your keyID and applicationKey.
Install AWS SDK
For Node.js: npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner. For Python: pip install boto3.
Configure Endpoint
Point SDK to Backblaze endpoint (e.g., s3.us-west-004.backblazeb2.com) instead of AWS endpoints.
Generate URL
Use SDK methods like getSignedUrl() or generate_presigned_url() with your desired expiration time.
Code Examples π»
Download (GET) - Node.js
Generate a presigned URL to allow temporary downloads of a private object:
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');
const { getSignedUrl } = require('@aws-sdk/s3-request-presigner');
const client = new S3Client({
endpoint: 'https://s3.us-west-004.backblazeb2.com',
region: 'us-west-004',
credentials: {
accessKeyId: process.env.B2_KEY_ID,
secretAccessKey: process.env.B2_KEY,
},
});
const command = new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'private/path/secret.pdf'
});
(async () => {
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
console.log('Presigned URL:', url);
})();Download (GET) - Python
Using boto3 to generate presigned URLs with Backblaze:
import boto3
from botocore.client import Config
# Initialize S3 client with Backblaze endpoint
s3_client = boto3.client(
's3',
endpoint_url='https://s3.us-west-004.backblazeb2.com',
aws_access_key_id=os.environ['B2_KEY_ID'],
aws_secret_access_key=os.environ['B2_KEY'],
config=Config(signature_version='s3v4'),
region_name='us-west-004'
)
# Generate presigned URL (valid for 1 hour)
presigned_url = s3_client.generate_presigned_url(
'get_object',
Params={'Bucket': 'my-bucket', 'Key': 'private/path/secret.pdf'},
ExpiresIn=3600
)
print(f'Presigned URL: {presigned_url}')Upload (PUT) - Node.js
Allow users to upload files directly to Backblaze without exposing credentials:
const { PutObjectCommand } = require('@aws-sdk/client-s3');
const uploadCommand = new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'uploads/new-file.pdf',
ContentType: 'application/pdf'
});
const uploadUrl = await getSignedUrl(client, uploadCommand, {
expiresIn: 1800 // 30 minutes
});
// Frontend: Use the URL to upload
const response = await fetch(uploadUrl, {
method: 'PUT',
body: fileData,
headers: { 'Content-Type': 'application/pdf' }
});The Stadium Analogy β½
Newcastle 2-1 Man City (November 2025)
Imagine how presigned URLs work using this epic upset as an analogy...
The Stadium = Storage Bucket
Private and secure. Only those with valid tickets (presigned URLs) can enter.
The Ticket = Presigned URL
Cryptographically signed by the club (API), valid for one match (object) and time window.
Gate Security = Backblaze API
Validates signature and expiry time. No credentials needed at the gate!
Final Whistle = Expiration
After expiry, even valid tickets can't grant re-entry. Access is revoked automatically.
The Upset: During Newcastle's stunning 2-1 victory, only fans with properly signed tickets saw Barnes score both goals. After the match ended (URL expired), even Haaland with an old season pass (expired/invalid presigned URL) couldn't get back in! π―
Backblaze vs AWS S3 π
| Feature | Backblaze B2 | AWS S3 |
|---|---|---|
| Presigned URL Support | β Full support (GET, PUT, DELETE) | β Full SDK support |
| Storage Cost (per GB) | $0.006/GB | $0.023/GB (Standard) |
| Egress/Bandwidth | Free with Bandwidth Alliance | $0.09/GB |
| API Compatibility | S3-Compatible (endpoint change only) | Native AWS SDK |
| Setup Complexity | 5 minutes (change endpoint) | Standard AWS setup |
| Max URL Expiry | 7 days | 7 days |
Security Best Practices π
Minimize Expiration Time
CriticalUse the shortest expiry that works for your use case. For downloads: 5-60 minutes. For uploads: 15-30 minutes.
Always Use HTTPS
CriticalNever use HTTP for presigned URLs. The signature protects tampering, but HTTPS protects the URL itself in transit.
Validate Uploads
HighFor PUT presigned URLs, validate content type, file size, and scan for malware. Add Content-Type restrictions.
Never Expose Keys
CriticalGenerate presigned URLs server-side only. Never put API keys in frontend code or client applications.
Monitor Usage
MediumLog presigned URL generation and usage. Set up alerts for unusual patterns or excessive requests.
Rotate Credentials
HighRegularly rotate your Backblaze application keys. Old URLs will stop working, enhancing security.
Advanced Use Cases π―
π± Direct Mobile Uploads
Mobile apps can request presigned PUT URLs from your backend, then upload directly to Backblaze without proxying through your servers. This saves bandwidth and reduces latency.
π§ Secure Email Attachments
Instead of attaching large files to emails, generate short-lived presigned URLs (1-7 days) and share the link. Recipients can download without authentication.
π₯ Video Streaming
Generate presigned URLs for video content with appropriate expiry. Video players can stream directly from Backblaze with byte-range requests supported.
π Report Generation
Generate reports server-side, upload to Backblaze, create a presigned URL, and share with stakeholders. Reports auto-expire after a set period.
Troubleshooting Guide π§
SignatureDoesNotMatch Error
Verify your endpoint URL, region, access key ID, and secret key are correct. Ensure no extra whitespace in credentials.
URL Expired / AccessDenied
The presigned URL has expired or was generated with incorrect permissions. Generate a new URL with appropriate expiry time.
CORS Errors on Frontend
Configure CORS rules in your Backblaze bucket settings to allow your domain. Include appropriate headers for GET/PUT operations.
Upload Fails Silently
Ensure Content-Type header matches what was specified in PutObjectCommand. Verify file size doesn't exceed limits.
Private Bucket Shows Public
Backblaze presigned URLs only work on private buckets. Public buckets don't need presigned URLsβuse direct links instead.
Performance Optimization β‘
Cache URLs Wisely
If serving the same file to multiple users, generate one presigned URL and cache it on your backend until it's close to expiry.
Use CDN Edge Caching
Combine presigned URLs with CloudFlare or other CDNs. Set appropriate Cache-Control headers for frequently accessed files.
Batch URL Generation
When displaying lists of files, generate presigned URLs in batch operations rather than one-by-one to reduce round-trip time.
Lazy Generate URLs
Don't generate presigned URLs until user initiates action. Generate on-demand when download/upload button is clicked.
Real Cost Savings Example π°
Scenario: Video Platform
10TB storage, 50TB bandwidth per month
Enough to hire another developer or invest in growth!
Ready to Get Started? π
Presigned URLs are a powerful tool for secure, scalable file access in cloud storage. With Backblaze's S3-Compatible API, you get enterprise-grade security and performance at a fraction of AWS costs. Whether you're building a file-sharing platform, mobile app, or video streaming service, presigned URLs provide the perfect balance of security, convenience, and cost-effectiveness.
References & Further Reading π
Last updated: November 2025 | Built with Next.js & Tailwind CSS