Makale

S3 presigned URL'leri: nedir, nasıl çalışır, süre sınırları ve kod örnekleri

S3 presigned URL nedir, her X-Amz parametresi ne anlama gelir, 7 günlük süre sınırı, yükleme ve indirme kodu (CLI, boto3, JS) ve sık hataların çözümü.

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

SoruYanıt
Neye izin verir?Tek bir nesne üzerinde tek bir işlem (GET, PUT, HEAD, DELETE…)
Maksimum süreSigV4 ve IAM kullanıcı anahtarlarıyla 7 gün (604.800 saniye)
Geçici anahtarlarla süreRol oturumu veya STS kimlik bilgileri bittiğinde biter, hangisi önce gelirse
S3 konsolu aralığı1 dakika ile 12 saat
Varsayılan süreAWS 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

  1. Kodunuz (veya CLI) bucket’ı, nesne anahtarını, HTTP yöntemini ve bir süreyi alır.
  2. 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.
  3. Ortaya çıkan URL’yi birine verirsiniz: bir tarayıcıya, bir iş arkadaşınıza, bir mobil uygulamaya.
  4. 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
ParametreAnlamı
X-Amz-Algorithmİmzalama algoritması: SigV4 için AWS4-HMAC-SHA256
X-Amz-CredentialErişim anahtarı kimliği artı kapsam: <key-id>/<YYYYMMDD>/<region>/s3/aws4_request
X-Amz-DateURL’nin imzalandığı an, UTC olarak, yyyyMMddTHHmmssZ
X-Amz-ExpiresURL’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-TokenYalnı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 bilgileriMaksimum 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 profileRol kimlik bilgileri yenilenene kadar, en fazla yaklaşık 6 saat
ECS task roleGörev kimlik bilgileri yenilenene kadar, genellikle 1 ila 6 saatte bir
İptal edilen veya silinen kimlik bilgileriX-Amz-Expires ne derse desin hemen durur
S3 konsolu1 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 PUT yöntemine izin veren bir CORS kuralına ihtiyacı vardır. Çok parçalı yüklemeler için ETag baş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, PUT ve DELETE’i destekler. Presigned POST’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

HataOlağan nedenÇözüm
SignatureDoesNotMatchYöntem, başlıklar veya sorgu imzalanandan farklı; saat senkronize değilAynı 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 eriyorGeçici kimlik bilgileriyle imzalanmış (rol, EC2, ECS, Lambda)Bağlantının yaşaması gereken süre kadar yaşayan kimlik bilgileriyle imzalayın
ExpiredTokenX-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
AuthorizationQueryParametersError604.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 engelleniyorBucket’ta kaynağınız ve yönteminiz için CORS kuralı yokKaynağınızı, GET/PUT’u ve açığa çıkarılan ETag’i içeren bir CORS kuralı ekleyin
HeadersNotSigned ile AccessDeniedRange 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:signatureAge koşulu belirli bir yaştan eski imzaları reddeder ve aws:SourceIp hangi 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.