Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/content/docs/aws/connecting/aws-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ aws --endpoint-url=http://localhost.localstack.cloud:4566 kinesis list-streams

:::note

To enable the creation of pre-signed URLs for S3 buckets, please set both `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` to the value "test." Our pre-signed URL signature verification algorithm validates the pre-signed URL and its expiration.
Pre-signed URLs for S3 are generated with the credentials configured on the client, such as the default `test`/`test` pair shown above.
For LocalStack to be able to validate a pre-signed URL, it must be generated with valid credentials. More details at [S3 signature validation](/aws/services/s3/#signature-validation).
:::

### Configuring a custom profile
Expand Down
6 changes: 4 additions & 2 deletions src/content/docs/aws/connecting/credentials.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ In all such cases, the account ID is evaluated to `000000000000`.

## Secret Access Key

The value of the secret access key are currently ignored by LocalStack.
The value of the secret access key is generally ignored by LocalStack.
We recommend using the same value as access key ID or `test`.

We recommend using the same value as access key ID or `test`
S3 can optionally validate request signatures, in which case the secret access key matters: it must be the secret the access key ID was issued with, or `test` for access key IDs not issued by LocalStack.
See [S3 signature validation](/aws/services/s3/#signature-validation) for details.
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,8 @@ Please consult the [migration guide](/aws/services/lambda#migrating-to-lambda-v2

| Variable | Example Values | Description |
| - | - | - |
| `S3_SKIP_SIGNATURE_VALIDATION`| `0` \| `1` (default) | Used to toggle validation of S3 pre-signed URL request signature. Set to `0` to validate. Note that validation can only pass if the `AWS_SECRET_ACCESS_KEY` is set to `test` or if using credentials returned from `STS.AssumeRole` |
| `S3_SKIP_SIGNATURE_VALIDATION`| `0` \| `1` (default) | Used to toggle validation of S3 pre-signed URLs. Set to `0` to validate their signature and expiration. See [Signature validation](/aws/services/s3/#signature-validation) for the credentials accepted by the validation. |
| `S3_VALIDATE_SIGNATURES` | `0` (default) \| `1` | Used to toggle SigV4 signature validation of regular (non-pre-signed) S3 requests. Set to `1` to validate the request signature and the payload integrity. See [Signature validation](/aws/services/s3/#signature-validation) for the credentials accepted by the validation. |
| `S3_SKIP_KMS_KEY_VALIDATION` | `0` \| `1` (default) | Used to toggle validation of provided KMS key in S3 operations. |

### SNS
Expand Down
97 changes: 97 additions & 0 deletions src/content/docs/aws/services/s3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ awslocal s3 presign s3://sample-bucket/image.jpg
You will see a generated pre-signed URL for your S3 object.
You can use [curl](https://curl.se/) or [`wget`](https://www.gnu.org/software/wget/) to retrieve the S3 object using the pre-signed URL.

By default, LocalStack does not validate the signature or the expiration of pre-signed URLs.
Check out the [Signature validation](#signature-validation) section to enable it.

## Path-Style and Virtual Hosted-Style Requests

Similar to AWS, LocalStack categorizes requests as either [Path style or Virtual-Hosted style](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) based on the Host header of the request.
Expand Down Expand Up @@ -154,6 +157,100 @@ The `ForcePathStyle` parameter name can vary between SDK and languages, please c
If your endpoint is not prefixed with `s3.`, all requests are treated as **Path style** requests.
Using the `s3.localhost.localstack.cloud` endpoint URL is recommended for all requests aimed at S3.

## Signature validation

Like AWS, S3 in LocalStack can validate the signature of incoming requests and reject requests signed with invalid credentials.
Signature validation is disabled by default, so that S3 accepts requests signed with any credentials.

Two independent configuration options control signature validation:

- [`S3_SKIP_SIGNATURE_VALIDATION=0`](/aws/customization/configuration-options/#s3) validates [pre-signed URLs](#pre-signed-urls).
- [`S3_VALIDATE_SIGNATURES=1`](/aws/customization/configuration-options/#s3) validates regular, [SigV4-signed requests](#sigv4-validation).

### Credentials

When signature validation is enabled, requests must be signed with credentials that are valid in LocalStack.
The following credentials pass validation:

- **Default credentials**: the default `test` access key ID with the `test` secret access key, which works out of the box.
- **IAM user credentials**: access keys created for an IAM user with [`CreateAccessKey`](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateAccessKey.html).
Check out the [IAM documentation](/aws/services/iam/#getting-started) to learn how to create a user and its access keys.
- **Temporary credentials**: credentials returned by the STS [`AssumeRole`](https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html) or [`GetSessionToken`](https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html) APIs, used together with their session token.

For example, after [creating a role](/aws/services/sts/#create-an-iam-role), you can retrieve temporary credentials for it using the `AssumeRole` API:

```bash
awslocal sts assume-role \
--role-arn arn:aws:iam::000000000000:role/localstack-role \
--role-session-name localstack-session
```

```bash title="Output"
{
"Credentials": {
"AccessKeyId": "ACCESS_KEY_ID",
"SecretAccessKey": "SECRET_ACCESS_KEY",
"SessionToken": "SESSION_TOKEN",
"Expiration": "TIMESTAMP"
},
...
}
```

Export the returned credentials and use the AWS CLI or your SDK as usual — requests are now signed with the temporary credentials and pass validation:

```bash
export AWS_ACCESS_KEY_ID=ACCESS_KEY_ID
export AWS_SECRET_ACCESS_KEY=SECRET_ACCESS_KEY
export AWS_SESSION_TOKEN=SESSION_TOKEN

awslocal s3api list-buckets
```

:::note
An access key ID that was not issued by LocalStack through IAM or STS is expected to be paired with the `test` secret access key.
Signing a request with such an access key ID and a different secret access key results in a `SignatureDoesNotMatch` error.

One exception is a 12-digit account ID used as access key ID for [multi-account namespacing](/aws/customization/advanced/multi-account-setups/), which cannot pass signature validation.
To send signed requests to another account than the default, use the credentials of an IAM user created in that account, or temporary credentials of a role assumed in it.
:::

Signature validation authenticates a request, but does not authorize it: LocalStack does not check whether the credentials are allowed to perform the operation.
Authorization is handled by [IAM policy enforcement](/aws/developer-tools/security-testing/iam-policy-enforcement/), which can be enabled independently and combined with signature validation for the closest behavior to AWS.

### Pre-signed URLs

A pre-signed URL grants time-limited access to an S3 object: anyone with the URL can access the object without providing credentials.
You can generate a pre-signed URL as shown in the [Getting started](#generate-a-pre-signed-url-for-s3-object) section.

Presigning is a purely client-side operation: the SDK or the CLI computes the pre-signed URL locally with the credentials it is configured with, without contacting LocalStack.
The signature is only checked when the pre-signed URL is used.
For the validation to pass, the URL must therefore be generated with valid [credentials](#credentials).

By default, LocalStack accepts pre-signed URLs with an invalid signature or an expired date.
Start LocalStack with `S3_SKIP_SIGNATURE_VALIDATION=0` to validate pre-signed URLs like AWS does:

- The signature must match the request. Both SigV2 and SigV4 pre-signed URLs are supported.
- The URL must not be expired.
- All `x-amz-*` headers sent with the request must be signed in the URL.

Requests that fail validation are rejected with a `403` error, such as `SignatureDoesNotMatch` for an invalid signature, or `AccessDenied` for an expired URL.

### SigV4 validation

By default, LocalStack accepts regular S3 requests signed with any credentials.
Start LocalStack with `S3_VALIDATE_SIGNATURES=1` to validate [SigV4-signed requests](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) like AWS does.
LocalStack validates the signature in the `Authorization` header, as well as the integrity of the payload declared in the `x-amz-content-sha256` header, including streamed `aws-chunked` uploads.

If your SDK or CLI is configured with valid [credentials](#credentials), validation is fully transparent and does not require any change.
Requests that fail validation are rejected with the same errors as AWS, such as `SignatureDoesNotMatch` for a signature computed with the wrong secret access key, or `XAmzContentSHA256Mismatch` for a payload that does not match its declared checksum.

:::note
`S3_VALIDATE_SIGNATURES` only applies to SigV4-signed requests.
Anonymous requests, such as requests to public buckets or static S3 websites, and CORS preflight requests are not affected.
Pre-signed URL validation is exclusively controlled by `S3_SKIP_SIGNATURE_VALIDATION`.
:::

## Configuring Cross-Origin Resource Sharing on S3

You can configure Cross-Origin Resource Sharing (CORS) on a LocalStack S3 bucket using AWS Command Line Interface (CLI).
Expand Down