Simulators
Presigned URLs
A presigned URL carries its credential in the query string, so a browser or a plain HTTP client can fetch an object with no header. The simulator accepts the URLs an SDK makes. A URL signed with 64 zeros works too, as long as it is well formed and fresh. Fetch an object with a SigV4 URL built by hand:
now=$(date -u +%Y%m%dT%H%M%SZ)
curl -s "$RYSTIC_URL/acme-demo-site/robots.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F${now%T*}%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=$now&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=0000000000000000000000000000000000000000000000000000000000000000"
# -> User-agent: *
# -> Allow: /
An SDK presigns offline, against the endpoint it is configured with, so aws s3 presign s3://acme-demo-site/robots.txt and boto3’s generate_presigned_url give URLs the simulator takes the same way.
What the simulator checks
The URL’s parameters stand in for the Authorization header and never reach the operation as arguments. The simulator checks the URL’s shape and its expiry against the real clock:
| The URL | The simulator returns |
|---|---|
SigV4 (X-Amz-Algorithm, X-Amz-Credential, X-Amz-Date, X-Amz-Expires, X-Amz-SignedHeaders, X-Amz-Signature) missing or repeating a parameter, an algorithm other than AWS4-HMAC-SHA256, a scope day other than X-Amz-Date’s, X-Amz-Expires above 604800 (seven days), signed headers without host or a signature other than 64 lowercase hex digits | 400 AuthorizationQueryParametersError |
SigV2 (AWSAccessKeyId, Signature, Expires) missing or repeating a parameter, or Expires not a Unix time | 403 AccessDenied |
| Well-formed, past its expiry | 403 AccessDenied, Request has expired |
Two mechanisms at once: both forms, or a form beside an Authorization header | 400 InvalidArgument, Only one auth mechanism allowed |
Differs from S3: the simulator never checks a presigned URL’s signature, so a URL signed with the wrong secret is not caught.
A SigV2 URL whose Expires is long past returns Request has expired:
curl -s "$RYSTIC_URL/acme-demo-site/robots.txt?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Signature=abc&Expires=1" | grep -oE '<Code>[^<]*|<Message>[^<]*'
# -> <Code>AccessDenied
# -> <Message>Request has expired