Skip to content

feature(s3tables): read-only Amazon S3 Tables support via icebird/s3tables subpath#29

Merged
platypii merged 9 commits into
hyparam:masterfrom
The-Alchemist:cursor/add-s3-tables-support
Jul 11, 2026
Merged

feature(s3tables): read-only Amazon S3 Tables support via icebird/s3tables subpath#29
platypii merged 9 commits into
hyparam:masterfrom
The-Alchemist:cursor/add-s3-tables-support

Conversation

@The-Alchemist

@The-Alchemist The-Alchemist commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an optional icebird/s3tables subpath that connects to the Amazon S3 Tables Iceberg REST catalog and reads table data. The core icebird package stays AWS-free.

  • New icebird/s3tables subpath export backed by src/aws/* modules.
  • Requests are signed with icebird's own SigV4 implementation (src/sigv4.js) — no AWS signing SDK.
  • The only optional dependency is @aws-sdk/credential-providers, used solely to resolve the default AWS credential chain. It is imported lazily, so passing explicit credentials needs no AWS SDK at all.
  • Generic signRequest hook on the REST catalog (restCatalogConnect / restFetch) — a cloud-agnostic per-request auth hook.
  • Extracted the hand-rolled SigV4 primitives from src/s3.js into src/sigv4.js, reused for both S3 data reads (service s3) and the S3 Tables catalog (service s3tables).

Fixes found while reading a live S3 Tables bucket

  • SigV4 403: double-URI-encode the canonical path for non-s3 services. S3 Tables catalog paths carry the URL-encoded warehouse prefix; S3 uses single-encoding, every other service double-encodes.
  • 301 redirects: use the regional S3 endpoint so buckets outside us-east-1 (incl. S3 Tables --table-s3 buckets) don't redirect.
  • Avro decode: handle boxed primitives ({"type":"string"}), maps, and enums, which S3 Tables manifests emit.

Questions

  • Maintainer feedback on API surface / packaging approach
    • we didn't want to add aws as a dependency to the whole icebird package
  • Decide whether to keep scripts/s3tables-smoke.mjs in-tree

@The-Alchemist The-Alchemist force-pushed the cursor/add-s3-tables-support branch from 43d5f83 to e3bdbc3 Compare July 2, 2026 21:02
@The-Alchemist The-Alchemist changed the title WIP: Read-only Amazon S3 Tables support via icebird/s3tables subpath feature(s3tables): read-only Amazon S3 Tables support via icebird/s3tables subpath Jul 2, 2026
@The-Alchemist The-Alchemist marked this pull request as ready for review July 2, 2026 21:21
Adds an optional `icebird/s3tables` subpath that connects to the S3 Tables
Iceberg REST catalog and reads table data. The core `icebird` package stays
AWS-free: requests are signed with icebird's own SigV4 implementation, and the
only optional peer dependency is `@aws-sdk/credential-providers` (imported
lazily, and only when resolving the default credential chain — explicit
credentials need no AWS SDK at all).

- New `icebird/s3tables` subpath export and `src/aws/*` modules.
- Generic `signRequest` hook on the REST catalog (`restCatalogConnect` /
  `restFetch`) so signing stays cloud-agnostic.
- Extract the hand-rolled SigV4 primitives into `src/sigv4.js` and reuse them
  for both S3 data reads (service `s3`) and the S3 Tables catalog (`s3tables`).

Fixes found while reading a live S3 Tables bucket:
- double-URI-encode the canonical path for non-`s3` services (S3 Tables 403'd
  on catalog paths containing the URL-encoded warehouse prefix)
- use the regional S3 endpoint so non us-east-1 buckets don't 301 redirect
- decode boxed primitives, maps, and enums in the Avro reader, which S3 Tables
  manifests use

Signed-off-by: Karl Pietrzak <karl@medplum.com>
@The-Alchemist The-Alchemist force-pushed the cursor/add-s3-tables-support branch from e3bdbc3 to 4b9e629 Compare July 2, 2026 21:48
Signed-off-by: Karl Pietrzak <karl@medplum.com>
The v0.8.12 characterization test expects multiple aggregates on one
column to share a single scanColumn pass, but that behavior only landed
in squirreling 0.12.26.

Signed-off-by: Karl Pietrzak <karl@medplum.com>
@The-Alchemist The-Alchemist force-pushed the cursor/add-s3-tables-support branch from 458e1a6 to d0b84ca Compare July 3, 2026 20:34
@platypii platypii force-pushed the cursor/add-s3-tables-support branch from d0b84ca to 805f700 Compare July 11, 2026 22:18
@platypii platypii force-pushed the cursor/add-s3-tables-support branch from 805f700 to b0be936 Compare July 11, 2026 22:20

@platypii platypii left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good thanks @The-Alchemist !

I tested this against real s3tables. First confirmed that master failed. Then your branch, and indeed looks good!

I pushed some modifications to the branch, hope that was ok.

  • merge master and fix conflicts
  • fix lint error
  • remove s3tables smoke script
  • move AWS typedefs to src/aws/types.d.ts
  • don't require tableBucketArn in s3TablesResolver options

@platypii platypii merged commit a07d494 into hyparam:master Jul 11, 2026
3 checks passed
@platypii

Copy link
Copy Markdown
Contributor

Published in icebird 0.8.15 thanks again @The-Alchemist!

@The-Alchemist

Copy link
Copy Markdown
Contributor Author

np, @platypii ! the next step for us is a version with S3 Tables support that also understands Lake Formation grants (https://docs.aws.amazon.com/lake-formation/latest/dg/enable-s3-tables-catalog-integration.html), the recommended approach for handling fine-grained permissions.

unfortunately, that's another dependency (@aws-sdk/client-lakeformation). what's the best way to handle that? should it be part of aws/s3tables.js, or a separate aws/lake_formation.js?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants