Skip to main content

Transparent S3 Access Grants for fsspec/s3fs — per-grant scoped credentials, no Access Grants logic in application code.

Project description

s3fs-access-grants

Transparent S3 Access Grants for fsspec / s3fs.

Register the implementation for s3:// once and every fsspec consumer — pandas, polars, universal-pathlib, fsspec.open, ... — routes each call through a credential scoped to the matching grant. No Access Grants logic leaks into application code.

How it works

ScopedS3FileSystem subclasses s3fs.S3FileSystem. On construction it enumerates the caller's grants (ListCallerAccessGrants) and builds a longest-prefix routing table. Each S3 operation is matched to a grant scope and served by a per-scope aiobotocore client whose credentials come from GetDataAccess and auto-refresh on expiry. Calls that match no grant fall through to the default IAM client (fail-closed), and cross-scope copies are rejected.

If the caller has no grants (or no permission to list them), register() installs nothing and plain s3fs handles s3:// with zero added overhead. The same holds when there is no AWS access at all (no credentials, no region, or an unreachable endpoint): register() fails open and leaves the default s3fs in place, so it is safe to call unconditionally in tests and CI.

Install

pip install s3fs-access-grants
# or
uv add s3fs-access-grants

Usage

Registration is explicit — importing the package does no AWS I/O.

import s3fs_access_grants

# Install the s3:// handler for the calling identity's grants.
s3fs_access_grants.register()

import polars as pl
df = pl.read_parquet("s3://bucket/teamA/data.parquet")  # scoped automatically

Pass the grants-instance account/region explicitly (e.g. in a notebook, or when the grants instance lives in a different account than your role):

import s3fs_access_grants

s3fs_access_grants.register(account_id="123456789012", region="eu-west-1")

register() is the only entry point and returns nothing — it's a one-time setup call. It resolves the account/region, then binds them into the handler it registers, so a later argless fsspec.filesystem("s3") (what pandas / polars use under the hood) builds the filesystem with the right values. After calling it, just use fsspec / pandas / polars as normal.

Configuration

register() resolves the grants-instance account and region in this order:

Setting Resolution order
Account ID explicit arg → S3FS_ACCESS_GRANTS_ACCOUNT_ID → STS caller
Region explicit arg → S3FS_ACCESS_GRANTS_REGION → session default

The grants instance may live in a different account than the caller's role, so the explicit arg / env is authoritative; the STS caller account is only a same-account fallback.

Advanced: manual construction

register() covers the common case. To build a scoped filesystem by hand — e.g. pointing at a different grants account without touching the global s3:// registration — construct ScopedS3FileSystem directly:

from s3fs_access_grants import ScopedS3FileSystem

fs = ScopedS3FileSystem(grants_account_id="123456789012", grants_region="eu-west-1")

Compatibility

This subclass depends on s3fs internals (_call_s3 and _iterdir resolving their client via get_s3()). Validated against s3fs 2026.6.0 / aiobotocore 2.25.1. Re-check on any s3fs major bump.

Development

bun install          # installs JS tooling + runs uv sync + lefthook install
bun run check        # lint + typecheck (ruff, ty, editorconfig)
bun run test         # pytest with coverage
bun run build        # uv build (wheel + sdist)

Releases are managed with changesets: add one with bun run changeset:add, and merging the generated "version packages" PR bumps the version, syncs it into pyproject.toml, and publishes to PyPI.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

s3fs_access_grants-0.1.1.tar.gz (118.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

s3fs_access_grants-0.1.1-py3-none-any.whl (10.3 kB view details)

Uploaded Python 3

File details

Details for the file s3fs_access_grants-0.1.1.tar.gz.

File metadata

  • Download URL: s3fs_access_grants-0.1.1.tar.gz
  • Upload date:
  • Size: 118.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for s3fs_access_grants-0.1.1.tar.gz
Algorithm Hash digest
SHA256 186dec8fcc577657d7ff43d0972f2358994a5558c1e754bca27a3cd647bddb41
MD5 0f08a29de31d413b8eb10dd5fe63ef2c
BLAKE2b-256 41ecdd0c0164876c3125563a8db304edd8f7a5c83e16617019c3786859f5f411

See more details on using hashes here.

Provenance

The following attestation bundles were made for s3fs_access_grants-0.1.1.tar.gz:

Publisher: release.yaml on undeadpixel/s3fs-access-grants

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file s3fs_access_grants-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for s3fs_access_grants-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f09be1b87a7878a04b2d10bd703044c83abba4bb3b6deaa60c073c9f19927d67
MD5 230a45280903633b1a572fd16af161b3
BLAKE2b-256 8551350a881d6c558e077c3c40e998533f51f590b6708b58ba4b6e60f9beb705

See more details on using hashes here.

Provenance

The following attestation bundles were made for s3fs_access_grants-0.1.1-py3-none-any.whl:

Publisher: release.yaml on undeadpixel/s3fs-access-grants

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page