What's Changed
New Contributors
- @dcrn made their first contribution in #514
- @marcin-nowak-scl made their first contribution in #515
[1.3.20] — 2026-04-29
Added
- API Gateway (HTTP API and REST): JWT authorizer enforcement, HTTP proxy parameter mapping, and non-blocking proxy/JWKS I/O — HTTP API (
apigateway) and REST API (apigateway_v1) now enforce JWTissuer+audiencevalidation against a JWKS URL (RS256 signatures only — Cognito's standard), apply request parameter mappings forHTTP/HTTP_PROXYintegrations (append/overwrite/removefor headers and querystring, plusoverwrite:path, with$context.authorizer.jwt.claims.*and$stageVariables.*substitution), and offload upstream proxy + JWKS fetches off the event loop so a slow backend can no longer stall unrelated requests. Authorizer issuers of the formhttps://cognito-idp.{region}.amazonaws.com/{poolId}are rewritten to MiniStack's local Cognito JWKS endpoint so locally-minted tokens verify without leaving the box. Reserved-header list for parameter mapping matches the AWS HTTP API spec exactly. Operator tuning:MINISTACK_APIGW_PROXY_TIMEOUT_SECONDS(default30),MINISTACK_APIGW_JWKS_TIMEOUT_SECONDS(default5). Cognito's signing key is now persisted under${STATE_DIR}/cognito-rsa-key.pemso tokens minted in one process verify in another. Contributed by @marcin-nowak-scl. - DynamoDB Streams read API — new
ministack/services/dynamodb_streams.pyexposesListStreams,DescribeStream,GetShardIterator, andGetRecordsviaboto3.client("dynamodbstreams")and thestreams.dynamodb.*host. Reads the records already captured by the main DynamoDB service (emitted fromPutItem,UpdateItem,DeleteItem,TransactWriteItems, andBatchWriteItem) so the public Streams API and the internal Lambda ESM path share one source of truth. Supports all four iterator types (TRIM_HORIZON,LATEST,AT_SEQUENCE_NUMBER,AFTER_SEQUENCE_NUMBER) and all four stream view types (NEW_AND_OLD_IMAGES,NEW_IMAGE,OLD_IMAGE,KEYS_ONLY). Single synthetic shard per stream; opaque base64 iterator tokens. UnblocksDynamoDbOutboxWorker-style consumers. Contributed by @marcin-nowak-scl. - DynamoDB → Kinesis streaming destination —
EnableKinesisStreamingDestination,DisableKinesisStreamingDestination,DescribeKinesisStreamingDestination, andUpdateKinesisStreamingDestinationonboto3.client("dynamodb"). Item mutations fromPutItem/UpdateItem/DeleteItem/TransactWriteItems/BatchWriteItemfan out to every ACTIVE destination as JSON-encoded records (viakinesis.put_record_internal) for Kinesis / Lambda ESM / Firehose-style consumers. DISABLED destinations remain onDescribefor the ~24h AWS window;DeleteTabledrops destinations. The wire envelope reuses the DynamoDB Streams record shape — AWS does not publicly document the exact Kinesis envelope it produces, so MiniStack approximates it with the Streams record. Contributed by @marcin-nowak-scl. - Native HTTPS via
USE_SSL=1— the gateway listener now speaks TLS whenUSE_SSL=1(also acceptstrue/yes), aligning with LocalStack'sUSE_SSLflag name so acompose.ymlswitching emulator doesn't need TLS-specific changes. By default, MiniStack auto-generates a self-signed RSA cert (CN:ministack-local, SAN:localhost,ministack,127.0.0.1,::1) cached under${TMPDIR}/ministack-tls/so the cert survives restarts. To pin a specific cert (e.g. anmkcert-issued one for browser trust), setMINISTACK_SSL_CERTandMINISTACK_SSL_KEYto PEM paths. Auto-generation shells out to theopensslCLI (already present in both images), so no Python crypto dep is added. Unblocks AWS SDKs that hardcodehttps://against Cognito Hosted UI endpoints (e.g. Amplify v6) without needing a separate TLS-terminating proxy. Contributed by @prandogabriel.
Fixed
- Step Functions
aws-sdk:rds:removeFromGlobalClusterleft global cluster members attached — query-protocol parameter conversion uppercasedDbClusterIdentifiertoDBClusterIdentifier, but the RDS API shape forRemoveFromGlobalClusterintentionally usesDbClusterIdentifier. The task now preserves that member name so a successful remove actually detaches the cluster and a followingDeleteGlobalClustermatches AWS behavior. Contributed by @jayjanssen. - Kinesis
ListShardsNextTokenreturned a raw shard ID instead of an opaque pagination token — AWS specifies an opaque token (length 1-1048576) with a 300-second TTL that yieldsExpiredNextTokenExceptionwhen expired. MiniStack now emits a base64url-encoded opaque token and rejects expired or malformed tokens with the AWS-correct error code, so SDKs that round-trip the token (and the rare consumers that inspect or persist it) see AWS-shape behavior. - DynamoDB
DescribeContinuousBackupsreturnedEarliestRestorableDateTime: 0/LatestRestorableDateTime: 0when PITR was disabled — emitting Unix epoch 1970 misled SDK consumers that parsed the values into datetimes. Both fields are now omitted whenPointInTimeRecoveryStatusisDISABLEDand populated with a real timestamp whenENABLED. - DynamoDB
DescribeEndpointsreturned the hardcoded real-AWS endpointdynamodb.us-east-1.amazonaws.com— endpoint-discovery-aware SDKs would cache that address and silently redirect subsequent calls AWAY from MiniStack to real AWS. The endpoint now reflects MiniStack's own host (MINISTACK_HOST:GATEWAY_PORT) so SDKs keep talking to the emulator.