Bir S3 presigned URL, özel bir bucket’taki tek bir nesneye giden geçici bir bağlantıdır. Sorgu dizesinde bir imza taşır, bu yüzden ona sahip olan herkes bağlantının süresi dolana kadar AWS kimlik bilgileri olmadan o nesneyi indirebilir (veya yükleyebilir) ve bucket hiçbir zaman herkese açık hale gelmez. Onu kendi anahtarlarınızla, kodunuzda veya AWS CLI’dan oluşturursunuz ve 1 saniyeden 7 güne kadar geçerli olabilir. Bu kılavuz nasıl çalıştığını, her X-Amz-* parametresinin ne anlama geldiğini, ne kadar sürebileceğini, indirme ve yükleme kodunu ve en olası hataları ele alıyor. Sınırlar Ekim 2026 itibarıyla AWS ve Cloudflare belgelerinden alınmıştır.
Bir bakışta S3 presigned URL’leri
| Soru | Yanıt |
|---|---|
| Neye izin verir? | Tek bir nesne üzerinde tek bir işlem (GET, PUT, HEAD, DELETE…) |
| Maksimum süre | SigV4 ve IAM kullanıcı anahtarlarıyla 7 gün (604.800 saniye) |
| Geçici anahtarlarla süre | Rol oturumu veya STS kimlik bilgileri bittiğinde biter, hangisi önce gelirse |
| S3 konsolu aralığı | 1 dakika ile 12 saat |
| Varsayılan süre | AWS CLI ve boto3’te 3.600 sn, JavaScript v3 presigner’da 900 sn |
| Birkaç kez kullanılabilir mi? | Evet, süresi dolana kadar herkes istediği kadar |
| Tek bir URL iptal edilebilir mi? | Hayır, yalnızca imzalayan kimlik bilgileri iptal edilerek veya bir ilkeyle reddedilerek |
| Oluşturmak S3’ü çağırır mı? | Hayır, imza yerel olarak hesaplanır |
Bir presigned URL nasıl çalışır
- Kodunuz (veya CLI) bucket’ı, nesne anahtarını, HTTP yöntemini ve bir süreyi alır.
- SDK bu değerleri AWS Signature Version 4 ile gizli erişim anahtarınızı kullanarak imzalar. Bu aşamada S3’e hiçbir şey gönderilmez.
- Ortaya çıkan URL’yi birine verirsiniz: bir tarayıcıya, bir iş arkadaşınıza, bir mobil uygulamaya.
- URL kullanıldığında S3, URL’deki erişim anahtarına ait gizli anahtarla imzayı yeniden hesaplar. İmza eşleşirse, URL’nin süresi dolmamışsa ve imzalayanın o işlemi yapma izni varsa istek geçer.
URL, onu imzalayan kişinin izinlerini taşır. AWS bu konuda açıktır: URL’yi oluşturan IAM kullanıcısı veya rolü nesneyi okuyamıyorsa, imza ne kadar geçerli olursa olsun URL 403 döndürür.
X-Amz parametreleri ne anlama gelir
Bir SigV4 presigned URL şöyle görünür (satır sonları eklenmiştir):
https://my-bucket.s3.eu-west-1.amazonaws.com/reports/q3.pdf
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20261017%2Feu-west-1%2Fs3%2Faws4_request
&X-Amz-Date=20261017T093000Z
&X-Amz-Expires=3600
&X-Amz-SignedHeaders=host
&X-Amz-Signature=5f2c...e91a
| Parametre | Anlamı |
|---|---|
X-Amz-Algorithm | İmzalama algoritması: SigV4 için AWS4-HMAC-SHA256 |
X-Amz-Credential | Erişim anahtarı kimliği artı kapsam: <key-id>/<YYYYMMDD>/<region>/s3/aws4_request |
X-Amz-Date | URL’nin imzalandığı an, UTC olarak, yyyyMMddTHHmmssZ |
X-Amz-Expires | URL’nin X-Amz-Date’ten sonra kaç saniye geçerli olduğu, 1 ile 604800 arası |
X-Amz-SignedHeaders | İmzanın kapsadığı başlıklar, her zaman en az host |
X-Amz-Signature | İmza, 64 onaltılık karakter |
X-Amz-Security-Token | Yalnızca URL geçici kimlik bilgileriyle (STS, roller, EC2, ECS, SSO) imzalandığında bulunur |
İmzalanan herhangi bir parçayı (anahtar, yöntem, süre veya imzalı bir başlık) değiştirirseniz imza artık eşleşmez. URL’nin düz metin olarak neleri açığa çıkardığına da dikkat edin: bucket adı, nesnenin tam anahtarı ve erişim anahtarı kimliğiniz. Gizli anahtar hiçbir zaman URL’de bulunmaz.
Bir presigned URL ne kadar sürer
Sınır, onu imzalayan kimlik bilgilerine bağlıdır:
| İmzalandığı kimlik bilgileri | Maksimum geçerlilik |
|---|---|
| IAM kullanıcı erişim anahtarları (SigV4) | 7 gün, çünkü SigV4 imzalama anahtarının kendisi 7 gün geçerlidir |
| IAM rol oturumu (STS AssumeRole) | Oturum bitene kadar, varsayılan olarak 1 saat |
| EC2 instance profile | Rol kimlik bilgileri yenilenene kadar, en fazla yaklaşık 6 saat |
| ECS task role | Görev kimlik bilgileri yenilenene kadar, genellikle 1 ila 6 saatte bir |
| İptal edilen veya silinen kimlik bilgileri | X-Amz-Expires ne derse desin hemen durur |
| S3 konsolu | 1 dakika ile 12 saat arasında siz seçersiniz |
Bu en yaygın sürprizi açıklar: bir Lambda fonksiyonundan veya bir EC2 instance’ından 7 gün istersiniz ve bağlantı bir saat veya birkaç saat sonra ölür. URL ancak arkasındaki kimlik bilgileri kadar uzun yaşar. Uzun bağlantılara ihtiyacınız varsa, yalnızca o bucket’a okuma erişimi olan özel bir IAM kullanıcısıyla imzalayın.
S3 süreyi bir istek başladığında kontrol eder. Son tarihten bir saniye önce başlayan büyük bir indirme normal şekilde tamamlanır, ancak son tarihten sonraki bir yeniden deneme AccessDenied ve “Request has expired” mesajıyla başarısız olur. 604.800 saniyeden fazlasını istemek doğrudan reddedilir.
Bir presigned URL nasıl oluşturulur
AWS CLI
aws s3 presign s3://my-bucket/reports/q3.pdf --expires-in 3600
Komut bir indirme (GET) URL’si imzalar. Varsayılan 3.600 saniye, maksimum 604.800’dür. Son CLI sürümleri her zaman SigV4 kullanır, bu yüzden bir bölgenin yapılandırıldığından emin olun. Yükleme URL’leri için bir SDK’ya ihtiyacınız var.
Python (boto3)
import boto3
from botocore.config import Config
s3 = boto3.client('s3', region_name='eu-west-1', config=Config(signature_version='s3v4'))
url = s3.generate_presigned_url(
ClientMethod='get_object',
Params={
'Bucket': 'my-bucket',
'Key': 'reports/q3.pdf',
'ResponseContentDisposition': 'attachment; filename="q3.pdf"',
},
ExpiresIn=3600,
)
signature_version='s3v4' değerini açıkça ayarlayın. Boto3 başvurusu, geriye dönük uyumluluk nedeniyle aksi halde hâlâ kabul eden bölgelerde eski Signature Version 2 ile imzalayabileceği konusunda uyarır; bu da Range gibi bazı parametreleri ve başlıkları sessizce düşürür. ResponseContentDisposition isteğe bağlıdır: tarayıcının dosyayı satır içinde açmak yerine temiz bir adla kaydetmesini sağlar.
JavaScript (AWS SDK v3)
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
const client = new S3Client({ region: 'eu-west-1' })
const url = await getSignedUrl(
client,
new GetObjectCommand({ Bucket: 'my-bucket', Key: 'reports/q3.pdf' }),
{ expiresIn: 3600 }
)
expiresIn belirtmezseniz JavaScript presigner’ı 900 saniye (15 dakika) kullanır.
Presigned yükleme URL’leri (PUT)
Aynı fikir ters yönde de çalışır. Tek bir anahtar için bir PutObject imzalarsınız ve URL’ye sahip olan herkes o nesneyi yazabilir. Dosya doğrudan onların cihazından bucket’a gider ve sunucunuz baytlara hiç dokunmaz. O anahtarla bir nesne zaten varsa değiştirilir.
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
const client = new S3Client({ region: 'eu-west-1' })
const url = await getSignedUrl(
client,
new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'incoming/brief.pdf',
ContentType: 'application/pdf',
}),
{ expiresIn: 900, signableHeaders: new Set(['content-type']) }
)
await fetch(url, {
method: 'PUT',
headers: { 'Content-Type': 'application/pdf' },
body: file,
})
content-type’ı signableHeaders’a eklemek URL’yi o türe bağlar, böylece farklı bir Content-Type ile yapılan yükleme reddedilir. Boto3’te bunun karşılığı generate_presigned_url('put_object', Params={'Bucket': ..., 'Key': ..., 'ContentType': 'application/pdf'}) şeklindedir ve istemcinin aynı başlığı göndermesi gerekir.
Bir tarayıcıdan yüklemeden önce kontrol edilecek üç şey:
- CORS. Bucket’ın, kaynağınıza ve
PUTyöntemine izin veren bir CORS kuralına ihtiyacı vardır. Çok parçalı yüklemeler içinETagbaşlığını da açığa çıkarmalıdır, çünkü tarayıcının bunu her parçadan okuması gerekir. - Sabit anahtar. Bir ziyaretçinin başkasının dosyasının üzerine yazamaması için sunucuda benzersiz bir anahtar oluşturun (örneğin UUID önekiyle).
- Sağlama toplamları. Güncel AWS SDK’ları yüklemelere varsayılan olarak bir CRC sağlama toplamı ekler. S3 uyumlu bir sağlayıcıya presigned yüklemeler imza veya sağlama toplamı hatalarıyla başarısız olursa, istemcide
requestChecksumCalculation: 'WHEN_REQUIRED'ayarlayın.
Presigned POST, düz HTML formları için boyutu ve içerik türünü sınırlayabilen bir ilkeyle çalışan ayrı bir mekanizmadır. Her S3 uyumlu sağlayıcı bunu desteklemez (R2 desteklemez), bu yüzden presigned PUT daha taşınabilir bir seçimdir.
Büyük dosyalar: presigned çok parçalı yüklemeler
S3’e tek bir PUT 5 GB ile sınırlıdır ve AWS yaklaşık 100 MB’tan itibaren çok parçalı yüklemeyi önerir. Çok parçalı yükleme dosyayı, sonuncusu hariç her biri 5 MiB ile 5 GiB arasında olan en fazla 10.000 parçaya böler; parçalar bağımsız olarak, paralel ve parça başına yeniden denemelerle yüklenir. Önceden imzalama parça başına çalışır: sunucu yüklemeyi başlatır, her parça için bir UploadPart URL’si imzalar, tarayıcı her parçayı gönderir ve ETag’ini geri bildirir, sunucu da yüklemeyi tamamlar.
import {
CreateMultipartUploadCommand,
UploadPartCommand,
CompleteMultipartUploadCommand,
} from '@aws-sdk/client-s3'
const { UploadId } = await client.send(
new CreateMultipartUploadCommand({ Bucket: 'my-bucket', Key: 'video/raw.mov' })
)
const partUrl = await getSignedUrl(
client,
new UploadPartCommand({ Bucket: 'my-bucket', Key: 'video/raw.mov', UploadId, PartNumber: 1 }),
{ expiresIn: 3600 }
)
await client.send(
new CompleteMultipartUploadCommand({
Bucket: 'my-bucket',
Key: 'video/raw.mov',
UploadId,
MultipartUpload: { Parts: [{ PartNumber: 1, ETag: etagFromPartResponse }] },
})
)
Tamamlanmamış çok parçalı yüklemeleri birkaç gün sonra iptal eden bir yaşam döngüsü kuralı ekleyin, yoksa terk edilmiş parçalar faturalandırılan depolama alanı kaplamaya devam eder.
R2, B2, Spaces ve Wasabi’de presigned URL’ler
S3 API’sini SigV4 ile uygulayan sağlayıcılar aynı kodu kabul eder: yalnızca endpoint’i, bölgeyi ve anahtarları değiştirirsiniz. Ayrıntılar farklıdır, bu yüzden sağlayıcının belgelerini kontrol edin:
- Cloudflare R2, 1 saniyeden 7 güne kadar süreyle presigned
GET,HEAD,PUTveDELETE’i destekler. PresignedPOST’u desteklemez ve presigned URL’ler yalnızca S3 API alan adında (<ACCOUNT_ID>.r2.cloudflarestorage.com) çalışır, özel alan adlarında çalışmaz.region: 'auto'kullanın. - Backblaze B2, S3 uyumlu API’sinin AWS CLI veya SDK’larla oluşturulan presigned URL’leri desteklediğini belirtir.
- DigitalOcean Spaces ve Wasabi, kendi endpoint’lerine yönlendirilen aynı SDK çağrılarıyla çalışır.
Her sağlayıcının fiyatları için S3, R2, Spaces, Wasabi ve B2 karşılaştırması makalesine bakın.
Sık görülen presigned URL hataları ve çözümleri
| Hata | Olağan neden | Çözüm |
|---|---|---|
SignatureDoesNotMatch | Yöntem, başlıklar veya sorgu imzalanandan farklı; saat senkronize değil | Aynı Content-Type ve başlıkları gönderin; saati NTP ile senkronize edin |
AccessDenied “Request has expired” | URL, X-Amz-Date + X-Amz-Expires süresini aşmış | Yeni bir URL oluşturun; imzalama ile kullanım arasındaki süreyi kısaltın |
| URL istenenden önce sona eriyor | Geçici kimlik bilgileriyle imzalanmış (rol, EC2, ECS, Lambda) | Bağlantının yaşaması gereken süre kadar yaşayan kimlik bilgileriyle imzalayın |
ExpiredToken | X-Amz-Security-Token arkasındaki STS oturumu sona ermiş | İmzalamadan önce kimlik bilgilerini yenileyin |
Yeni bir URL’de 403 AccessDenied | İmzalayanın s3:GetObject veya s3:PutObject izni yok ya da bir ilke reddediyor | İzni imzalayan kimliğe verin; bucket ilkelerini kontrol edin |
AuthorizationQueryParametersError | 604.800 saniyenin üzerinde süre veya hatalı bir kimlik bilgisi kapsamı | X-Amz-Expires’ı 7 gün veya altında tutun; bucket’ın bölgesinde imzalayın |
| Tarayıcı CORS tarafından engelleniyor | Bucket’ta kaynağınız ve yönteminiz için CORS kuralı yok | Kaynağınızı, GET/PUT’u ve açığa çıkarılan ETag’i içeren bir CORS kuralı ekleyin |
HeadersNotSigned ile AccessDenied | Range imzalanmış ama If-Range imzasız gönderilmiş | If-Range’i imzalı başlıklara ekleyin |
Başlıkları veya sorgu dizelerini yeniden yazan kurumsal proxy’ler de imzaları bozar. Bir URL bir ağdan çalışıp diğerinden çalışmıyorsa proxy olmadan test edin.
Güvenlik için en iyi uygulamalar
AWS presigned URL’leri taşıyıcı belirteç olarak adlandırır ve korunmalarını önerir. Pratikte:
- Kısa tutun. Yüklemeler ve hassas dosyalar için dakikalar, sıradan indirmeler için saatler. Biri dosyaya tekrar ihtiyaç duyduğunda yeni bir tane oluşturun.
- Dar yetkili bir kimlikle imzalayın. İlgili öneki yalnızca okuyabilen (veya yalnızca yazabilen) özel bir IAM kullanıcısı veya rolü, bir bağlantı sızarsa zararı sınırlar.
- Bucket ilkesine korkuluklar ekleyin.
s3:signatureAgekoşulu belirli bir yaştan eski imzaları reddeder veaws:SourceIphangi ağların bunları kullanabileceğini kısıtlar. - Günlüklere yazmayın. Uygulama günlüklerinde, analitikte veya sohbet geçmişinde duran tam presigned URL’ler, süreleri dolana kadar çalışan kimlik bilgileridir.
- Eksiklerini hesaba katın. Şifre, indirme sayacı veya bağlantı başına iptal yoktur, bu yüzden bunlara ihtiyacınız olduğunda önüne bir uygulama koyun.
Paylaşım tarafını bu kontrolleri ekleyen seçeneklerle derinlemesine görmek için S3 dosyalarını bucket’ı herkese açık yapmadan paylaşma makalesine bakın.
Nubbo presigned URL’leri nasıl kullanır
Nubbo bu model üzerine kuruludur. Gezginde yükleme yaptığınızda sunucu bir PUT (veya 100 MB’tan itibaren üç paralel parçalı çok parçalı bir yükleme) imzalar ve tarayıcınız baytları doğrudan bucket’ınıza gönderir. Tek dosya indirmeleri bir saat geçerli presigned GET URL’leri kullanır. Erişim anahtarlarınız AES-256-GCM ile şifrelenmiş olarak saklanır ve yalnızca sunucuda imzalamak için kullanılır.
Paylaşım bağlantıları, ham presigned URL’lerin eksiklerini ekler: Nubbo’nun kısa ömürlü bir URL vermeden önce kontrol ettiği isteğe bağlı bir şifre, son kullanma tarihi ve indirme sınırı; ayrıca bir bağlantıyı istediğiniz zaman devre dışı bırakabilirsiniz. Çok dosyalı ZIP indirmeleri, her dosyayı doğrudan bucket’ınızdan indiren tarayıcınızda oluşturulur: Nubbo içeriği asla görmez. Dürüst tek bir istisna: küçük resimler kendi bucket’ınıza .nubbo-thumbs/ altında yazılır. Amazon S3, Cloudflare R2, DigitalOcean Spaces, Wasabi, Backblaze B2 ve herkese açık S3 uyumlu endpoint’lerde aynı şekilde çalışır.
Sıkça sorulan sorular
S3'te presigned URL nedir?
Özel bir bucket'taki tek bir nesneye giden, sorgu dizesine bir imza eklenmiş normal bir HTTPS bağlantısıdır. Bağlantıya sahip olan herkes, süresi dolana kadar imzalandığı tek işlemi, genellikle bir indirme (GET) veya yükleme (PUT), gerçekleştirebilir. Bucket özel kalır ve bağlantıyı kullanan kişinin AWS kimlik bilgilerine ihtiyacı olmaz.
Bir S3 presigned URL'sinin maksimum süresi ne kadar?
Signature Version 4 ve uzun süreli IAM kullanıcı anahtarlarıyla imzaladığınızda yedi gün (604.800 saniye). Üstlenilen bir rol veya EC2 instance profile gibi geçici kimlik bilgileriyle imzalanan bir URL, daha uzun bir süre isteseniz bile o kimlik bilgilerinin süresi dolduğunda çalışmayı bırakır. S3 konsolunda 1 dakika ile 12 saat arasında seçim yapabilirsiniz.
X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders ve X-Amz-Signature ne anlama gelir?
Bunlar SigV4 kimlik doğrulama parametreleridir. Algorithm imzalama yöntemidir (AWS4-HMAC-SHA256), Credential erişim anahtarı kimliğiniz artı tarih, bölge ve hizmet kapsamıdır, Date URL'nin imzalandığı andır, Expires kaç saniye geçerli kaldığıdır, SignedHeaders imzanın kapsadığı başlıkları listeler ve Signature imzanın kendisidir. X-Amz-Security-Token yalnızca URL geçici kimlik bilgileriyle imzalandığında görünür.
Bir S3 presigned URL'sini süresi dolmadan iptal edebilir miyim?
Tek tek hayır. Bir presigned URL yalnızca onu imzalayan kimlik bilgileri iptal edildiğinde, silindiğinde veya devre dışı bırakıldığında ya da bir bucket ilkesi isteği reddettiğinde erken çalışmayı bırakır. Tek tek bağlantıları iptal etmeniz gerekiyorsa, önüne yalnızca kendi kontrollerinden sonra kısa ömürlü URL'ler veren bir uygulama koyun.
S3 presigned URL'leri güvenli mi?
İmza sahtelenemez veya değiştirilemez ve bucket özel kalır. Ancak AWS presigned URL'leri taşıyıcı belirteç (bearer token) olarak tanımlar: bağlantıyı ele geçiren herkes süresi dolana kadar istediği kadar kullanabilir. Süreleri kısa tutun, HTTPS kullanın ve bağlantıları kopyalanabilecekleri yerlerde paylaşmaktan kaçının.
Presigned URL'ler Cloudflare R2, Backblaze B2 veya Wasabi ile çalışır mı?
S3 API'sini Signature Version 4 ile uygulayan sağlayıcılar genellikle bunları destekler ve aynı SDK çağrılarını sağlayıcının endpoint'iyle kullanırsınız. Örneğin Cloudflare R2, 1 saniyeden 7 güne kadar süreyle presigned GET, HEAD, PUT ve DELETE'i destekler, ancak POST form yüklemelerini ve özel alan adlarını desteklemez.
Presigned URL'im neden SignatureDoesNotMatch döndürüyor?
AWS üç yaygın neden listeler: saati senkronize olmayan bir bilgisayar, başlıkları veya sorgu dizesini değiştiren bir proxy ve yöntemi, başlıkları veya parametreleri imzalananlardan farklı olan bir istek. Yüklemelerde olağan suçlu, URL oluşturulurken kullanılandan farklı bir Content-Type göndermektir.
Kaynaklar
Fiyatlar ve sınırlar aşağıdaki resmi sayfalardan alınmıştır. Sağlayıcılar bunları değiştirebilir, karar vermeden önce kontrol edin.
- Amazon S3: presigned URL'lerle nesne indirme ve yükleme
- AWS IAM: kimlik doğrulama yöntemleri (SigV4 sorgu parametreleri)
- Amazon S3 API: sorgu parametreleriyle istekleri doğrulama (SigV4)
- AWS CLI başvurusu: s3 presign
- Boto3 başvurusu: generate_presigned_url
- JavaScript v3 için AWS SDK: @aws-sdk/s3-request-presigner
- Amazon S3: çok parçalı yükleme sınırları
- AWS SDK'ları ve araçları: Amazon S3 için veri bütünlüğü korumaları
- Cloudflare R2: presigned URL'ler
- Backblaze: B2 S3 uyumlu API presigned URL'leri destekliyor mu?