En presigned URL i S3 er et midlertidigt link til ét objekt i en privat bucket. Den har en signatur i forespørgselsstrengen, så den, der har den, kan downloade (eller uploade) objektet uden AWS-loginoplysninger, indtil linket udløber, og bucketen bliver aldrig offentlig. Du opretter den med dine egne nøgler, i din kode eller fra AWS CLI, og den kan gælde fra 1 sekund op til 7 dage. Denne guide gennemgår, hvordan den virker, hvad hver X-Amz-*-parameter betyder, hvor længe den kan gælde, kode til downloads og uploads og de fejl, du højst sandsynligt løber ind i. Grænserne er taget fra AWS’ og Cloudflares dokumentation i oktober 2026.
Presigned URLs i S3 i overblik
| Spørgsmål | Svar |
|---|---|
| Hvad giver den adgang til? | Én operation (GET, PUT, HEAD, DELETE…) på ét objekt |
| Længste udløbstid | 7 dage (604.800 sekunder) med SigV4 og nøgler til en IAM-bruger |
| Udløb med midlertidige nøgler | Slutter, når rollesessionen eller STS-loginoplysningerne slutter, alt efter hvad der kommer først |
| Interval i S3-konsollen | 1 minut til 12 timer |
| Standardudløb | 3.600 s i AWS CLI og boto3, 900 s i presigneren til JavaScript v3 |
| Kan den bruges flere gange? | Ja, så tit nogen har lyst, indtil den udløber |
| Kan én URL tilbagekaldes? | Nej, kun ved at tilbagekalde de signerende loginoplysninger eller afvise den i en politik |
| Kalder oprettelsen S3? | Nej, signaturen beregnes lokalt |
Sådan virker en presigned URL
- Din kode (eller CLI’en) tager bucketen, objektnøglen, HTTP-metoden og en udløbstid.
- SDK’et signerer de værdier med din secret access key ved hjælp af AWS Signature Version 4. Der sendes intet til S3 på dette tidspunkt.
- Du giver den resulterende URL til nogen: en browser, en kollega, en mobilapp.
- Når de bruger den, beregner S3 signaturen igen med den secret, der hører til access key i URL’en. Hvis den passer, URL’en ikke er udløbet, og den, der signerede, må udføre operationen, går forespørgslen igennem.
URL’en har de tilladelser, som den, der signerede den, har. AWS er tydelig på det punkt: hvis IAM-brugeren eller rollen, der genererede URL’en, ikke kan læse objektet, returnerer URL’en 403, uanset hvor gyldig signaturen er.
Det betyder X-Amz-parametrene
En presigned URL med SigV4 ser sådan ud (linjeskift tilføjet):
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
| Parameter | Betydning |
|---|---|
X-Amz-Algorithm | Signeringsalgoritmen: AWS4-HMAC-SHA256 for SigV4 |
X-Amz-Credential | Access key ID plus omfang: <key-id>/<YYYYMMDD>/<region>/s3/aws4_request |
X-Amz-Date | Hvornår URL’en blev signeret, i UTC, yyyyMMddTHHmmssZ |
X-Amz-Expires | Hvor mange sekunder URL’en er gyldig efter X-Amz-Date, fra 1 til 604800 |
X-Amz-SignedHeaders | Headers, signaturen dækker, altid mindst host |
X-Amz-Signature | Signaturen, 64 hexadecimale tegn |
X-Amz-Security-Token | Kun til stede, når URL’en blev signeret med midlertidige loginoplysninger (STS, roller, EC2, ECS, SSO) |
Ændrer du en signeret del (nøglen, metoden, udløbet eller en signeret header), passer signaturen ikke længere. Læg også mærke til, hvad URL’en afslører i klartekst: bucketens navn, hele objektnøglen og dit access key ID. Den hemmelige nøgle står aldrig i URL’en.
Hvor længe en presigned URL gælder
Grænsen afhænger af de loginoplysninger, der signerer den:
| Signeret med | Længste gyldighed |
|---|---|
| Adgangsnøgler til en IAM-bruger (SigV4) | 7 dage, fordi selve SigV4-signeringsnøglen er gyldig i 7 dage |
| IAM-rollesession (STS AssumeRole) | Indtil sessionen slutter, som standard 1 time |
| EC2-instansprofil | Indtil rollens loginoplysninger roteres, højst omkring 6 timer |
| ECS-opgaverolle | Indtil opgavens loginoplysninger roteres, typisk hver 1. til 6. time |
| Loginoplysninger, der tilbagekaldes eller slettes | Stopper med det samme, uanset hvad X-Amz-Expires siger |
| S3-konsollen | Du vælger mellem 1 minut og 12 timer |
Det forklarer den mest almindelige overraskelse: du beder om 7 dage fra en Lambda-funktion eller en EC2-instans, og linket dør efter en time eller nogle få timer. URL’en lever kun så længe som loginoplysningerne bag den. Har du brug for lange links, så signér med en dedikeret IAM-bruger, der kun har læseadgang til den bucket.
S3 tjekker udløbet, når en forespørgsel starter. En stor download, der begynder ét sekund før fristen, gennemføres normalt, men et nyt forsøg efter fristen fejler med AccessDenied og beskeden “Request has expired”. Beder du om mere end 604.800 sekunder, afvises det med det samme.
Sådan genererer du en presigned URL
AWS CLI
aws s3 presign s3://my-bucket/reports/q3.pdf --expires-in 3600
Kommandoen signerer en URL til download (GET). Standard er 3.600 sekunder og maksimum 604.800. Nyere CLI-versioner bruger altid SigV4, så sørg for, at der er konfigureret en region. Til upload-URL’er skal du bruge et SDK.
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,
)
Angiv signature_version='s3v4' eksplicit. Boto3-referencen advarer om, at den af hensyn til bagudkompatibilitet ellers kan signere med den ældre Signature Version 2 i regioner, der stadig accepterer den, hvilket stiltiende dropper nogle parametre og headers som Range. ResponseContentDisposition er valgfri: den får browseren til at gemme filen med et pænt navn i stedet for at åbne den direkte.
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 }
)
Udelader du expiresIn, bruger presigneren til JavaScript 900 sekunder (15 minutter).
Presigned upload-URL’er (PUT)
Den samme idé virker i den anden retning. Du signerer en PutObject for én nøgle, og den, der har URL’en, kan skrive objektet. Filen går direkte fra deres enhed til bucketen, og din server håndterer aldrig bytene. Hvis der allerede findes et objekt med den nøgle, bliver det erstattet.
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,
})
Når du tilføjer content-type til signableHeaders, bindes URL’en til den type, så en upload med en anden Content-Type afvises. I boto3 svarer det til generate_presigned_url('put_object', Params={'Bucket': ..., 'Key': ..., 'ContentType': 'application/pdf'}), og klienten skal sende den samme header.
Tre ting, du skal tjekke, før du uploader fra en browser:
- CORS. Bucketen skal have en CORS-regel, der tillader din origin og metoden
PUT. Til multipart-uploads skal den også eksponere headerenETag, fordi browseren skal læse den fra hver del. - Fast nøgle. Generér en unik nøgle på serveren (f.eks. med et UUID-præfiks), så en besøgende ikke kan overskrive en andens fil.
- Checksummer. Aktuelle AWS SDK’er tilføjer som standard en CRC-checksum til uploads. Hvis presigned uploads mod en S3-kompatibel udbyder fejler med signatur- eller checksumfejl, så sæt
requestChecksumCalculation: 'WHEN_REQUIRED'på klienten.
Presigned POST er en separat mekanisme til almindelige HTML-formularer med en politik, der kan begrænse størrelse og indholdstype. Ikke alle S3-kompatible udbydere understøtter den (R2 gør ikke), så presigned PUT er det mere portable valg.
Store filer: presigned multipart-uploads
En enkelt PUT til S3 er begrænset til 5 GB, og AWS foreslår multipart fra omkring 100 MB. Multipart deler filen op i op til 10.000 dele, hver fra 5 MiB til 5 GiB undtagen den sidste, som uploades uafhængigt, parallelt og med nye forsøg pr. del. Presigning virker pr. del: serveren starter uploaden, signerer én UploadPart-URL pr. del, browseren sender hver bid og melder dens ETag tilbage, og serveren afslutter uploaden.
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 }] },
})
)
Tilføj en livscyklusregel, der afbryder ufærdige multipart-uploads efter nogle få dage, ellers bliver forladte dele ved med at fylde afregnet lagring.
Presigned URLs hos R2, B2, Spaces og Wasabi
Udbydere, der implementerer S3 API’et med SigV4, accepterer den samme kode: du ændrer kun endpoint, region og nøgler. Detaljerne varierer, så tjek udbyderens dokumentation:
- Cloudflare R2 understøtter presigned
GET,HEAD,PUTogDELETEmed en udløbstid fra 1 sekund til 7 dage. Den understøtter ikke presignedPOST, og presigned URLs virker kun på S3 API-domænet (<ACCOUNT_ID>.r2.cloudflarestorage.com), ikke på egne domæner. Brugregion: 'auto'. - Backblaze B2 oplyser, at deres S3-kompatible API understøtter presigned URLs genereret med AWS CLI eller SDK’erne.
- DigitalOcean Spaces og Wasabi virker med de samme SDK-kald rettet mod deres endpoints.
Priserne hos hver udbyder finder du i sammenligningen af S3, R2, Spaces, Wasabi og B2.
Almindelige fejl med presigned URLs og hvordan du løser dem
| Fejl | Sædvanlig årsag | Løsning |
|---|---|---|
SignatureDoesNotMatch | Metode, headers eller forespørgsel afviger fra det signerede; uret går forkert | Send samme Content-Type og headers; synkronisér uret med NTP |
AccessDenied “Request has expired” | URL’en er forbi X-Amz-Date + X-Amz-Expires | Generér en ny URL; afkort tiden mellem signering og brug |
| URL’en udløber tidligere end ønsket | Signeret med midlertidige loginoplysninger (rolle, EC2, ECS, Lambda) | Signér med loginoplysninger, der lever lige så længe som linket |
ExpiredToken | STS-sessionen bag X-Amz-Security-Token er slut | Forny loginoplysningerne før signering |
403 AccessDenied på en ny URL | Den, der signerer, mangler s3:GetObject eller s3:PutObject, eller en politik afviser det | Giv tilladelsen til den signerende identitet; tjek bucket policies |
AuthorizationQueryParametersError | Udløb over 604.800 sekunder eller et forkert formateret credential scope | Hold X-Amz-Expires på 7 dage eller mindre; signér i bucketens region |
| Browseren blokeres af CORS | Ingen CORS-regel for din origin og metode på bucketen | Tilføj en CORS-regel med din origin, GET/PUT og eksponeret ETag |
AccessDenied med HeadersNotSigned | Range blev signeret, men If-Range blev sendt usigneret | Tilføj If-Range til de signerede headers |
Virksomhedsproxyer, der omskriver headers eller forespørgselsstrenge, ødelægger også signaturer. Hvis en URL virker fra ét netværk og ikke fra et andet, så test uden proxyen.
God praksis for sikkerhed
AWS kalder presigned URLs bearer tokens og anbefaler at beskytte dem. I praksis:
- Hold dem korte. Minutter til uploads og følsomme filer, timer til almindelige downloads. Generér en ny, når nogen skal bruge filen igen.
- Signér med en snæver identitet. En dedikeret IAM-bruger eller rolle, der kun kan læse (eller kun skrive) det pågældende præfiks, begrænser skaden, hvis et link slipper ud.
- Læg sikkerhedsgelændere ind i bucket policyen. Betingelsen
s3:signatureAgeafviser signaturer, der er ældre end en fastsat alder, ogaws:SourceIpbegrænser, hvilke netværk der kan bruge dem. - Log dem ikke. Fulde presigned URLs i applikationslogs, analyse eller chathistorik er fungerende adgangsoplysninger, indtil de udløber.
- Tag højde for det, de mangler. Der er ingen adgangskode, ingen downloadtæller og ingen tilbagekaldelse pr. link, så sæt en applikation foran, når du har brug for det.
For delingssiden i dybden, med muligheder, der tilføjer de kontroller, se sådan deler du S3-filer uden at gøre bucketen offentlig.
Sådan bruger Nubbo presigned URLs
Nubbo er bygget på dette mønster. Når du uploader i stifinderen, signerer serveren en PUT (eller, fra 100 MB, en multipart-upload med tre dele parallelt), og din browser sender bytene direkte til din bucket. Downloads af enkeltfiler bruger presigned GET-URL’er, der er gyldige i én time. Dine adgangsnøgler gemmes krypteret med AES-256-GCM og bruges kun på serveren til at signere.
Delingslinks tilføjer det, rå presigned URLs mangler: en valgfri adgangskode, udløbsdato og downloadgrænse, som Nubbo tjekker, før den udsteder en kortlivet URL, og du kan til enhver tid deaktivere et link. ZIP-downloads med flere filer samles i din browser, som henter hver fil direkte fra din bucket: Nubbo ser aldrig indholdet. Én ærlig undtagelse: miniaturer skrives til din egen bucket under .nubbo-thumbs/. Det virker på samme måde på Amazon S3, Cloudflare R2, DigitalOcean Spaces, Wasabi, Backblaze B2 og offentlige S3-kompatible endpoints.
Ofte stillede spørgsmål
Hvad er en presigned URL i S3?
Det er et almindeligt HTTPS-link til ét objekt i en privat bucket med en signatur tilføjet i forespørgselsstrengen. Den, der har linket, kan udføre den ene operation, det er signeret til, som regel en download (GET) eller en upload (PUT), indtil det udløber. Bucketen forbliver privat, og den, der bruger linket, skal ikke have AWS-loginoplysninger.
Hvad er den længste udløbstid for en presigned URL i S3?
Syv dage (604.800 sekunder), når du signerer med Signature Version 4 og langvarige nøgler til en IAM-bruger. En URL signeret med midlertidige loginoplysninger, f.eks. en assumed role eller en EC2-instansprofil, holder op med at virke, når de loginoplysninger udløber, selv hvis du bad om længere tid. I S3-konsollen kan du vælge mellem 1 minut og 12 timer.
Hvad betyder X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders og X-Amz-Signature?
Det er SigV4-godkendelsesparametrene. Algorithm er signeringsmetoden (AWS4-HMAC-SHA256), Credential er dit access key ID plus omfanget af dato, region og tjeneste, Date er, hvornår URL'en blev signeret, Expires er, hvor mange sekunder den er gyldig, SignedHeaders angiver de headers, signaturen dækker, og Signature er selve signaturen. X-Amz-Security-Token vises kun, når URL'en blev signeret med midlertidige loginoplysninger.
Kan jeg tilbagekalde en presigned URL i S3, før den udløber?
Ikke enkeltvis. En presigned URL holder kun op med at virke før tid, når de loginoplysninger, der signerede den, tilbagekaldes, slettes eller deaktiveres, eller når en bucket policy afviser forespørgslen. Hvis du skal kunne annullere enkelte links, så sæt en applikation foran, der kun udleverer kortlivede URL'er efter sine egne tjek.
Er presigned URLs i S3 sikre?
Signaturen kan ikke forfalskes eller ændres, og bucketen forbliver privat. Men AWS beskriver presigned URLs som bearer tokens: alle, der får linket, kan bruge det, så mange gange de vil, indtil det udløber. Hold udløbstiderne korte, brug HTTPS, og undgå at lægge linkene ud, hvor de kan kopieres.
Virker presigned URLs med Cloudflare R2, Backblaze B2 eller Wasabi?
Udbydere, der implementerer S3 API'et med Signature Version 4, understøtter dem generelt, og du bruger de samme SDK-kald med udbyderens endpoint. Cloudflare R2 understøtter f.eks. presigned GET, HEAD, PUT og DELETE med en udløbstid fra 1 sekund til 7 dage, men ikke uploads via POST-formularer og ikke egne domæner.
Hvorfor giver min presigned URL SignatureDoesNotMatch?
AWS nævner tre almindelige årsager: et computerur, der går forkert, en proxy, der ændrer headers eller forespørgselsstrengen, og en forespørgsel, hvis metode, headers eller parametre afviger fra dem, der blev signeret. Ved uploads er den sædvanlige synder at sende en anden Content-Type end den, der blev brugt, da URL'en blev genereret.
Kilder
Priser og grænser stammer fra de officielle sider nedenfor. Udbyderne ændrer dem, så tjek dem, før du binder dig.
- Amazon S3: download og upload objekter med presigned URLs
- AWS IAM: godkendelsesmetoder (SigV4-forespørgselsparametre)
- Amazon S3 API: godkendelse af forespørgsler med forespørgselsparametre (SigV4)
- AWS CLI-reference: s3 presign
- Boto3-reference: generate_presigned_url
- AWS SDK for JavaScript v3: @aws-sdk/s3-request-presigner
- Amazon S3: grænser for multipart-upload
- AWS SDKs and Tools: beskyttelse af dataintegritet i Amazon S3
- Cloudflare R2: presigned URLs
- Backblaze: understøtter B2's S3-kompatible API presigned URLs?