May 3, 2026 · v1.3.25
1.3.25 ships four additions and a sweep of EventBridge spec fixes verified against botocore/data/events/service-2.json and the live AWS docs.
Full Event API surface: management plane under /v2/apis (Create / Get / List / Update / Delete Api, channel namespace CRUD, API keys via the AWS SDK's /v1/apis/{apiId}/apikeys path), HTTP publish on POST /event at {apiId}.appsync-api.*, and the realtime WebSocket on {apiId}.appsync-realtime-api.* using the aws-appsync-event-ws subprotocol.
Verified against the AWS Events realtime protocol docs:
aws-appsync-event-ws + header-<base64url(json)> auth subprotocolconnection_init / connection_ack with connectionTimeoutMs: 300000ka keep-alive cadencesubscribe / subscribe_success / subscribe_error, publish / publish_success / publish_error, unsubscribe / unsubscribe_success / unsubscribe_error (with UnknownOperationError on unknown sub IDs), and server-pushed data frames* wildcard on subscribesubscribe_error instead of silently overwritingLambda authorizer payload matches AWS spec exactly (authorizationToken, requestContext with apiId / accountId / requestId / operation / channelNamespaceName / channel, plus requestHeaders); operation values are EVENT_CONNECT / EVENT_SUBSCRIBE / EVENT_PUBLISH; response field is handlerContext per spec. Strict-auth gate via APPSYNC_EVENTS_ENFORCE_AUTH=1. Contributed by @marcin-nowak-scl.
Two distinct AWS SDK services, both shipping in this release.
Management plane lives inside the existing cloudfront service: CreateKeyValueStore, DescribeKeyValueStore, ListKeyValueStores, UpdateKeyValueStore, DeleteKeyValueStore under /2020-05-31/key-value-store/. ETag-based optimistic concurrency on update + delete; CannotDeleteEntityWhileInUse when a CloudFront Function references the store. KeyValueStoreAssociations are now round-tripped through CreateFunction / UpdateFunction.
Data plane is a separate cloudfront-keyvaluestore SDK service (signing name cloudfront-keyvaluestore, REST/JSON): DescribeKeyValueStore, ListKeys, GetKey, PutKey, DeleteKey, UpdateKeys under /key-value-stores/{KvsARN}. ETag concurrency on every mutating op; UpdateKeys is atomic (validates the whole batch, rejects with ValidationException on the first invalid entry); ListKeys paginates with opaque NextToken capped at 50 results per AWS spec; DeleteKey on a missing key returns ResourceNotFoundException (404) instead of silent 200. Contributed by @DaviReisVieira.
$ aws --endpoint-url=http://localhost:4566 cloudfront create-key-value-store \
--name routing-config --comment "edge routes"
$ aws --endpoint-url=http://localhost:4566 cloudfront-keyvaluestore put-key \
--kvs-arn "arn:aws:cloudfront::000000000000:key-value-store/routing-config" \
--key "/home" --value "/index.html" --if-match <etag>
cron() — full AWS-spec parity1.3.23 shipped rate() auto-fire and parsed cron() but didn't fire it. 1.3.25 closes the loop with the complete AWS cron syntax — zero new dependencies.
cron(Min Hr DoM Mon DoW Year)* and ?, lists, ranges (MON-FRI), steps (*/5, 5/10), named month/weekday tokensL (last day of month) and LW (last weekday)<n>W (nearest weekday to day n, never crossing month boundary)<n>L (last n-of-month, e.g. 6L = last Friday in AWS DoW where 6 = FRI)<n>#<k> (kth n-of-month, e.g. 2#1 = first Monday)PutRule per AWS — exactly one of the two fields must be ? or the rule is rejected with ValidationExceptionExamples that now fire correctly:
cron(0 0 L * ? *) # midnight on the last day of every month cron(0 0 LW * ? *) # midnight on the last weekday of every month cron(0 12 15W * ? *) # noon on the weekday nearest the 15th cron(0 12 ? * 6L *) # noon on the last Friday of every month cron(0 9 ? * 2#1 *) # 9 a.m. on the first Monday of every month
Contributed by @hiddengearz.
Pulled botocore/data/events/service-2.json, walked the shapes, fixed every divergence:
DescribeRule / ListRules now emit CreatedBy AND ManagedBy (both spec members were silently dropped from the response)PutEvents rejects requests with more than 10 entries (AWS Entries list cap)Time is int epoch seconds — was a float, breaking Java/Go SDK v2 timestamp parsers; archives now also dispatch the int form on replay[{"exists": false}] matches absent keys — was short-circuiting to no-match before the exists branch was evaluated, so patterns that should fire on missing fields silently droppedListRules paginates with Limit (1–100) + opaque NextToken — was returning the full list, so SDK paginators looped on the first pageListRuleNamesByTarget NextToken is now opaque base64 — was a raw integer offset stringDescribeEventBus / ListEventBuses omit Policy when no policy is set — was emitting an empty string, divergent from the AWS shapeDescribeEventSource State returns ACTIVE — was hardcoded to the invalid ENABLED; AWS EventSourceState enum is PENDING / ACTIVE / DELETEDChannelNamespace response now includes channelNamespaceArn — spec-required member that Terraform aws_appsync_channel_namespace and Java SDK v2 expectDescribeKeyValueStore Created / LastModified now parsed from the management-plane LastModifiedTime into int epoch seconds (was hardcoded to 0)/key-value-stores/ path bypass so the cloudfront-keyvaluestore SDK client (which boto3 sends with host <account>.localhost:4566) doesn't get misrouted to S3terraform apply outputdocker pull ministackorg/ministack:1.3.25 docker run -d -p 4566:4566 ministackorg/ministack:1.3.25
Or pin in compose.yaml:
services:
ministack:
image: ministackorg/ministack:1.3.25
ports:
- "4566:4566"
Shipped by the MiniStack community. Contributions credited throughout. GitHub · r/ministack