github ministackorg/ministack v1.3.20

latest release: v1.3.21
5 hours ago

What's Changed

New Contributors

[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 JWT issuer + audience validation against a JWKS URL (RS256 signatures only — Cognito's standard), apply request parameter mappings for HTTP / HTTP_PROXY integrations (append/overwrite/remove for headers and querystring, plus overwrite: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 form https://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 (default 30), MINISTACK_APIGW_JWKS_TIMEOUT_SECONDS (default 5). Cognito's signing key is now persisted under ${STATE_DIR}/cognito-rsa-key.pem so tokens minted in one process verify in another. Contributed by @marcin-nowak-scl.
  • DynamoDB Streams read API — new ministack/services/dynamodb_streams.py exposes ListStreams, DescribeStream, GetShardIterator, and GetRecords via boto3.client("dynamodbstreams") and the streams.dynamodb.* host. Reads the records already captured by the main DynamoDB service (emitted from PutItem, UpdateItem, DeleteItem, TransactWriteItems, and BatchWriteItem) 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. Unblocks DynamoDbOutboxWorker-style consumers. Contributed by @marcin-nowak-scl.
  • DynamoDB → Kinesis streaming destinationEnableKinesisStreamingDestination, DisableKinesisStreamingDestination, DescribeKinesisStreamingDestination, and UpdateKinesisStreamingDestination on boto3.client("dynamodb"). Item mutations from PutItem / UpdateItem / DeleteItem / TransactWriteItems / BatchWriteItem fan out to every ACTIVE destination as JSON-encoded records (via kinesis.put_record_internal) for Kinesis / Lambda ESM / Firehose-style consumers. DISABLED destinations remain on Describe for the ~24h AWS window; DeleteTable drops 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 when USE_SSL=1 (also accepts true / yes), aligning with LocalStack's USE_SSL flag name so a compose.yml switching 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. an mkcert-issued one for browser trust), set MINISTACK_SSL_CERT and MINISTACK_SSL_KEY to PEM paths. Auto-generation shells out to the openssl CLI (already present in both images), so no Python crypto dep is added. Unblocks AWS SDKs that hardcode https:// 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:removeFromGlobalCluster left global cluster members attached — query-protocol parameter conversion uppercased DbClusterIdentifier to DBClusterIdentifier, but the RDS API shape for RemoveFromGlobalCluster intentionally uses DbClusterIdentifier. The task now preserves that member name so a successful remove actually detaches the cluster and a following DeleteGlobalCluster matches AWS behavior. Contributed by @jayjanssen.
  • Kinesis ListShards NextToken returned a raw shard ID instead of an opaque pagination token — AWS specifies an opaque token (length 1-1048576) with a 300-second TTL that yields ExpiredNextTokenException when 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 DescribeContinuousBackups returned EarliestRestorableDateTime: 0 / LatestRestorableDateTime: 0 when PITR was disabled — emitting Unix epoch 1970 misled SDK consumers that parsed the values into datetimes. Both fields are now omitted when PointInTimeRecoveryStatus is DISABLED and populated with a real timestamp when ENABLED.
  • DynamoDB DescribeEndpoints returned the hardcoded real-AWS endpoint dynamodb.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.

Don't miss a new ministack release

NewReleases is sending notifications on new releases.