September 20, 2026 · v1.5.14
v1.5.14 is an issue-sweep release. Ten reported issues are fixed in it, and most of them were cases where MiniStack accepted a request and then quietly did nothing with part of it: an API Gateway usage plan that throttled nothing, a Bedrock Retrieve filter that was parsed and ignored, an AppConfig feature-flag profile served in the wrong format, an S3 notification that read back empty for anything but the SDK that wrote it. Alongside those, KMS gained the real external key-material flow, PostgreSQL instances serve TLS, and IoT job executions actually time out.
Origin=EXTERNAL stayed unusable because there was no way to supply its material. GetParametersForImport, ImportKeyMaterial and DeleteImportedKeyMaterial complete the flow: the key waits in PendingImport, all five wrapping algorithms unwrap, and ExpirationModel and ValidTo are reported. Reported by @guymahieu.RequestValidator operations are implemented, a method's requestValidatorId is applied to the body and parameters, and an API key is checked against its usage plan's rate, burst and quota. Reported by @iot-rocket.sslmode=verify-full completes the handshake; GET /_ministack/rds/ca.pem returns that CA. Separately, a verified IAM database token is authorized against the policy's resource, so a grant scoped to one database user stops matching another. Reported by @jayjanssen. Contributed by @Areson.vectorSearchConfiguration.filter was parsed and ignored, so every query returned the whole knowledge base; all eleven comparators plus andAll and orAll now select against a document's .metadata.json sidecar. A Converse call carrying tools was proxied without them, so the model could never answer with a tool use. Reported by @Vidminas.timeoutConfig.inProgressTimeoutInMinutes and the device's own stepTimeoutInMinutes were stored and ignored, so an execution stayed IN_PROGRESS for ever. An execution past its timeout is now TIMED_OUT, and the device plane reports approximateSecondsBeforeTimedOut while it runs./_ministack/health carries iot_mtls, and /_ministack/ready waits for that listener, so a consumer polling readiness no longer races the MQTT port.Resource, NotResource, StringLike, StringNotLike, ArnEquals and ArnLike compared case-insensitively, so a policy naming arn:aws:s3:::MyBucket also matched mybucket. Only Action stays case-insensitive, as on AWS.TRANSCRIBE_JOB_RUN_SECONDS, GLUE_CRAWLER_RUN_SECONDS, MINISTACK_DDB_IMPORT_COMPLETE_AFTER_SEC and LAMBDA_STATE_TRANSITION_SECONDS paced emulator-only state transitions and had no AWS counterpart. The transitions keep their previous pacing.Id read back missing, where AWS assigns base64 of a UUID, and the request XML was echoed back verbatim, so a configuration sent with LambdaFunctionConfigurations came back empty for a client expecting the wire name CloudFunctionConfiguration — which also hid a CloudFormation-declared Lambda notification. Reported by @jin-gizmo.{flags, values, version} document was returned verbatim, so a client reading a flag found nothing at the top level. Reported by @dk-tanio.CreateAgentRuntime answered with a JSON number while ListAgentRuntimes answered with a string for the same field, so a typed SDK failed on one of the two. Reported by @ykalemi.HttpParameters JSON paths went to the endpoint as literal $. strings. They now resolve against the original event, before input transformation. Contributed by @dmgarland.*.rds.amazonaws.com name handed out at creation, breaking connection strings and hostname-verified TLS. Separately, numberOfRecordsUpdated carried the row count for a SELECT, where AWS reports 0. Contributed by @jayjanssen.Snapshot, defaulted to Delete here. Both now snapshot and then delete, on a stack delete and on an update that removes the resource.AWS::WAFv2::WebACL returned a bare id where AWS returns name|id|scope, ExecuteChangeSet sent the shape name InvalidChangeSetStatusException as its error code, the Rules section evaluated Fn::If where a real account refuses it, and the 60 dynamic references per template quota was not enforced.PutImage failed and a delete left images behind. Separately, an update handler deleted the predecessor as soon as the replacement existed, so a later failure rolled back to a resource that was gone. Contributed by @iot-rocket.500 AUTHORIZER_FAILURE, a missing backend 500 API_CONFIGURATION_ERROR, an unknown stage 403 Forbidden, and a MOCK integration honours its own statusCode. Contributed by @iot-rocket.!= and == were evaluated where AWS refuses both, and a nested SELECT in a WHERE clause was accepted. A failed action was reported as {action, errorMessage}, where AWS names failedAction and failedResource, with a clientId of N/A and a sourceIp.UpdateJobExecution with a status a device cannot set now answers InvalidStateTransitionException 409, and an unknown executionNumber ResourceNotFoundException 404.http even with USE_SSL=1, so the document contradicted its own https issuer and a discovery client refused it. Reported by @epcap90.LambdaInsightsExtension, the Parameters and Secrets, AppConfig or OpenTelemetry extensions or AWSSDKPandas could not deploy, because the publisher account is unknown offline. It resolves by layer name with CodeSize 0, so the extension does not run.AlreadyExistsFault instead of the wire code AlreadyExists; a bare -e NAME EC2 docker flag was passed as an empty string instead of taking the host value; an unknown S3 Control /v20180820 path answered generically instead of InvalidURI; and Signer kept every clientRequestToken for ever.docker pull ministackorg/ministack:1.5.14 docker run -d -p 4566:4566 ministackorg/ministack:1.5.14
Or pin in compose.yaml:
services:
ministack:
image: ministackorg/ministack:1.5.14
ports:
- "4566:4566"
Issues and PRs welcome on GitHub. Discussion on r/ministack.