S3 Connector¶
Built-in s3 connector for AWS S3 and S3-compatible APIs (for example MinIO) via the AWS SDK v3, with optional custom endpoints and Floh’s SSRF-aware endpoint validation.
Local MinIO with Docker¶
Run MinIO on your machine (API on 9000, web console on 9001):
docker run -d --name minio \
-p 9000:9000 -p 9001:9001 \
-e MINIO_ROOT_USER=minioadmin \
-e MINIO_ROOT_PASSWORD=minioadmin \
-v minio-data:/data \
minio/minio server /data --console-address ":9001"
- Open http://localhost:9001 and sign in with
minioadmin/minioadmin. - Create a bucket (for example
floh-dev) for workflow tests.
MinIO root credentials → Floh S3 connector fields¶
The container’s root identity is defined by MINIO_ROOT_USER and MINIO_ROOT_PASSWORD. In the Floh connector instance, use the same values as AWS-style keys:
| MinIO (Docker env) | Floh connector field |
|---|---|
MINIO_ROOT_USER |
Access key id |
MINIO_ROOT_PASSWORD |
Secret access key |
If you change the env vars when starting the container, use those new strings in Floh — they are not “console-only”; they are the S3 API access key and secret MinIO expects for SigV4.
Custom endpoint, forcePathStyle, and allowPrivateNetworkEndpoint¶
Floh’s S3 connector wraps the AWS SDK. endpoint decides which HTTP server receives S3 API calls. forcePathStyle decides how the bucket name appears in the URL. allowPrivateNetworkEndpoint decides whether Floh’s SSRF-style URL validation allows targets that are not on the public internet (localhost, Docker bridge IPs, RFC1918, etc.).
endpoint — where requests go¶
- Unset (empty) — The SDK uses AWS’s normal regional hostname for
region(for examples3.us-east-1.amazonaws.com). Use this for production AWS buckets with no custom gateway. - Set — Every S3 call goes to that base URL instead. Use this for MinIO, LocalStack, on-prem S3-compatible products, reverse proxies, or dual-stack / custom gateways in front of AWS.
The value must be a bare base URL (scheme + host + optional port + path prefix if your proxy needs it). Do not embed access keys in the URL; Floh rejects userinfo in endpoint.
Who resolves the hostname: whatever machine runs the Floh server performs DNS and opens TCP to endpoint. “Docker vs non-Docker” is really where the Floh process runs vs where S3/MinIO runs:
| Floh | S3 / MinIO | Typical endpoint |
allowPrivateNetworkEndpoint |
|---|---|---|---|
On your host (e.g. pnpm run dev) |
MinIO on host (-p 9000:9000) |
http://127.0.0.1:9000 or http://localhost:9000 |
Yes — loopback is blocked by the default strict policy. |
| In a Docker container | MinIO on the same host, published port | http://host.docker.internal:9000 (Docker Desktop) or the host’s LAN IP |
Yes — localhost inside the Floh container is the container itself, not the host. |
| In Docker Compose, Floh and MinIO as two services on one network | MinIO service name minio, API port 9000 |
http://minio:9000 |
Yes — the name usually resolves to a private bridge / overlay IP. |
| On host or VM in a corporate LAN | Appliance at https://s3-gw.internal.example |
That URL | Yes if DNS resolves to RFC1918 or similar; No if it is a public IP and passes strict validation. |
| AWS (normal buckets) | AWS | Leave endpoint empty | No — not needed when using default regional endpoints. |
HTTPS vs HTTP: MinIO dev often uses http. Production endpoints should use https when the server presents a real TLS certificate.
forcePathStyle — bucket in path vs bucket in hostname¶
S3 supports two URL shapes:
- Virtual-hosted style —
https://my-bucket.s3.amazonaws.com/key(bucket is a subdomain). AWS’s global and regional endpoints expect this pattern for many workloads. - Path style —
https://s3.amazonaws.com/my-bucket/key(bucket is the first path segment). MinIO and many S3-compatible servers expect path style for custom endpoints.
In Floh, when endpoint is set and the host is not *.amazonaws.com, forcePathStyle defaults to true if you leave the field unset (create-client.ts). That matches typical MinIO / on-prem setups.
When to override:
- Set
forcePathStyleto false (explicitly) if you pointendpointat an AWS-managed hostname that still requires virtual-hosted addressing (for example some VPC interface endpoint URLs under*.amazonaws.com). The code avoids auto-forcing path style for*.amazonaws.comso the SDK can use hosted-style where required. - Leave
forcePathStyleunset for plain AWS with no customendpoint— the SDK chooses the correct addressing for regional S3.
allowPrivateNetworkEndpoint — relaxing URL validation for trusted backends¶
By default, Floh applies the same strict outbound URL rules as other HTTP connectors: localhost, RFC1918, and similar targets are rejected so a compromised workflow cannot scan your internal network (connector-endpoint-policy.ts + http-url-policy.ts).
Set allowPrivateNetworkEndpoint to true only when you intentionally configure endpoint to such a target (local MinIO, Docker service name → private IP, LAN appliance). The flag does not disable all checks: cloud metadata hostnames and link-local addresses (for example 169.254.169.254) remain blocked even when enabled.
Docker: almost every “Floh in Compose + MinIO in Compose” or “Floh container → MinIO on host” setup needs allowPrivateNetworkEndpoint: true.
Non-Docker / production AWS: leave it off or false; use an empty endpoint and a normal region so traffic goes to AWS’s public S3 endpoints and strict validation stays in force.
Quick recap¶
| Goal | endpoint |
forcePathStyle |
allowPrivateNetworkEndpoint |
|---|---|---|---|
| Real AWS S3 | empty | omit (SDK default) | false / omit |
| MinIO on laptop | http://127.0.0.1:9000 |
omit (defaults path-style) | true |
| Floh container → MinIO on host | http://host.docker.internal:9000 (or host IP) |
omit | true |
| Floh + MinIO both in Compose | http://minio:9000 |
omit | true |
Connection configuration¶
Create a connector instance via the Connectors API or UI with type s3.
| Field | Required | Secret | Purpose |
|---|---|---|---|
| region | Yes | No | AWS region for SigV4 and SDK routing (for example us-east-1). For MinIO, us-east-1 is commonly used even though MinIO is not region-bound. |
| access key id | Yes | No | IAM access key ID on AWS. On MinIO: same value as MINIO_ROOT_USER. |
| secret access key | Yes | Yes | IAM secret on AWS. On MinIO: same value as MINIO_ROOT_PASSWORD. |
| session token | No | Yes | STS temporary credentials (AWS_SESSION_TOKEN shape). |
| endpoint | No | No | Custom S3 API base URL. Empty = default AWS endpoint for region. See Custom endpoint, forcePathStyle, and allowPrivateNetworkEndpoint above. |
| force path style | No | No | Path-style vs virtual-hosted URLs. Omit for AWS-only; omit for MinIO (defaults path-style). See forcePathStyle in that same section. |
| allow private network endpoint | No | No | Allow localhost / RFC1918 / Docker-internal targets for endpoint. Required for typical local MinIO; off for public AWS only. See allowPrivateNetworkEndpoint in that same section. |
Do not put credentials in the endpoint URL; validation rejects userinfo in the URL.
Commands and parameters¶
The connector is defined in aws-s3.ts. The default command in the designer is getObject if no command is chosen.
test¶
Verifies credentials by listing buckets (ListBuckets).
| Param | Required | Description |
|---|---|---|
| (none) | — | — |
Outputs: ok, bucketCount, region.
listObjects¶
Lists object keys in a bucket (ListObjectsV2).
| Param | Required | Description |
|---|---|---|
| bucket | Yes | Bucket name. |
| prefix | No | Key prefix filter. |
| maxKeys | No | Page size; integer 1–1000. |
Outputs: objects, isTruncated, nextContinuationToken.
headObject¶
Reads object metadata without downloading the body (HeadObject).
| Param | Required | Description |
|---|---|---|
| bucket | Yes | Bucket name. |
| key | Yes | Object key. |
Outputs: object (metadata envelope from the SDK).
getObject¶
Downloads object bytes and metadata (GetObject).
| Param | Required | Description |
|---|---|---|
| bucket | Yes | Bucket name. |
| key | Yes | Object key. |
| partNumber | No | Multipart part number 1–10,000 when reading a specific part. |
Outputs: object (includes body handling implemented in operations.ts).
putObject¶
Uploads an object (PutObject). Exactly one body field must match body mode (enforced server-side as well as in the UI).
| Param | Required | Description |
|---|---|---|
| bucket | Yes | Bucket name. |
| key | Yes | Object key. |
| body mode | No | base64 (default), text, or json. |
| body base64 | When mode is base64 | Base64-encoded bytes. |
| body text | When mode is text | Non-empty UTF-8 text. |
| body json | When mode is json | JSON string; stored as canonical JSON.stringify bytes. |
| content type | No | IANA media type; for json mode defaults to application/json when omitted. |
| metadata | No | JSON object of string → string only; keys must match [A-Za-z0-9._-]+; total UTF-8 size of keys + values ≤ 2048 bytes (S3 limit). |
Outputs: written, etag, versionId.
deleteObject¶
Deletes one object (DeleteObject).
| Param | Required | Description |
|---|---|---|
| bucket | Yes | Bucket name. |
| key | Yes | Object key. |
Outputs: deleted, deleteMarker, versionId.
Manual QA checklist¶
- [ ] test returns a bucket count and the configured region.
- [ ] listObjects on a known bucket returns expected keys (or an empty page).
- [ ] putObject (small text or base64 file) then headObject / getObject round-trip.
- [ ] deleteObject removes the test object (or confirms delete marker behavior on versioned buckets).
Related code¶
| Area | Path |
|---|---|
| Connector definition & put-body resolution | packages/server/src/modules/connectors/handlers/aws-s3.ts |
| Connection schema | packages/server/src/modules/connectors/handlers/s3-support/connection.ts |
| Param schemas | packages/server/src/modules/connectors/handlers/s3-support/command-params.ts |
| S3 client construction & path style | packages/server/src/modules/connectors/handlers/s3-support/create-client.ts |
| Custom endpoint / private network policy | packages/server/src/modules/connectors/connector-endpoint-policy.ts |
| SDK calls | packages/server/src/modules/connectors/handlers/s3-support/operations.ts |
| Error mapping | packages/server/src/modules/connectors/handlers/s3-support/map-s3-error.ts |