En forhåndssignert S3-URL er en midlertidig lenke til ett objekt i en privat bucket. Den har en signatur i spørrestrengen, så den som har den, kan laste ned (eller laste opp) det objektet uten AWS-legitimasjon til lenken utløper, og bucketen blir aldri offentlig. Du lager den med dine egne nøkler, i koden din eller fra AWS CLI, og den kan vare fra 1 sekund opptil 7 dager. Denne veiledningen viser hvordan den fungerer, hva hver X-Amz-*-parameter betyr, hvor lenge den kan vare, kode for nedlastinger og opplastinger og feilene du mest sannsynlig støter på. Grensene er hentet fra dokumentasjonen til AWS og Cloudflare per oktober 2026.
Forhåndssignerte S3-URL-er i korte trekk
| Spørsmål | Svar |
|---|---|
| Hva gir den tilgang til? | Én operasjon (GET, PUT, HEAD, DELETE…) på ett objekt |
| Lengste utløpstid | 7 dager (604 800 sekunder) med SigV4 og nøkler for en IAM-bruker |
| Utløp med midlertidige nøkler | Slutter når rolleøkten eller STS-legitimasjonen slutter, avhengig av hva som skjer først |
| Område i S3-konsollen | 1 minutt til 12 timer |
| Standard utløpstid | 3 600 s i AWS CLI og boto3, 900 s i presigneren for JavaScript v3 |
| Kan den brukes flere ganger? | Ja, så ofte noen vil til den utløper |
| Kan én URL trekkes tilbake? | Nei, bare ved å trekke tilbake legitimasjonen som signerte, eller avvise den i en policy |
| Kaller det S3 å lage en? | Nei, signaturen beregnes lokalt |
Slik fungerer en forhåndssignert URL
- Koden din (eller CLI-et) tar bucketen, objektnøkkelen, HTTP-metoden og en utløpstid.
- SDK-et signerer disse verdiene med den hemmelige tilgangsnøkkelen din ved hjelp av AWS Signature Version 4. Ingenting sendes til S3 på dette tidspunktet.
- Du gir den ferdige URL-en til noen: en nettleser, en kollega, en mobilapp.
- Når de bruker den, beregner S3 signaturen på nytt med hemmeligheten som hører til tilgangsnøkkelen i URL-en. Hvis den stemmer, URL-en ikke har utløpt og den som signerte har lov til å utføre operasjonen, går forespørselen gjennom.
URL-en har tillatelsene til den som signerte den. AWS er tydelig på dette: hvis IAM-brukeren eller rollen som laget URL-en ikke kan lese objektet, returnerer URL-en 403 uansett hvor gyldig signaturen er.
Hva X-Amz-parameterne betyr
En forhåndssignert URL med SigV4 ser slik ut (med linjeskift lagt til):
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 | Tilgangsnøkkel-ID pluss omfang: <key-id>/<YYYYMMDD>/<region>/s3/aws4_request |
X-Amz-Date | Når URL-en ble signert, i UTC, yyyyMMddTHHmmssZ |
X-Amz-Expires | Hvor mange sekunder URL-en er gyldig etter X-Amz-Date, fra 1 til 604800 |
X-Amz-SignedHeaders | Headerne som signaturen dekker, alltid minst host |
X-Amz-Signature | Signaturen, 64 heksadesimale tegn |
X-Amz-Security-Token | Finnes bare når URL-en ble signert med midlertidig legitimasjon (STS, roller, EC2, ECS, SSO) |
Endrer du en signert del (nøkkelen, metoden, utløpstiden eller en signert header), stemmer ikke signaturen lenger. Merk også hva URL-en avslører i klartekst: navnet på bucketen, hele objektnøkkelen og tilgangsnøkkel-ID-en din. Den hemmelige nøkkelen står aldri i URL-en.
Hvor lenge en forhåndssignert URL varer
Grensen avhenger av legitimasjonen som signerer den:
| Signert med | Lengste gyldighet |
|---|---|
| Tilgangsnøkler for IAM-bruker (SigV4) | 7 dager, fordi selve signeringsnøkkelen i SigV4 er gyldig i 7 dager |
| IAM-rolleøkt (STS AssumeRole) | Til økten slutter, 1 time som standard |
| EC2-instansprofil | Til rollelegitimasjonen roteres, høyst rundt 6 timer |
| ECS-oppgaverolle | Til oppgavelegitimasjonen roteres, vanligvis hver 1. til 6. time |
| Legitimasjon som trekkes tilbake eller slettes | Slutter umiddelbart, uansett hva X-Amz-Expires sier |
| S3-konsollen | Du velger mellom 1 minutt og 12 timer |
Dette forklarer den vanligste overraskelsen: du ber om 7 dager fra en Lambda-funksjon eller en EC2-instans, og lenken dør etter en time eller noen få timer. URL-en lever bare så lenge som legitimasjonen bak den. Hvis du trenger lange lenker, signerer du med en egen IAM-bruker som bare har lesetilgang til den bucketen.
S3 sjekker utløpstiden når en forespørsel starter. En stor nedlasting som begynner ett sekund før fristen, fullføres normalt, men et nytt forsøk etter fristen mislykkes med AccessDenied og meldingen «Request has expired». Ber du om mer enn 604 800 sekunder, avvises det med en gang.
Slik lager du en forhåndssignert URL
AWS CLI
aws s3 presign s3://my-bucket/reports/q3.pdf --expires-in 3600
Kommandoen signerer en URL for nedlasting (GET). Standard er 3 600 sekunder og maksimum 604 800. Nyere CLI-versjoner bruker alltid SigV4, så sørg for at en region er konfigurert. For opplastings-URL-er trenger du 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,
)
Sett signature_version='s3v4' eksplisitt. Boto3-referansen advarer om at den ellers, av hensyn til bakoverkompatibilitet, kan signere med den eldre Signature Version 2 i regioner som fortsatt godtar den, noe som stille fjerner enkelte parametere og headere, som Range. ResponseContentDisposition er valgfri: den får nettleseren til å lagre filen med et ryddig navn i stedet for å åpne 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 }
)
Hvis du utelater expiresIn, bruker presigneren for JavaScript 900 sekunder (15 minutter).
Forhåndssignerte URL-er for opplasting (PUT)
Den samme ideen fungerer den andre veien. Du signerer en PutObject for én nøkkel, og den som har URL-en, kan skrive det objektet. Filen går rett fra enheten deres til bucketen, og serveren din håndterer aldri bytene. Hvis det allerede finnes et objekt med den nøkkelen, erstattes det.
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 legger til content-type i signableHeaders, bindes URL-en til den typen, så en opplasting med en annen Content-Type avvises. I boto3 tilsvarer det generate_presigned_url('put_object', Params={'Bucket': ..., 'Key': ..., 'ContentType': 'application/pdf'}), og klienten må sende den samme headeren.
Tre ting du bør sjekke før du laster opp fra en nettleser:
- CORS. Bucketen trenger en CORS-regel som tillater opprinnelsen din og metoden
PUT. For multipart-opplastinger må den også eksponere headerenETag, fordi nettleseren må lese den fra hver del. - Fast nøkkel. Lag en unik nøkkel på serveren (for eksempel med et UUID-prefiks), slik at en besøkende ikke kan overskrive filen til noen andre.
- Sjekksummer. Nåværende AWS SDK-er legger som standard til en CRC-sjekksum på opplastinger. Hvis forhåndssignerte opplastinger mislykkes mot en S3-kompatibel leverandør med signatur- eller sjekksumfeil, setter du
requestChecksumCalculation: 'WHEN_REQUIRED'på klienten.
Presigned POST er en egen mekanisme for vanlige HTML-skjemaer, med en policy som kan begrense størrelse og innholdstype. Ikke alle S3-kompatible leverandører støtter det (R2 gjør det ikke), så forhåndssignert PUT er det mest portable valget.
Store filer: forhåndssignerte multipart-opplastinger
En enkelt PUT til S3 er begrenset til 5 GB, og AWS foreslår multipart fra rundt 100 MB. Multipart deler filen i opptil 10 000 deler, hver fra 5 MiB til 5 GiB unntatt den siste, som lastes opp uavhengig, parallelt og med nye forsøk per del. Forhåndssignering skjer per del: serveren starter opplastingen, signerer én UploadPart-URL per del, nettleseren sender hver bit og rapporterer tilbake ETag, og serveren fullfører opplastingen.
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 }] },
})
)
Legg til en livssyklusregel som avbryter ufullførte multipart-opplastinger etter noen dager, ellers fortsetter forlatte deler å ta opp fakturerbar lagring.
Forhåndssignerte URL-er hos R2, B2, Spaces og Wasabi
Leverandører som implementerer S3 API-et med SigV4, godtar den samme koden: du endrer bare endepunktet, regionen og nøklene. Detaljene varierer, så sjekk dokumentasjonen til leverandøren:
- Cloudflare R2 støtter forhåndssignerte
GET,HEAD,PUTogDELETE, med en utløpstid fra 1 sekund til 7 dager. Den støtter ikke forhåndssignertPOST, og forhåndssignerte URL-er fungerer bare på domenet til S3 API-et (<ACCOUNT_ID>.r2.cloudflarestorage.com), ikke på egne domener. Brukregion: 'auto'. - Backblaze B2 sier at det S3-kompatible API-et støtter forhåndssignerte URL-er laget med AWS CLI eller SDK-er.
- DigitalOcean Spaces og Wasabi fungerer med de samme SDK-kallene pekt mot endepunktene deres.
For priser hos hver leverandør, se sammenligningen av S3, R2, Spaces, Wasabi og B2.
Vanlige feil med forhåndssignerte URL-er og hvordan du løser dem
| Feil | Vanlig årsak | Løsning |
|---|---|---|
SignatureDoesNotMatch | Metode, headere eller spørring er forskjellig fra det som ble signert; klokken går feil | Send samme Content-Type og headere; synkroniser klokken med NTP |
AccessDenied «Request has expired» | URL-en er forbi X-Amz-Date + X-Amz-Expires | Lag en ny URL; kort ned tiden mellom signering og bruk |
| URL-en utløper før forventet | Signert med midlertidig legitimasjon (rolle, EC2, ECS, Lambda) | Signer med legitimasjon som lever like lenge som lenken må |
ExpiredToken | STS-økten bak X-Amz-Security-Token er avsluttet | Forny legitimasjonen før du signerer |
403 AccessDenied på en ny URL | Den som signerer, mangler s3:GetObject eller s3:PutObject, eller en policy avviser det | Gi tillatelsen til den som signerer; sjekk bucket policyer |
AuthorizationQueryParametersError | Utløpstid over 604 800 sekunder eller et feilformatert omfang i legitimasjonen | Hold X-Amz-Expires på 7 dager eller mindre; signer i regionen til bucketen |
| Nettleseren blokkeres av CORS | Ingen CORS-regel for opprinnelsen og metoden din på bucketen | Legg til en CORS-regel med opprinnelsen din, GET/PUT og eksponert ETag |
AccessDenied med HeadersNotSigned | Range ble signert, men If-Range ble sendt usignert | Legg til If-Range i de signerte headerne |
Bedriftsproxyer som skriver om headere eller spørrestrenger, ødelegger også signaturer. Hvis en URL fungerer fra ett nettverk og ikke fra et annet, kan du teste uten proxyen.
God praksis for sikkerhet
AWS kaller forhåndssignerte URL-er bærertokener og anbefaler å beskytte dem. I praksis:
- Hold dem korte. Minutter for opplastinger og sensitive filer, timer for vanlige nedlastinger. Lag en ny når noen trenger filen igjen.
- Signer med en smal identitet. En egen IAM-bruker eller rolle som bare kan lese (eller bare skrive) det aktuelle prefikset, begrenser skaden hvis en lenke lekker.
- Legg inn sikringer i bucket policyen. Betingelsen
s3:signatureAgeavviser signaturer som er eldre enn en angitt alder, ogaws:SourceIpbegrenser hvilke nettverk som kan bruke dem. - Ikke logg dem. Fullstendige forhåndssignerte URL-er i applikasjonslogger, analyseverktøy eller chathistorikk er fungerende legitimasjon til de utløper.
- Planlegg for det de mangler. Det finnes ikke passord, nedlastingsteller eller tilbaketrekking per lenke, så sett en applikasjon foran når du trenger det.
For delingssiden i dybden, med alternativer som legger til disse kontrollene, se slik deler du S3-filer uten å gjøre bucketen offentlig.
Slik bruker Nubbo forhåndssignerte URL-er
Nubbo er bygd på dette mønsteret. Når du laster opp i utforskeren, signerer serveren en PUT (eller, fra 100 MB, en multipart-opplasting med tre deler parallelt), og nettleseren din sender bytene direkte til bucketen din. Nedlastinger av enkeltfiler bruker forhåndssignerte GET-URL-er som er gyldige i én time. Tilgangsnøklene dine lagres kryptert med AES-256-GCM og brukes bare på serveren til å signere.
Delingslenker legger til det rå forhåndssignerte URL-er mangler: valgfritt passord, utløpsdato og nedlastingsgrense som Nubbo sjekker før den utsteder en kortlivet URL, og du kan deaktivere en lenke når som helst. ZIP-nedlastinger med flere filer settes sammen i nettleseren din, som laster ned hver fil rett fra bucketen din: Nubbo ser aldri innholdet. Ett ærlig unntak: miniatyrbilder skrives til din egen bucket under .nubbo-thumbs/. Det fungerer på samme måte med Amazon S3, Cloudflare R2, DigitalOcean Spaces, Wasabi, Backblaze B2 og offentlige S3-kompatible endepunkter.
Ofte stilte spørsmål
Hva er en forhåndssignert URL i S3?
Det er en vanlig HTTPS-lenke til ett objekt i en privat bucket, med en signatur lagt til i spørrestrengen. Den som har lenken, kan utføre den ene operasjonen den ble signert for, vanligvis en nedlasting (GET) eller en opplasting (PUT), til den utløper. Bucketen forblir privat, og den som bruker lenken, trenger ingen AWS-legitimasjon.
Hva er lengste utløpstid for en forhåndssignert S3-URL?
Sju dager (604 800 sekunder) når du signerer med Signature Version 4 og langvarige nøkler for en IAM-bruker. En URL som er signert med midlertidig legitimasjon, for eksempel en antatt rolle eller en EC2-instansprofil, slutter å virke når den legitimasjonen utløper, selv om du ba om lengre tid. I S3-konsollen kan du velge mellom 1 minutt og 12 timer.
Hva betyr X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders og X-Amz-Signature?
De er autentiseringsparameterne i SigV4. Algorithm er signeringsmetoden (AWS4-HMAC-SHA256), Credential er tilgangsnøkkel-ID-en din pluss omfanget med dato, region og tjeneste, Date er når URL-en ble signert, Expires er hvor mange sekunder den er gyldig, SignedHeaders lister headerne som signaturen dekker, og Signature er selve signaturen. X-Amz-Security-Token vises bare når URL-en ble signert med midlertidig legitimasjon.
Kan jeg trekke tilbake en forhåndssignert S3-URL før den utløper?
Ikke én og én. En forhåndssignert URL slutter å virke før tiden bare når legitimasjonen som signerte den, trekkes tilbake, slettes eller deaktiveres, eller når en bucket policy avviser forespørselen. Hvis du må kunne annullere enkeltlenker, setter du en applikasjon foran som bare deler ut kortlivede URL-er etter sine egne kontroller.
Er forhåndssignerte S3-URL-er sikre?
Signaturen kan ikke forfalskes eller endres, og bucketen forblir privat. Men AWS beskriver forhåndssignerte URL-er som bærertokener (bearer tokens): alle som får lenken, kan bruke den, så mange ganger de vil, til den utløper. Hold utløpstidene korte, bruk HTTPS og unngå å legge ut lenkene der de kan kopieres.
Fungerer forhåndssignerte URL-er med Cloudflare R2, Backblaze B2 eller Wasabi?
Leverandører som implementerer S3 API-et med Signature Version 4, støtter dem som regel, og du bruker de samme SDK-kallene med endepunktet til leverandøren. Cloudflare R2 støtter for eksempel forhåndssignerte GET, HEAD, PUT og DELETE med en utløpstid fra 1 sekund til 7 dager, men ikke opplasting via POST-skjema og ikke egne domener.
Hvorfor gir den forhåndssignerte URL-en min SignatureDoesNotMatch?
AWS oppgir tre vanlige årsaker: en datamaskinklokke som går feil, en proxy som endrer headere eller spørrestrengen, og en forespørsel der metoden, headerne eller parameterne er forskjellige fra dem som ble signert. Ved opplastinger er den vanlige synderen at det sendes en annen Content-Type enn den som ble brukt da URL-en ble laget.
Kilder
Priser og grenser er hentet fra de offisielle sidene nedenfor. Leverandørene endrer dem, så sjekk før du bestemmer deg.
- Amazon S3: last ned og last opp objekter med forhåndssignerte URL-er
- AWS IAM: autentiseringsmetoder (spørreparametere i SigV4)
- Amazon S3 API: autentisering av forespørsler med spørreparametere (SigV4)
- AWS CLI-referanse: s3 presign
- Boto3-referanse: generate_presigned_url
- AWS SDK for JavaScript v3: @aws-sdk/s3-request-presigner
- Amazon S3: grenser for multipart-opplasting
- AWS SDKs and Tools: dataintegritet for Amazon S3
- Cloudflare R2: forhåndssignerte URL-er
- Backblaze: støtter B2 S3 Compatible API forhåndssignerte URL-er?