August 14, 2026 · v1.4.17
v1.4.17 hardens EventBridge API destination delivery so caller-supplied endpoints and credentials are validated and contained, enforces API Gateway (HTTP API / v2) custom Lambda authorizers, and lands a large S3 conformance batch. On top of that: broader CloudFormation resource coverage (LayerVersionPermission, IoT and Cognito types, S3 bucket notifications, and stack-metadata persistence) and two new Step Functions intrinsics.
AWS::Lambda::LayerVersionPermission now calls AddLayerVersionPermission (Ref returns <layer version ARN>#<statement id>), and layer policies gained a real RevisionId, principal validation, and AWS's root-ARN statement shape. AWS::IoT::ThingType, AWS::IoT::Policy, and AWS::Cognito::IdentityPoolRoleAttachment each provision onto their own service instead of failing a stack with Unsupported resource type. Contributed by @iot-rocket.aws-sdk:route53 tasks and the Base64 intrinsics. A Step Functions task can now call the Route 53 SDK integration (e.g. ChangeResourceRecordSets), and the States.Base64Encode / States.Base64Decode intrinsic functions are implemented (UTF-8, a 10,000-character input cap, lenient decode padding). Contributed by @bandle.GetLogGroupFields. Returns field names found in recent stored events with a rough presence percent, honoring logGroupName / logGroupIdentifier, an optional time window, system @* fields, and flattened JSON message keys. Contributed by @ovsteenb.3xx to another host could carry the Authorization header to the redirect target), InvocationEndpoint and the OAuth AuthorizationEndpoint must be dialable http(s):// URLs, HttpMethod and AuthorizationType are validated against their enums, a connection ApiKeyName can no longer override EventBridge's reserved headers, DeauthorizeConnection clears the stored credentials, and the OAuth token response is read with a 1 MiB bound. Contributed by @t-rech.REQUEST) authorizers are invoked and enforced. A route referencing a REQUEST authorizer (authorization type CUSTOM) fell through unauthenticated because the data path only branched on JWT. It now honors authorizerPayloadFormatVersion (1.0 vs. 2.0), enableSimpleResponses ({isAuthorized, context}) vs. an IAM policy, and authorizerResultTtlInSeconds caching, injecting requestContext.authorizer.lambda for the integration. Contributed by @ryan-bennett.encoding-type=url now leaves the forward slash intact (so a delimiter-collapsed "folder" listing is readable); a delimited listing's NextMarker is the common prefix, not an underlying key; CopyObject honors the copy-source date preconditions; a canned ACL expands to its group grants (public-read → AllUsers READ); a malformed Content-MD5 is InvalidDigest rather than BadDigest; CompleteMultipartUpload's Location reflects the request host; and PutObject echoes the bucket's default-encryption header. Reported by @gaul.AWS::S3::Bucket NotificationConfiguration is applied, and stack metadata persists. The bucket provisioner dropped NotificationConfiguration silently (so S3 → Lambda/SQS/SNS/EventBridge never fired); it is now routed through the same path PutBucketNotificationConfiguration takes, on create, update, and removal (reported by @VictorAlejMadrid). Separately, with PERSIST_STATE=1 the stack records, events, exports, and change sets now survive a restart, so ListStacks / DescribeStacks / ListExports are no longer empty after a warm boot (reported by @iot-rocket).X-Amz-Function-Error: Unhandled. The Docker/RIE executor read the error class off a header the RIE never sets, so every failure was reported Handled and API Gateway consumers keying off the 502-for-Unhandled contract never took the error path; headerless payloads are now classified by shape. Contributed by @iot-rocket.CreateThingType is idempotent for identical re-creates. Re-creating an existing thing type always returned ResourceAlreadyExistsException; identical thingTypeProperties now return the existing ids and only a real mismatch keeps the 409. Contributed by @iot-rocket.RevokeSecurityGroupIngress / RevokeSecurityGroupEgress honor SecurityGroupRuleIds. Both read only IpPermissions, so a revoke by rule id (as Terraform does) returned Return=true while removing nothing; ids now resolve against the group's sgr-* rules. Contributed by @iot-rocket./oauth2/userInfo returns custom attributes and the plain username. The response filtered attributes through a fixed standard-OIDC allowlist, dropping custom: attributes; it now returns them (as AWS does for openid and openid profile), plus the plain username claim and middle_name. Contributed by @rjmackay.docker pull ministackorg/ministack:1.4.17 docker run -d -p 4566:4566 ministackorg/ministack:1.4.17
Or pin in compose.yaml:
services:
ministack:
image: ministackorg/ministack:1.4.17
ports:
- "4566:4566"
Issues and PRs welcome on GitHub. Discussion on r/ministack.