DocsAWS 101Blog
← Back to Blog

v1.3.17 — :full Docker image, S3 vhost on any endpoint, Lambda routing sweep, STS session identity

April 28, 2026 · v1.3.17

1.3.17 fixes a cluster of routing and integration gaps. The :full Docker image with DuckDB / psycopg2 / pymysql lands so Athena and native database drivers stop fighting Alpine's musl wheels. S3 virtual-hosted routing now works against any endpoint hostname (not just localhost), unblocking AWS SDK for JavaScript v3 and Docker Compose service-name setups. Lambda's path-based routing was only matching /2015-03-31/functions — every other API version (EventInvokeConfig, ProvisionedConcurrency, FunctionUrl, Layers, Tags, Runtime) silently fell through to S3 for unsigned clients. CloudFormation Lambdas backed by S3 finally fetch their code instead of returning a mock. STS GetCallerIdentity now reflects the assumed role. And GetWebIdentityToken joins the STS surface for OIDC dev flows.

1. ministackorg/ministack:full — DuckDB-backed Athena, no source builds

The default image is Alpine-based, which keeps it small (~110 MB) but also keeps it free of manylinux-only wheels. DuckDB and psycopg2-binary ship manylinux but not musllinux; on Alpine they fall back to slow source builds or silently disable themselves. Athena's DuckDB engine has been hitting that pain since the engine landed.

1.3.17 publishes a Debian/glibc variant alongside the regular image:

docker pull ministackorg/ministack:full

It's a functional superset of the regular image — same SFTP support, same env-var contract, same healthcheck — plus duckdb, psycopg2-binary, and pymysql. The :full tag tracks the latest release; pinned variants are also published as :1.3.17-full and :1.3-full. The regular :latest and :1.3.17 tags are unchanged. Closes the long-standing Athena-on-Alpine gap raised by @arischow.

The full image self-identifies via /_ministack/health:

{ "edition": "full", "version": "1.3.17", "services": { ... } }

2. S3 virtual-hosted routing now works on any endpoint hostname

S3 virtual-hosted-style URLs are the default for AWS SDK for JavaScript v3 and Terraform AWS provider v4+. The bucket is the first label of the Host header: Host: mybucket.s3.us-east-1.amazonaws.com. Against MiniStack the SDK drops in your endpoint, so the Host arrives as Host: mybucket.localhost:4566 — or, when you point the SDK at the Docker Compose service name, Host: mybucket.ministack:4566.

Before 1.3.17 the regex that detected S3 vhost was anchored to _MINISTACK_HOST (default localhost), so anything else fell through to S3 path-style with the wrong bucket. JS SDK v3 setups using a Compose service name silently broke; reported by @mgius-ae.

The replacement validates the first label against the AWS bucket-naming rules (3–63 chars, lowercase + digits + dots + hyphens, alphanum start/end, no .., not IPv4) and accepts any tail — so vhost works against localhost, ministack, custom DNS, or s3.amazonaws.com without configuration. Verified against 40 host-header cases including IPv6 brackets, mixed-case headers, control characters, and length boundaries.

3. Lambda routing missed every API path that wasn't /2015-03-31/functions

The path-based service detector only matched the original Lambda API version date. Every other version date silently fell through to S3 when the request didn't carry a SigV4 Authorization header:

boto3 always signs and routed via the SigV4 credential scope (which encodes the service name), so most users never noticed. But raw HTTP / curl / Lambda Runtime traffic missed. The detector now matches ^/{date}/{lambda-resource}/... for every documented Lambda resource.

4. CloudFormation Lambdas backed by S3 — actually fetched now

A quiet showstopper for CDK users. The CloudFormation provisioner for AWS::Lambda::Function accepted Code.S3Bucket / Code.S3Key and stored them as metadata on the function record — but never actually fetched the bytes. Every CFN-deployed Lambda backed by S3 had code_zip = None and returned a hardcoded "Mock response - no code deployed" on invocation. Inline ZipFile was unaffected; the S3 path simply never worked.

1.3.17 fixes the provisioner to actually call the Lambda S3 helper — the same one CreateFunction and UpdateFunctionCode already used. Contributed by @hiddengearz. Pairs with the S3ObjectVersion threading that landed in 1.3.16 — together they make CDK Code.fromBucket(..., objectVersion=...) a fully working path.

5. STS session identity, finally

Two STS fixes that matter for any test harness asserting on identity:

GetCallerIdentity now returns the assumed-role ARN. Before 1.3.17 it always returned arn:aws:iam::000000000000:root, regardless of which credentials made the call — so tests that obtain temporary credentials via AssumeRole and then verify the assumed role could never confirm the role. The handler now extracts the AccessKeyId from the SigV4 Authorization header and looks it up in a session map populated at AssumeRole / AssumeRoleWithWebIdentity time, returning the matching arn:aws:sts::{account}:assumed-role/{role}/{session} and {role-id}:{session} UserId. Contributed by @hectormauer.

GetWebIdentityToken action added. Implements the AWS-spec validation: SigningAlgorithm is required and must be RS256 or ES384; Audience.member.N is required, 1–10 items × 1–1000 chars; DurationSeconds is bounded 60–3600 (default 300). Returns a parseable JWT with the expected claims (sub, aud, iss, iat, exp) for OIDC dev flows. The signature is HS256 — sufficient for emulator workloads that inspect claims, not for clients that verify against AWS JWKS. Requested by @anghel93.

6. Wire-format compliance — four small bugs the JVM and CLI noticed

Also in this release

Upgrade

# Regular image (Alpine, ~110 MB)
docker pull ministackorg/ministack:1.3.17

# Full image (Debian + DuckDB + psycopg2 + pymysql, ~360 MB)
docker pull ministackorg/ministack:1.3.17-full

# pip
pip install -U ministack

Full changelog: CHANGELOG.md.

Shipped by the MiniStack community. Contributions credited throughout. GitHub · r/ministack