> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreflux.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Amazon S3

> Client-mode REST API connector for a curated Amazon S3 slice: PutObject, GetObject, HeadObject, ListBuckets, and PUT to a presigned URL

Technical Preview

## Overview

A client-mode connector for a **curated IIoT object-storage** slice of the [Amazon S3 REST API](https://docs.aws.amazon.com/AmazonS3/latest/API/Welcome.html) under path-style `https://s3.amazonaws.com`:

| Catalog connector event | Entity / path | Notes |
| - | - | - |
| (smoke) | `GET /` | ListBuckets for the signing identity |
| PUT object (snapshot, CSV rollup) | `PUT /{bucket}/{key}` | SigV4 headers required |
| GET object | `GET /{bucket}/{key}` | SigV4 headers required |
| (optional) HeadObject | `HEAD /{bucket}/{key}` | Metadata without body |
| PUT to presigned URL | `PUT {presigned_path}` | No Authorization; switch BASE to URL origin |
| S3 → SNS event | — | Docs-only; future `ENABLE_SERVER` |

`BASE_ADDRESS` defaults to `https://s3.amazonaws.com` (no trailing slash; path-style). Prefer regional `https://s3.{region}.amazonaws.com` when required. Topics use `storage/amazon-s3/<object>/<verb>`.

> [!NOTE]
>
> **Virtual-hosted style:** set `BASE_ADDRESS` to `https://{bucket}.s3.{region}.amazonaws.com` and use endpoints like `/{key}` (bucket is already in the host).

> [!NOTE]
>
> **Presigned PUT:** set `BASE_ADDRESS` to the presigned URL origin only, put path+query in `presigned_path`, and omit SigV4 headers — the query string carries the signature. Ideal for edge devices that must not hold AWS keys.

> [!NOTE]
>
> **S3 event notifications** (SNS / EventBridge / Lambda) are not inbound HTTP on this client connector. Receiving notification POSTs needs a separate `ENABLE_SERVER` REST\_API template (not packaged).

> [!NOTE]
>
> Prefer Hub secrets for AWS keys used by an upstream SigV4 signer. This template has not been verified against a live AWS account. Status remains blocked until an authenticated live smoke (or working presigned URL smoke) succeeds.

## Basic Syntax

```lot wrap theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
# Coreflux REST_API template — Amazon S3 curated slice
# Auth: SigV4 via {value.json.authorization}, {value.json.x_amz_date},
#       {value.json.x_amz_content_sha256} — or PutPresigned (no Authorization)
# BASE_ADDRESS: https://s3.amazonaws.com (path-style)

DEFINE ROUTE AmazonS3RestApi WITH TYPE REST_API
    ADD REST_API_CONFIG
        WITH BASE_ADDRESS "https://s3.amazonaws.com"
        WITH ENABLE_CLIENT "true"
        WITH USE_SSL "true"
        WITH REQUEST_TIMEOUT '60'
        WITH DEFAULT_CONTENT_TYPE "application/octet-stream"
    ADD EVENT Listbuckets
        WITH SOURCE_TOPIC "storage/amazon-s3/buckets/list"
        WITH DESTINATION_TOPIC "storage/amazon-s3/buckets/list/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/"
        WITH HEADERS
            ADD "Accept" "application/xml"
            ADD "Authorization" "{value.json.authorization}"
            ADD "x-amz-date" "{value.json.x_amz_date}"
            ADD "x-amz-content-sha256" "{value.json.x_amz_content_sha256}"
    ADD EVENT Putobject
        WITH SOURCE_TOPIC "storage/amazon-s3/object/put"
        WITH DESTINATION_TOPIC "storage/amazon-s3/object/put/response"
        WITH METHOD "PUT"
        WITH ENDPOINT "/{value.json.bucket}/{value.json.key}"
        WITH HEADERS
            ADD "Accept" "application/xml"
            ADD "Content-Type" "{value.json.content_type}"
            ADD "Authorization" "{value.json.authorization}"
            ADD "x-amz-date" "{value.json.x_amz_date}"
            ADD "x-amz-content-sha256" "{value.json.x_amz_content_sha256}"
        WITH BODY "{payload}"
    ADD EVENT Getobject
        WITH SOURCE_TOPIC "storage/amazon-s3/object/get"
        WITH DESTINATION_TOPIC "storage/amazon-s3/object/get/response"
        WITH METHOD "GET"
        WITH ENDPOINT "/{value.json.bucket}/{value.json.key}"
        WITH HEADERS
            ADD "Accept" "*/*"
            ADD "Authorization" "{value.json.authorization}"
            ADD "x-amz-date" "{value.json.x_amz_date}"
            ADD "x-amz-content-sha256" "{value.json.x_amz_content_sha256}"
    ADD EVENT Headobject
        WITH SOURCE_TOPIC "storage/amazon-s3/object/head"
        WITH DESTINATION_TOPIC "storage/amazon-s3/object/head/response"
        WITH METHOD "HEAD"
        WITH ENDPOINT "/{value.json.bucket}/{value.json.key}"
        WITH HEADERS
            ADD "Authorization" "{value.json.authorization}"
            ADD "x-amz-date" "{value.json.x_amz_date}"
            ADD "x-amz-content-sha256" "{value.json.x_amz_content_sha256}"
    ADD EVENT Putpresigned
        WITH SOURCE_TOPIC "storage/amazon-s3/object/put-presigned"
        WITH DESTINATION_TOPIC "storage/amazon-s3/object/put-presigned/response"
        WITH METHOD "PUT"
        WITH ENDPOINT "{value.json.presigned_path}"
        WITH HEADERS
            ADD "Content-Type" "{value.json.content_type}"
        WITH BODY "{payload}"
```

## Configuration

| Setting | Value |
| - | - |
| Connector name | `AmazonS3RestApi` |
| Type | `REST_API` (client) |
| BASE\_ADDRESS | `https://s3.amazonaws.com` (path-style default) |
| Topic prefix | `storage/amazon-s3/...` |
| Default Content-Type | `application/octet-stream` |
| Hub status | Technical preview (`WITH STATUS "beta"`) |

## Authentication

### AWS Signature Version 4

S3 does **not** use `Authorization: Bearer …`. Sign each request with [SigV4](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) and pass:

| MQTT JSON field | HTTP header |
| - | - |
| `authorization` | `Authorization` (`AWS4-HMAC-SHA256 Credential=…`) |
| `x_amz_date` | `x-amz-date` |
| `x_amz_content_sha256` | `x-amz-content-sha256` |

Use Hub secrets for `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` in an upstream signing helper. Never commit real keys. STS sessions may also need `x-amz-security-token` (add that header in a customized fork if required).

### Presigned URLs (recommended for edge)

Generate a time-limited PUT or GET URL with the AWS CLI/SDK. For PutPresigned:

1. Point `BASE_ADDRESS` at the URL origin.
2. Put path + query into `presigned_path`.
3. Omit Authorization — do not re-sign on the broker.

## MQTT topics

| Event | Request topic | Response topic |
| - | - | - |
| ListBuckets | `storage/amazon-s3/buckets/list` | `…/response` |
| PutObject | `storage/amazon-s3/object/put` | `…/response` |
| GetObject | `storage/amazon-s3/object/get` | `…/response` |
| HeadObject | `storage/amazon-s3/object/head` | `…/response` |
| PutPresigned | `storage/amazon-s3/object/put-presigned` | `…/response` |

## Example payloads

**ListBuckets smoke (after signing):**

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "authorization": "AWS4-HMAC-SHA256 Credential=AKIA.../20261004/eu-west-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=...",
  "x_amz_date": "20261004T040000Z",
  "x_amz_content_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
```

**PutObject CSV rollup:**

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "bucket": "my-iiot-rollups",
  "key": "line-a/2026-10-04/rollup.csv",
  "content_type": "text/csv",
  "authorization": "AWS4-HMAC-SHA256 Credential=...",
  "x_amz_date": "20261004T040100Z",
  "x_amz_content_sha256": "<sha256 of body>",
  "payload": "ts,device,temp\n2026-10-04T04:01:00Z,sensor-01,72.5\n"
}
```

**PutPresigned:**

```json theme={"theme":"css-variables","languages":{"custom":["/languages/lot.json"]}}
{
  "presigned_path": "/line-a/snapshot.json?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...&X-Amz-Signature=...",
  "content_type": "application/json",
  "payload": "{\"device\":\"sensor-01\",\"temp\":72.5}"
}
```

## References

* [S3 API PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
* [S3 API GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)
* [S3 API HeadObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html)
* [S3 API ListBuckets](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html)
* [Upload with a presigned URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html)
* [Authenticating Requests (SigV4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html)
* [Coreflux REST API Connectors](/latest/lot-language/routes/rest-api-routes)

## Package status

Blocked on the factory until `AWS_ACCESS_KEY_ID` + `AWS_SECRET_ACCESS_KEY` (+ region + test bucket) or a valid presigned URL enables a live authenticated smoke recorded in `TEST.md`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.