June 1, 2026 · v1.3.55
A new control-plane service (AWS Elemental MediaConnect), two EKS additions that unblock terraform IRSA modules, and four API Gateway Lambda-proxy correctness fixes — three contributed and all verified against real AWS.
5 ops at /v1/flows[/{FlowArn}] and /tags/{ResourceArn}: CreateFlow, DescribeFlow, ListFlows, UpdateFlow, ListTagsForResource. ListFlows returns the slimmer AWS ListedFlow projection (no Outputs / Sources / Entitlements); UpdateFlow is narrow to the AWS-allowed top-level fields (SourceFailoverConfig, Maintenance, SourceMonitoringConfig, NdiConfig); records use the wire-form camelCase keys per the AWS REST-JSON model. No real streaming or transcoder — flows are control-plane metadata, enough to integration-test services that wrap the MediaConnect API. Reported by @tashif-hoda.
AssociateEncryptionConfig + OIDC discovery / JWKS for IRSATwo EKS gaps that broke common terraform modules:
POST /clusters/{name}/encryption-config/associate records KMS secrets-encryption config, returns the AWS-shape update envelope, and rejects re-association — matching AWS, which only lets you add encryption to a cluster that has none.identity.oidc.issuer now points at a ministack-hosted URL (/oidc/id/{32-char-id}) instead of the real oidc.eks.{region}.amazonaws.com, which is unreachable from clients and was breaking aws_iam_openid_connect_provider at thumbprint time. GET <issuer>/.well-known/openid-configuration and GET <issuer>/keys are served at AWS-shape paths, with authorization_endpoint: "urn:kubernetes:programmatic_authorization" and claims_supported: ["sub","iss"] matching the real EKS discovery document. A single RSA keypair is generated lazily on first request — sufficient for terraform / opentofu to fetch the document.Reported by @b-rajesh.
Set-Cookie from headers and the cookies array now both shipObserved real-AWS behavior for HTTP API (v2) Lambda-proxy: when a function returns both the cookies array and a Set-Cookie in headers, AWS emits the array entries first followed by any header Set-Cookie. An earlier supersede approach silently dropped the header cookie. Now both reach the wire, array first, case-insensitive on the header key.
isBase64Encoded honored in both directionsBinary uploads through HTTP API were being corrupted: the inbound body was always body.decode("utf-8") with isBase64Encoded: false, destroying any non-UTF-8 byte before Lambda saw it. Outbound base64 responses were emitted as the literal base64 string. Both directions are now correct:
text/* and application/json / application/xml / application/javascript arrive as UTF-8 strings; everything else — including a missing Content-Type and application/x-www-form-urlencoded — is base64-encoded with isBase64Encoded: true. The text-vs-binary split was verified against real AWS.isBase64Encoded: true bodies are decoded to raw bytes before sending. HTTP API has no binaryMediaTypes negotiation — it's unconditional.Contributed by @rmlasseter.
binaryMediaTypes is now wiredbinaryMediaTypes on a REST API was stored on the API record but never consulted at Lambda-proxy invocation, so binary uploads and binary responses were both broken on v1 too. Now both directions are wired per the AWS contract:
Content-Type matches a configured binaryMediaType (exact, type/*, or */*), the body is delivered base64-encoded with isBase64Encoded: true; otherwise as a UTF-8 string.isBase64Encoded: true) is decoded to raw bytes only when the request Accept also matches a binaryMediaType. A request Accept of */* does NOT auto-match specific configured types — verified against real AWS.Contributed by @rmlasseter.
A lowercase content-type from a Lambda response was shipping alongside ministack's seeded default Content-Type instead of replacing it — two Content-Type headers on the wire. HTTP field names are case-insensitive per RFC 9110 §5.1, so the function's header now overrides any case-mismatched default. Same fix on both v1 and v2 builders. Contributed by @rmlasseter.
docker pull ministackorg/ministack:1.3.55 docker run -d -p 4566:4566 ministackorg/ministack:1.3.55
Or pin in compose.yaml:
services:
ministack:
image: ministackorg/ministack:1.3.55
ports:
- "4566:4566"
Issues and PRs welcome on GitHub. Discussion on r/ministack.