What's Changed
New Contributors
[1.3.16] — 2026-04-27
Added
BIND_HOSTenv var to configure the listen interface —BIND_HOST=127.0.0.1 ministacknow restricts the listener to loopback forpip installusers on shared dev machines. Defaults to0.0.0.0, so existing setups are unchanged. Distinct fromMINISTACK_HOST(the virtual hostname used for S3 virtual-host / execute-api URL matching). Contributed by @mattwang44.- Lambda
Code.S3ObjectVersionhonoured end-to-end —CreateFunction,UpdateFunctionCode,PublishLayerVersion, and the CloudFormationAWS::Lambda::Functionprovisioner all thread the version through to S3, so Terraformaws_lambda_function.s3_object_versionand CDKCode.fromBucket(..., objectVersion=...)deploy the pinned bytes instead of silently picking up the latest.
Fixed
- Lambda 250 MB unzipped-size limit was not enforced —
CreateFunction/UpdateFunctionCode/PublishLayerVersionaccepted oversize zips and failed only at invocation time. All three now reject up-front withInvalidParameterValueException, matching AWS. - S3 with
S3_PERSIST=1: versioned object bodies capped at 10 MB andGetObject(VersionId)returned 500 for larger multipart uploads — bodies now persist to disk (in-memory record drops the body, on-demand reads stream back), versioned reads return the persisted bytes, and disk writes go through atomictmp+renamewith mode0o600/ dir0o700plus a path-traversal guard that rejects keys resolving outsideS3_DATA_DIR. - CloudFormation
AWS::Lambda::Functionnever fetched S3 code —_lambda_createstoredCode.S3Bucket/Code.S3Keyas metadata but never resolved them against the in-memory S3 service, so every CFN-deployed S3-backed Lambda hadcode_zip = Noneand failed to invoke. InlineZipFilewas unaffected; everything else broken. Provisioner now fetches the bytes via the standard Lambda S3 helper. - Persisted Cognito hosted-UI / federation
_auth_codeslost across warm-boot —_auth_codeshad a 5-minute TTL but was declared "ephemeral, not persisted", so any in-flight hosted-UI sign-in straddling a warm-boot was silently invalidated. Now wired intoget_state/restore_stateso codes survive a restart up to their normal TTL. Plain-dict choice (noAccountScopedDict) preserved with a corrected rationale: none of the OAuth2 endpoints carry SigV4, so wrapping inAccountScopedDictwould be functionally equivalent. Contributed by @bognari. PERSIST_STATE=1: twelve mutated state dicts were silently dropped on warm-boot. Five wired in by @bognari (secretsmanager._resource_policies,kinesis._consumers,ecs._attributes,sns._platform_applications,sns._platform_endpoints) — without these,aws_secretsmanager_secret_policy,aws_kinesis_stream_consumer, ECS PutAttributes, and mobile-push topology silently disappeared on restart. Pluscloudwatch_logs._destinations/_metric_filters/_queries(also @bognari) — log-destinations and metric filters wiped on restart. Plus the seven follow-ups for the same bug family:sqs._queue_name_to_url(snapshotted viadict(asd)instead ofcopy.deepcopy, dropping every non-current-tenant mapping),eventbridge._event_bus_policies/_connections/_api_destinations(everyaws_cloudwatch_event_connectionandaws_cloudwatch_event_api_destinationlost),ssm._parameter_historyand_tags(GetParameterHistoryreturned empty after warm-boot), andlambda_svc._kinesis_positions/_dynamodb_stream_positions(every restart replayed event-source-mapping streams fromStartingPosition, a real at-least-once-delivery violation).- Persisted services failed to restore on startup for autoscaling / backup / eks / scheduler / pipes — these five services declared
restore_statebut never invoked it on import, so warm-boots came up with empty state regardless ofPERSIST_STATE=1. Wired in. Contributed by @bognari. - Eager-imported non-routable persisted services on startup — services without an HTTP route never imported, so their
load_stateblock never fired and persisted state evaporated. Eager-import now triggers restore. Contributed by @bognari. NameErrorat import on warm-boot for any persisted service whoserestore_statereferenced a forward-declared symbol — parametrized regression test added across every persisted service to catch the import-order shape that previously hitlambda_svc._ensure_poller,ecs._attributes, andacm._synthetic_pem. Contributed by @bognari.- ACM
GetCertificatereturned a placeholder PEM and leaked private-key bytes to disk onRequestCertificateissuance — body / chain fidelity now matches real AWS shape, and the private-key disk-leak path is scrubbed. Contributed by @bognari. - API Gateway v2 integration
physicalIdreturned{apiId}/{integrationId}instead of just{integrationId}— brokeRefresolution againstaws_apigatewayv2_integration, so route → integration lookup failed at request time and CFN-deployed HTTP APIs returned500 No integration configuredfor every request.Refnow matches AWS;handle_executeand_invoke_ws_lambdadefensively strip a legacy{apiId}/prefix so existing stacks continue to work. Contributed by @hiddengearz. - API Gateway v1
PutIntegrationdroppedcontentHandling— the field was accepted on create but never persisted, soCONVERT_TO_TEXT/CONVERT_TO_BINARYpayload translation silently no-op'd. Contributed by @bognari. - SNS → SQS raw delivery did not forward message attributes — raw subscriptions delivered the message body but stripped
MessageAttributes, so SQS receivers never saw them. Forwarded now, plus the follow-up that adds the matchingMD5OfMessageAttributesheader so Java / Go SDK receivers (which verify the digest) match real AWS. Contributed by @arischow. - Three medium / low correctness bugs.
apigatewayandapigateway_v1get_state()returned liveAccountScopedDictreferences instead of deep copies, so a concurrent write during shutdown serialisation could corrupt the persisted snapshot.secretsmanager._delete_secret(force=True)deleted the secret but left orphan entries in_resource_policieskeyed by ARN — invisible to the API but accumulating in memory and surviving warm-boot.acm._list_certificatesreturned{"NextToken": null}unconditionally — boto3 strips it client-side, but Java / Go / raw-HTTP pagination clients that loop onif NextToken in responselooped forever. Contributed by @bognari. Pattern extended in this release with a sweep acrossses_v2,apigatewayv2, andapigatewayv1 (ten more endpoints) so every list response now omitsNextTokenwhen there is no next page; AppSync's GraphQL{items, nextToken}shape is intentionally unchanged. /healthreportedversion: devin the published Docker image —pipis stripped from the runtime image, so theimportlib.metadatalookup that worked underpip install ministackreturned the fallback. Now reads from aMINISTACK_VERSIONenv var injected at image build time.