Guides, changelogs, and community highlights for the free LocalStack alternative.
.github/workflows/ file that runs your AWS tests on every push.deploy UsePreviousValue, Step Functions .waitForTaskToken for SQS/SNS, RDS Data API PostgreSQL fixes, Cognito token invalidation, RDS parameter-group validation, Athena table metadata, SNS non-string Messagedefault.* parameter groups for Redis, Memcached, and Valkey (including .cluster.on) with engine-version→family mapping; immutable seeded defaults; replication-group creation materializes member clusters (metadata, tags, IDs) and removes them on deletion; user-group validation; tag fanout to member ARNs; Resource Groups Tagging API coverage; AWS wire error codes (UserNotFound, UserGroupNotFound). Contributed by @ZiningYin. Added — IAM managed policies — AWSXRayDaemonWriteAccess, AWSXrayReadOnlyAccess, AWSLambdaRole seeded with canonical documents so Terraform's attach_tracing_policy lookup resolves. Contributed by @mattwang44. CloudFormation — deploy without --parameter-overrides now updates resources — a UsePreviousValue=true change set resolved parameters to empty, so a parameter-driven resource name resolved wrong and the update silently missed the real resource; UsePreviousValue is now resolved against the stack's stored parameters. Reported by @ankitaabad. Step Functions — .waitForTaskToken invokes non-Lambda integrations — sqs:sendMessage.waitForTaskToken (and sns:publish, dynamodb:*, aws-sdk:*) scheduled the task but never performed the integration, so the token payload was never sent and the execution hung; the callback path now dispatches the integration before blocking, and an object MessageBody is JSON-serialized for SQS. Reported by @taylor1791. RDS Data API — PostgreSQL fixes — psycopg2 autocommit (non-transactional ExecuteStatement no longer rolled back), longest-first parameter substitution (:1 no longer corrupts :10/:18), and jsonb returned as JSON text. Reported by @awilson9. Cognito — token/session invalidation takes effect — RevokeToken/GlobalSignOut/AdminUserGlobalSignOut were no-ops; they now invalidate refresh tokens and REFRESH_TOKEN_AUTH honours it. RDS — parameter-group validation — CreateDBInstance/CreateDBCluster reject a missing custom parameter group. Athena — table metadata returns real columns and partition keys instead of empty stubs. SNS — Publish accepts non-string Message — Step Functions object payloads are JSON-serialized before delivery. Contributed by @noynoy83. CI — test suite sharded across parallel runners. Contributed by @jgrumboe.GetBucketOwnershipControls 404-after-delete, API Gateway v2 ms-custom-id in CloudFormation, EC2 source-security-group references, Glue \Q…\E regex patterns, Lambda content-addressed code blobs + CloudFormation/CDK layer content + DynamoDB-stream ESM anchoring, ECS RunTask SSM Parameter Store secretsStartInstanceRefresh, DescribeInstanceRefreshes, and CancelInstanceRefresh failed with InvalidAction: Unknown AutoScaling action; they're now handled and recorded on the group so a refresh can be started, polled, and cancelled. Contributed by @c-julin. S3 — GetBucketOwnershipControls now 404s after delete — it always returned a default ownership block (200), so DeleteBucketOwnershipControls wasn't observable and Terraform's delete waiter looped (found resource); it now returns OwnershipControlsNotFoundError (404) once deleted, while still reporting the default Object Ownership for a never-configured bucket. Contributed by @c-julin. API Gateway v2 — CloudFormation provisioner honours the ms-custom-id tag — AWS::ApiGatewayV2::Api always got a random id, ignoring the tag even though CreateApi and the v1 REST provisioner honoured it; the v2 provisioner now resolves the custom id first. Contributed by @hiddengearz. EC2 — source security groups (UserIdGroupPairs) returned by DescribeSecurityGroupRules / DescribeSecurityGroups — rules referencing another security group were dropped at ingestion and never surfaced (ReferencedGroupInfo omitted, empty <groups>); they're now parsed and emitted by both. Reported by @kamegoro. Contributed by @kurok. Glue — GetUserDefinedFunctions accepts java.util.regex \Q…\E patterns — real AWS compiles Pattern with java.util.regex, so clients like Trino send literal-quoted patterns (e.g. trino__\Qname\E__.*) that Python's re rejected with InvalidInputException; the literal-quote sequences are now translated before matching. Contributed by @yonatoasis. Lambda — function code stored as content-addressed blob files — get_state base64-encoded every code_zip inline into lambda.json, so many large zips (e.g. 26 × ~30 MB) produced a ~1 GB state file that OOM'd on warm boot; code bytes are now written as content-addressed blobs and loaded lazily. Contributed by @mattwang44. Lambda — CloudFormation/CDK-provisioned layers carry their content — layers created via CloudFormation stored no zip data, so functions couldn't import their layer packages even though ListLayers showed them; the provisioner now stores the layer bytes. Lambda — CloudFormation-created DynamoDB-stream ESMs anchor LATEST at create time — matching the API path, so a LATEST mapping skips records that existed when the stack was deployed instead of replaying them (no-op for SQS/Kinesis). ECS — RunTask secrets resolve SSM Parameter Store references — containerDefinitions[].secrets valueFrom entries pointing at SSM were left unresolved; they're now fetched in-process and injected alongside Secrets Manager references.DeletePublicAccessBlock 404 + WebsiteRedirectLocation, CloudFormation GetTemplateSummary capabilities, Lambda FilterCriteria + CloudFormation DynamoDB ESM polling, CloudWatch Logs subscription-filter delivery, EventBridge reserved transformer variables, Step Functions mock Throw→Catch, Glue regex Pattern, IAM instance-profile tagsUserIdGroupPairs) returned by DescribeSecurityGroupRules / DescribeSecurityGroups — rules referencing another security group were dropped at ingestion and never surfaced (ReferencedGroupInfo omitted, empty <groups>); they're now parsed and emitted by both. Reported by @kamegoro. ECS — RunTask injects containerDefinitions[].secrets from Secrets Manager — valueFrom references (including the :json-key: form) were dropped, so containers started without those env vars; now resolved and merged before overrides (SSM not yet resolved). Reported by @kamegoro. Contributed by @kurok. ECS — RunTask applies containerOverrides.command — an overridden command (including an explicit empty command) was ignored because Docker still used the task-definition command. Contributed by @noynoy83. S3 — DeletePublicAccessBlock now actually clears the configuration — GetPublicAccessBlock returned a default all-blocked 200 instead of NoSuchPublicAccessBlockConfiguration (404), so Terraform's delete waiter timed out; it now returns 404 when unset. Reported by @kamegoro. Contributed by @kurok. S3 — WebsiteRedirectLocation preserved — x-amz-website-redirect-location on PutObject is stored and returned by GetObject / HeadObject. Contributed by @murlock. CloudFormation — GetTemplateSummary returns Capabilities / CapabilitiesReason — computed from the template (CAPABILITY_NAMED_IAM / CAPABILITY_IAM / CAPABILITY_AUTO_EXPAND). Contributed by @maximoosemine. Lambda — CreateEventSourceMapping persists FilterCriteria — the parameter was silently dropped at creation time. Contributed by @maximoosemine. Lambda — CloudFormation-created DynamoDB stream ESMs now poll — an ARN-with-qualifier FunctionName was mis-parsed so the poller couldn't resolve the function, and a LATEST mapping skipped its first record on an empty table. Contributed by @maximoosemine. CloudWatch Logs — subscription filters deliver matching log events to the destination Lambda — a SubscriptionFilter (via CloudFormation or PutSubscriptionFilter) was provisioned but never forwarded log events; matching events from PutLogEvents and Lambda's own log emission are now delivered to Lambda destinations in the awslogs gzip+base64 DATA_MESSAGE envelope, with a self-loop guard. Reported by @ankitaabad. EventBridge — reserved input-transformer variables — <aws.events.event.json>, <aws.events.event>, <aws.events.rule-name>, <aws.events.rule-arn>, <aws.events.event.ingestion-time> were left literal, producing invalid JSON; they now resolve. Contributed by @AbdoNile. Step Functions — mocked Throw routes to Catch — a SFN_MOCK_CONFIG Throw was raised above Retry/Catch, so the execution always failed instead of routing to a matching Catch; it now flows through the same machinery as a real failure. Reported by @amissemer. Glue — GetUserDefinedFunctions treats Pattern as a regex — matched as a glob before, so patterns like Trino's trino__<name>__.* never matched; an invalid pattern now returns InvalidInputException. Contributed by @yonatoasis. IAM — instance-profile tagging actions — TagInstanceProfile / UntagInstanceProfile / ListInstanceProfileTags implemented and read back from GetInstanceProfile / ListInstanceProfiles. Contributed by @c-julin.site-packages on the local executor, CloudFormation deploy change-set detection + AWS::Logs::SubscriptionFilter, LoggingConfig.LogGroup, DescribeStackResources filter, Step Functions JSONata mock Assign + Pass context objectssite-packages — the in-process worker added <layer>/python to sys.path but not <layer>/python/lib/python<ver>/site-packages where pip install -t layers land; AWS exposes it as a site directory, so it's now added via site.addsitedir (so .pth files and namespace packages resolve too). Reported by @omargr299. Lambda — LoggingConfig.LogGroup honored — handler logs went to the default /aws/lambda/<name> group instead of the configured / shared group. Reported by @ankitaabad. CloudFormation — AWS::Logs::SubscriptionFilter resource type supported (provisions against the named log group, removed on stack delete). Reported by @ankitaabad. CloudFormation — change sets detect parameter-driven property changes — aws cloudformation deploy silently no-oped when a property like a Lambda Code S3 key was driven by a stack parameter because the diff compared unresolved templates; it now resolves parameters / intrinsics before diffing, matching update-stack. Reported by @ankitaabad. CloudFormation — DescribeStackResources honors the LogicalResourceId filter (returns the matching resource or ValidationError). Contributed by @maximoosemine. Step Functions — Assign applied in the JSONata mock path — with SFN_MOCK_CONFIG, Assign blocks were silently skipped on the mock return branch, failing downstream states with States.QueryEvaluationError: Undefined variable. Contributed by @amissemer. Step Functions — Pass state Parameters resolve context object paths — $$.* resolved to null because the executor didn't forward the execution context. Contributed by @noynoy83./iceberg, mirroring AWS Glue's glue.<region>.amazonaws.com/iceberg endpoint on the glue credential scope; GET /v1/config, ListNamespaces, GetNamespace, ListTables, LoadTable, HEAD TableExists (writes return 501); a Glue table participates when its Parameters["metadata_location"] points at an Iceberg metadata.json on MiniStack S3, letting DuckDB's iceberg extension ATTACH (requires USE_SSL=1). Contributed by @yonatoasis. Glue — ColumnStatistics API family (table + partition) — UpdateColumnStatisticsForTable / Get / Delete and the *ForPartition equivalents, account-scoped, persisted, cleared on table / partition delete. Contributed by @yonatoasis. CloudFormation — DescribeStackEvents returns the initial REVIEW_IN_PROGRESS event for change-set-created stacks — CreateChangeSet --change-set-type CREATE left an empty event list so sam deploy crashed reading StackEvents[0]. Contributed by @maximoosemine. Step Functions — ecs:runTask no longer drops ContainerOverrides — the Pascal→camelCase conversion only covered top-level keys, so nested Overrides.ContainerOverrides stayed PascalCase and was ignored; the conversion is now recursive. Contributed by @lucasmfraser. Lambda — layers reachable in the docker executor + zip permissions preserved — layers merge into /opt (not /opt/layer_N), and unix mode bits are restored so /opt/bin tools stay executable. Reported by @omargr299. awslocal works in TLS mode without --no-verify-ssl — resolves MiniStack's TLS cert and exports AWS_CA_BUNDLE only when it's a real file. Reported by @ChronosMasterOfAllTime. Lambda — restored SQS event source mappings resume polling after a warm restart — lambda_svc is eager-imported at boot when persisted ESMs exist, so the poller starts. Reported by @ChronosMasterOfAllTime.mq) covering both RabbitMQ and ActiveMQ: broker lifecycle (CreateBroker, ListBrokers, DescribeBroker, UpdateBroker, DeleteBroker, RebootBroker), engine/instance metadata (DescribeBrokerEngineTypes, DescribeBrokerInstanceOptions), ActiveMQ user management, and broker tagging. Brokers come up RUNNING immediately (metadata only, no container); state is account-scoped and persisted; REST routing matches AWS's mq request URIs so boto3 and Terraform's aws_mq_broker work unchanged. Contributed by @lucas-giaco. IAM — account posture: GetAccountSummary (computed counts + quotas), account password policy (GetAccountPasswordPolicy returns NoSuchEntity before set, plus Update / Delete), and account aliases (List / Create / DeleteAccountAlias). IAM — credential report (GenerateCredentialReport + GetCredentialReport) builds the exact 22-column AWS CSV with live password_enabled / mfa_active / access_key_*_active columns and returns ReportNotPresent (410) before generation. Both contributed by @lahmish. S3 — event notifications now fire for non-default accounts — the delivery thread didn't inherit the request's account context, so it ran under 000000000000, the account-scoped bucket-notification config resolved empty, and the event was silently dropped (SQS / SNS / Lambda / EventBridge targets also resolved under the wrong account); the thread now copies the request context. Reported by @rsking.CreateLoginProfile / Get / Update / Delete models whether an IAM user has a console password (the signal that distinguishes a human IAM user from a service account); virtual MFA device lifecycle (CreateVirtualMFADevice, EnableMFADevice, DeactivateMFADevice, ResyncMFADevice, ListMFADevices, ListVirtualMFADevices, DeleteVirtualMFADevice) with SerialNumber in ARN form, Base32StringSeed + QRCodePNG blobs, AssignmentStatus filter defaulting to Any, DeleteConflict on assigned devices; GetAccountAuthorizationDetails — the one-shot identity graph returning UserDetailList / GroupDetailList / RoleDetailList / Policies with inline + attached policies, group memberships, instance profiles, tags, and url-encoded policy documents; SAML provider CRUD plus ListOpenIDConnectProviders for federation discovery; Access Advisor generate / get job handshake returning JobStatus=COMPLETED with an empty ServicesLastAccessed list. Cognito — CUSTOM_AUTH RespondToAuthChallenge merges verify result into the pending round — multi-round flows (magic-link → SMS-OTP) were stuck because the verify result was appended as a separate metadata-less session entry; AWS records one ChallengeResult per round carrying both challengeMetadata and challengeResult, the pending round is now updated in place. Contributed by @AdigaAkhil. SQS — out-of-range numeric attributes rejected with InvalidAttributeValue — VisibilityTimeout (0–43200), MaximumMessageSize (1024–262144), MessageRetentionPeriod (60–1209600), DelaySeconds (0–900), ReceiveMessageWaitTimeSeconds (0–20), KmsDataKeyReusePeriodSeconds (60–86400) are validated against the documented AWS ranges and rejected with 400 when outside or non-numeric. Reported by @dcabib. EventBridge — anything-but honors nested prefix / suffix / wildcard matchers — {"anything-but": {"prefix": "TEST-"}} was silently ignored and every event matched; the dispatcher now negates the nested filter correctly. Reported by @aldirrix. ElastiCache — Redis container respawned after restart — with PERSIST_STATE=1, restored cluster metadata reported available but the persisted Docker container id was dead; restored clusters and replication groups are now marked pending and lazily spawned on the first dispatcher call (under a lock to prevent double-spawn), endpoint metadata is rewritten to the fresh container before any caller can read it. Reported by @ItsSmiffy.container.put_archive("/opt/layer_N", ...) returned 404 because the destination subdir doesn't pre-exist in the RIE image; layers now extract into the existing /opt with arcname=layer_N. The docker warm-container pool is also reaped on UpdateFunctionConfiguration / DeleteFunction so a layer attached after the first invoke is actually mounted on the next one. Reported by @omargr299. AppSync — AWS-standard AppSyncResolverEvent for AWS_LAMBDA data sources — arguments, source, request.headers, prev, stash, info.fieldName/parentTypeName/variables; AWS_LAMBDA auth runs the authorizer first and threads its resolverContext into identity; authorizer event carries the verbatim AWS requestContext (apiId / accountId / requestId / queryString / operationName / variables); rejected authorizers surface as UnauthorizedException (HTTP 401). Contributed by @AdigaAkhil. API Gateway v2 — JWT authorizer resolves JWKS via OIDC discovery — the JWKS path was hardcoded to {issuer}/.well-known/jwks.json (404 for Salesforce /id/keys, Okta /oauth2/v1/keys, etc.); the resolver now fetches {issuer}/.well-known/openid-configuration and reads jwks_uri per the documented AWS behavior, 2h cache, Cognito short-circuit preserved, conventional path as fallback. Contributed by @Pratham2703005. S3 — PutObject checksums end-to-end — SHA256 / SHA1 / CRC32 client-supplied values are accepted; x-amz-sdk-checksum-algorithm triggers server-side compute and validates mismatches with BadDigest; Get / HeadObject surface them under x-amz-checksum-mode: ENABLED; CopyObject propagates the source's checksum; versioned reads honor per-version checksums; checksums never accompany a 206 Partial Content reply; CRC32C / CRC64NVME are rejected with InvalidRequest instead of silently round-tripping unverifiable client-supplied values. Reported by @Guigoz. S3 — on-disk bucket directory account-scoped — CreateBucket's makedirs was at DATA_DIR/<bucket> while every object write goes to DATA_DIR/<account>/<bucket>/<key>; now scoped end-to-end, and DeleteBucket cleans it up. Reported by @rsking. Glue — BatchUpdatePartition — closes the last partition action; matches AWS per-entry shape (Entries[*].{PartitionValueList, PartitionInput} in, Errors[*].{PartitionValueList, ErrorDetail} out); preserves CreationTime, refreshes LastAccessTime. Contributed by @yonatoasis. Glue — StartJobRun script resolution + crawler completion under non-default accounts — _resolve_script built an unscoped on-disk path so file-backed scripts never matched; _finish_crawl ran on a threading.Timer without contextvars so crawlers under non-default accounts hung in RUNNING forever. Both background paths now carry the request's account via contextvars.copy_context().run(...), mirroring the established stepfunctions.py / rds.py idiom. Contributed by @AdigaAkhil. CloudFormation — AppConfig Environment / ConfigurationProfile / HostedConfigurationVersion / DeploymentStrategy / Deployment — the rest of the AppConfig CFN surface (Application landed in v1.3.55); property names, defaults, Ref returns and Fn::GetAtt attribute names match the AWS reference verbatim; HostedConfigurationVersion enforces the optional LatestVersionNumber locking token; Deployment tags stored against the AWS-shape ARN. Reported by @zdenekmartinec.UpdateFunctionConfiguration(Layers=[...]) finally works after the first invoke — GetFunctionConfiguration.Layers[*].CodeSize now reports the layer's real zip size (was hardcoded 0), and the warm worker is recycled when Layers / Runtime / Handler / Environment / MemorySize / Architectures / VpcConfig / FileSystemConfigs change, so the next Invoke mounts the layer at /opt/layer_N and the handler can import from it. Reported by @omargr299. KMS — Ed25519 (ECC_NIST_EDWARDS25519) sign / verify — real Ed25519 keypair generation, SigningAlgorithms=["ED25519_SHA_512","ED25519_PH_SHA_512"], Sign / Verify enforce MessageType=RAW for ED25519_SHA_512, ED25519_PH_SHA_512 (Ed25519ph, RFC 8032 §5.1) returns UnsupportedOperationException instead of producing wire-incompatible signatures. Contributed by @KABBOUCHI. EKS — default topology.kubernetes.io/zone and topology.kubernetes.io/region labels on k3s nodes — matches the labels the AWS cloud-controller-manager emits, unblocking Karpenter / Cluster Autoscaler / scheduler topologySpreadConstraints without manual kubectl label node. Contributed by @b-rajesh. ELBv2 — SetSubnets, SetIpAddressType, SetSecurityGroups — three load-balancer mutation actions, output shapes verified against botocore (SetSecurityGroups returns SecurityGroupIds, not SecurityGroups). Glue — UserDefinedFunction APIs — full lifecycle (Create / Update / Delete / Get / GetMany) with the AWS-required Pattern glob on GetUserDefinedFunctions. IAM — real EKS managed-policy seeds — AmazonEKSClusterPolicy, AmazonEKSWorkerNodePolicy, AmazonEKS_CNI_Policy, AmazonEKSServicePolicy now carry the verbatim AWS documents instead of the wildcard Allow * fallback, so Terraform diffs and policy simulators behave the same as real AWS. EC2 — Attachment.AttachTime on ENI describe matches the AWS NetworkInterfaceAttachment shape. Glue — CreateDatabase honors top-level Tags (previously dropped). Glue — UpdateTable optimistic concurrency via VersionId — stale VersionId returns ConcurrentModificationException; calls without VersionId keep the old back-compat behavior. ECS — DeleteService marks the record INACTIVE instead of removing it, matching the AWS contract that "DRAINING or INACTIVE services can still be viewed with DescribeServices". Cognito — CUSTOM_AUTH trigger Lambdas no longer deadlock the event loop — the IDP / Identity dispatchers are now async and run sync handlers via asyncio.to_thread, so a trigger Lambda's HTTP callback can be served by the same loop that's waiting for it. Reported by @aahoughton.CreateFleet + DescribeFleets with instant-type synchronous launch and maintain / request async fulfillment (response shape parity restored — Instances + Errors are emitted only when Type=instant), multi-config × multi-override round-robin capacity distribution (Karpenter's 2 configs × 2 overrides × total=4 launches one of each combination), DefaultTargetCapacityType-driven spot/on-demand selection (not the top-level Type, whose FleetType enum doesn't even include "spot"), and InvalidFleetId.NotFound for unknown FleetIds. Reported by @b-rajesh. Contributed by @b-rajesh. EKS — OIDC Identity Provider Config — AssociateIdentityProviderConfig / DescribeIdentityProviderConfig / DisassociateIdentityProviderConfig at /clusters/{name}/identity-provider-configs/{verb}. AWS allows one OIDC IdP per cluster (any second associate — same name or different — returns ResourceInUseException); issuer URL + client ID + claims forwarded to k3s via --kube-apiserver-arg=oidc-*; IdP ARN stable across describes so Terraform / CDK / Pulumi don't see drift; tags reachable via ListTagsForResource(resourceArn=idp_arn); cluster status stays ACTIVE throughout (the work is in the returned update record, not on the cluster). Contributed by @b-rajesh. DynamoDB — ExportTableToPointInTime + ImportTable return IN_PROGRESS at submit time — both used to claim COMPLETED immediately, so callers never observed the in-progress state real AWS guarantees; DescribeExport / DescribeImport stays IN_PROGRESS within the grace window and flips to COMPLETED + stamps EndTime after. Reported by @hicksy. Export contributed by @HarrisonTCodes. DynamoDB PartiQL — UPDATE / DELETE with a false non-key predicate returns ConditionalCheckFailedException — previously silently no-op'd because the WHERE clause was iterated against every row; PartiQL now splits WHERE into PK equalities + "the rest", looks up the single targeted item, and returns CCF if missing or non-key predicate fails (and ValidationException if no PK equality was given). Reported by @hicksy. SQS — /_ministack/sqs/messages admin endpoint mirroring the SES pattern, returning every queue's messages grouped by account with optional ?account / ?QueueUrl filters. Reported by @mbamber. RDS — MINISTACK_RDS_PUBLIC_ENDPOINT env — set 1 when MiniStack is in Docker but RDS clients connect from outside the network; DescribeDBInstances then returns {MINISTACK_HOST, host_port} instead of the unreachable container-internal address. AppConfigData — StartConfigurationSession accepts identifier by ID or name — service-2.json documents both shapes; ministack treated them as IDs only. Contributed by @LiamMacP. MINISTACK_HOST honored consistently across services — ECS / ElastiCache / OpenSearch / Lambda subprocess paths previously hardcoded "localhost" and ignored the env var. Contributed by @neriyaco.CUSTOM_AUTH flow with DefineAuthChallenge / CreateAuthChallenge / VerifyAuthChallengeResponse Lambda triggers — InitiateAuth / AdminInitiateAuth / RespondToAuthChallenge / AdminRespondToAuthChallenge now run the full custom-auth state machine through the configured Lambdas; session TTL honors the client's AuthSessionValidity, capped at 3 answered rounds per AWS. Unblocks passwordless / magic-link / SMS-OTP flows that previously failed with Unsupported AuthFlow: CUSTOM_AUTH. Reported by @aahoughton. Contributed by @AdigaAkhil. EKS Access Entries — modern post-1.29 IAM bindings replacing the aws-auth ConfigMap — 8 new ops at /clusters/{name}/access-entries[/{principalArn}[/access-policies[/{policyArn}]]]: CreateAccessEntry, DescribeAccessEntry, ListAccessEntries, UpdateAccessEntry, DeleteAccessEntry, AssociateAccessPolicy, DisassociateAccessPolicy, ListAssociatedAccessPolicies. accessScope validated against {cluster, namespace} with namespaces required when namespace-bound; deleting an access entry cascades its associated policies. Unblocks Crossplane accessentry.eks.aws.upbound.io and Terraform aws_eks_access_entry + aws_eks_access_policy_association. Reported by @b-rajesh. Lambda — _X_AMZN_TRACE_ID injected for TracingConfig.Mode=Active — the runtime env var the AWS X-Ray SDK reads on every segment was never being set, so aws-xray-sdk-python raised Missing AWS Lambda trace data for X-Ray. Now synthesized per invocation and threaded into the warm Python / Node pool, provided runtimes, and the local subprocess executor; the docker RIE path is documented as upstream-unsupported and logs a warning. Reported by @arivazhaganjeganathan-abc. Firehose — Lambda processor invoked in the delivery pipeline — ProcessingConfiguration.Processors[].Type=Lambda was persisted but never consulted at invocation, so records flowed straight to S3 without transformation. The full AWS contract is honored: per-batch event with {recordId, approximateArrivalTimestamp, data}, response with result ∈ {Ok, Dropped, ProcessingFailed}, Lambda failures pass records through unchanged (best-effort). Applies to both PutRecord / PutRecordBatch and the KinesisStreamAsSource fan-out. Reported by @arivazhaganjeganathan-abc. Cognito CUSTOM_AUTH — issueTokens on the cap-boundary attempt now wins over MaxAttempts. DynamoDB — AWS-canonical error-message parity across 24 operations driven by the dynamodb-conformance.org suite (set-duplicates include collection contents, UpdateExpression syntax / hash-key-modification pre-rejection, redundant-parens + begins_with non-string operand pre-validated, BatchExecuteStatement Code drops Exception suffix to match the AWS enum, TransactGetItems missing-key surfaces via cancellation reasons, size-exceeded envelopes include the Java-toString dump)./v1/flows[/{FlowArn}] and /tags/{ResourceArn}: CreateFlow, DescribeFlow, ListFlows, UpdateFlow, ListTagsForResource. ListFlows returns the slimmer ListedFlow projection; UpdateFlow is narrow to the AWS-allowed fields (SourceFailoverConfig, Maintenance, SourceMonitoringConfig, NdiConfig). No real streaming — flows are control-plane metadata, enough to integration-test services that wrap the MediaConnect API. Reported by @tashif-hoda. EKS AssociateEncryptionConfig + OIDC discovery / JWKS for IRSA — new POST /clusters/{name}/encryption-config/associate records KMS encryption config and rejects re-association (matches AWS, which only allows adding encryption to a cluster that has none). Each cluster's identity.oidc.issuer now points at a ministack-hosted URL (/oidc/id/{32-char-id}) instead of the unreachable real oidc.eks.{region}.amazonaws.com; GET <issuer>/.well-known/openid-configuration and GET <issuer>/keys are served with authorization_endpoint: "urn:kubernetes:programmatic_authorization" and claims_supported: ["sub","iss"] matching real EKS — enough for terraform's aws_iam_openid_connect_provider to fetch the document. Reported by @b-rajesh. API Gateway v2 Lambda-proxy — Set-Cookie from headers and the cookies array now both ship — observed real-AWS behavior is to emit the array entries first followed by any header Set-Cookie; the earlier supersede approach silently dropped the header cookie. API Gateway v2 Lambda-proxy — isBase64Encoded honored in both directions — only text/* and application/json / application/xml / application/javascript arrive as UTF-8; everything else (incl. missing Content-Type and application/x-www-form-urlencoded) is base64-encoded with isBase64Encoded: true. Outbound base64 bodies are decoded to raw bytes — HTTP API has no binaryMediaTypes negotiation. Contributed by @rmlasseter. API Gateway v1 Lambda-proxy — binaryMediaTypes is now wired — request bodies matching a configured pattern arrive base64 with isBase64Encoded: true; response base64 bodies are decoded only when the request Accept also matches. Wildcards (*/*, type/*) honored; a request Accept of */* does NOT auto-match specific configured types — verified against real AWS. Contributed by @rmlasseter. API Gateway v1 & v2 Lambda-proxy — case-insensitive header override — a lowercase content-type from a Lambda response now replaces the seeded default rather than shipping two Content-Type headers (RFC 9110 §5.1). Contributed by @rmlasseter./clusters/{name}/addons[/{addonName}[/update]] (CreateAddon, DescribeAddon, ListAddons, UpdateAddon, DeleteAddon), unblocking aws_eks_addon for the standard cluster bootstrap (vpc-cni, coredns, kube-proxy, aws-ebs-csi-driver). Status flips to ACTIVE immediately on create / update, matching the nodegroup shortcut. Reported by @b-rajesh. API Gateway Lambda-proxy Set-Cookie and multiValueHeaders now reach the client — v2 maps the payload-format-2.0 cookies array to a list-valued Set-Cookie (RFC 6265 §3 forbids comma-folding); v1 folds format-1.0 multiValueHeaders into the response with multiValueHeaders winning over headers on key collision per the AWS contract; _send_response expands list-valued headers into one wire line per entry. The v1 collision check is case-insensitive (HTTP headers are case-insensitive per RFC 7230 §3.2), so Set-Cookie in headers plus set-cookie in multiValueHeaders correctly resolves to MVH wins instead of shipping both. Contributed by @rmlasseter. DynamoDB data-plane table-name length range — data-plane ops (PutItem / GetItem / UpdateItem / DeleteItem / Query / Scan) now accept the AWS-documented 1..255 range (the 3-char minimum is a CreateTable-only rule). NULL-attribute error message text aligned. EC2 launch template version XML shape — CreateLaunchTemplateVersion returns a single <launchTemplateVersion> struct; DescribeLaunchTemplateVersions wraps in <launchTemplateVersionSet><item>…</item></launchTemplateVersionSet>. The <item> wrapper now belongs at the list-context boundary, not on the inner struct.KinesisStreamAsSource → S3 fan-out — delivery streams of type KinesisStreamAsSource with an ExtendedS3 / S3 destination now actually consume records from the source Kinesis stream and forward them to S3. Previously the source configuration round-tripped on DescribeDeliveryStream but no consumer ever read the records. Fan-out fires inline from Kinesis PutRecord / PutRecords (same pattern as SNS→SQS), honors Prefix and DeliveryStartTimestamp, and is best-effort so a Firehose problem can never break the producer. Reported by @arivazhaganjeganathan-abc. DynamoDB Tier 3 conformance pass — 30+ message-text fixes so the strings returned by ministack match the strings captured from real AWS by the dynamodb-conformance.org Tier 3 suite, including: non-existent-table responses uniformly returning "Requested resource not found" across Batch* / Transact* / single-item ops; BatchWriteItem / BatchGetItem empty RequestItems using the AWS "The requestItems parameter is required."; per-expression-scoped undefined-reference errors ("Invalid FilterExpression: An expression attribute value used in expression is not defined; attribute value: :v"); empty KeyConditionExpression / UpdateExpression using the "Invalid {Expression}: The expression cannot be empty;" template; Scan Segment validation; set / NULL / empty-BS / KeySchema / index-validation / billingMode / tableClass / deletion-protection / Limit / GSI-not-found messages all aligned; ListTagsOfResource on a non-existent ARN returns AccessDeniedException (AWS security-through-obscurity contract). Plus two functional bugs: GSI / LSI INCLUDE and KEYS_ONLY projections are now enforced on Query and Scan (items trimmed to declared NonKeyAttributes + keys); parallel Scan now partitions items deterministically across segments by hashing the partition key (previously every segment returned every item); LSI sparse semantics drop items lacking the LSI's range-key attribute from index scans. AWS error-type fixes across eight services — EFS resource-not-found is now per-resource-type (FileSystemNotFound / AccessPointNotFound); S3 Tables uses NotFoundException; CloudFront KeyValueStore / Account use ValidationException; API Gateway v1 uses BadRequestException instead of an invented 405; ECS / Batch use ClientException; MWAA uses ValidationException; OpenSearch uses ValidationException. KMS / MWAA / Inspector2 no longer leak Python exception text in InternalServerException / InvalidCiphertextException responses — AWS never surfaces internal exception detail. IMDS instance-profile-ID literal assembled at runtime so credential-pattern secret scanners stop false-flagging AIPA… in imds.py. Reported by @diplomatic-ms.2025-12-01): CreateFunction with DurableConfig, the seven management ops (CheckpointDurableExecution, GetDurableExecutionState, GetDurableExecution, GetDurableExecutionHistory, ListDurableExecutionsByFunction, StopDurableExecution), and the three external callback ops (SendDurableExecutionCallbackSuccess, SendDurableExecutionCallbackFailure, SendDurableExecutionCallbackHeartbeat). A resume scheduler fires WAIT expiries, callback timeouts (Callback.Timeout / Callback.Heartbeat), and step-retry backoffs; state persists across restarts (the in-memory callback index is rebuilt from restored executions on boot and pending timers are re-armed). End-to-end verified against the official aws-durable-execution-sdk-python 1.5.0 and aws-durable-execution-sdk-java 2.44.13. Reported by @youngkwangk. S3 object tagging by versionId — GET / PUT / DELETE ?tagging honor versionId, and PutObject / POST form upload store the x-amz-tagging header against the resulting version rather than the object key. Reported by @barrywilks7. CloudFormation AWS::AppConfig::Application — create / delete provisioners; physical id is the application id and ApplicationId is exposed via Fn::GetAtt. Reported by @zmartinec. Also: MaxItems on durable Lambda list / state / history ops now bounded to AWS's [0, 1000] range (out-of-range → 400 InvalidParameterValueException); CheckpointDurableExecution rejects malformed Updates; StopDurableExecution on a terminal execution returns 400.CreateBackup, DescribeBackup, DeleteBackup, ListBackups, RestoreTableFromBackup, RestoreTableToPointInTime; restore honors BillingModeOverride and index overrides; backup metadata persists across restarts. DynamoDB Export / Import — ExportTableToPointInTime, DescribeExport, ListExports, ImportTable, DescribeImport, ListImports; both idempotent on ClientToken. Contributor Insights — Update / Describe / List with ENABLING→ENABLED / DISABLING→DISABLED settling. Resource-Based Policies — PutResourcePolicy, GetResourcePolicy, DeleteResourcePolicy with full revision-id semantics and the NO_POLICY conditional path. PartiQL transactions and batches — BatchExecuteStatement, ExecuteTransaction, ClientRequestToken idempotency, all-or-nothing rollback, DuplicateItemException on duplicate INSERT. DescribeLimits returns canonical account and table capacity limits. EC2 security-group lifecycle — CreateSecurityGroup returns SecurityGroupArn, DeleteSecurityGroup returns GroupId, RevokeSecurityGroupEgress returns RevokedSecurityGroupRules, and DescribeSecurityGroups distinguishes malformed IDs from missing ones. Contributed by @Areson. Plus ~20 DynamoDB validator and shape fixes spanning item validation, batch and transaction caps, Create/UpdateTable validation, Query/Scan validation, UpdateItem snapshot semantics, nested ProjectionExpression, binary key ordering, reserved keyword rejection, and ExpressionAttribute bookkeeping. Glue StartJobRun no longer auto-pulls missing Docker images; MWAA worker containers auto-remove on exit.s3tables) — new service emulator for table buckets, namespaces, and Iceberg-format tables. Control plane: CreateTableBucket, ListTableBuckets, GetTableBucket, DeleteTableBucket, CreateNamespace, ListNamespaces, GetNamespace, DeleteNamespace, CreateTable, ListTables, GetTable, DeleteTable, GetTableMetadataLocation, UpdateTableMetadataLocation. Ships with an embedded Iceberg REST catalog at /iceberg so Spark jobs configured with spark.sql.catalog.*.type=rest can create / load / commit Iceberg tables without an external catalog. Glue Spark jobs run on the official amazon/aws-glue-libs PySpark image — GlueVersion: 4.0 and 3.0 map to glue_libs_4.0.0_image_01 / glue_libs_3.0.0_image_01; override via GLUE_DOCKER_IMAGE; containers run on MiniStack's Docker network so they reach S3 / RDS / other ministack services by hostname. IAM UpdateAccessKey + GetAccessKeyLastUsed — toggle access keys between Active / Inactive; never-used keys return the AWS Region/ServiceName = N/A shape with no LastUsedDate. Contributed by @lahmish. Lambda invocation log includes user output alongside the traceback on error — handlers that printed before raising used to drop their print output and only return the traceback; both are now returned newline-separated, matching real Lambda CloudWatch Logs. Contributed by @Baptiste-Garcin. EC2 CreateVpcEndpoint and CreateFlowLogs persist TagSpecifications — tags passed at creation time were silently dropped; now stored, returned by DescribeFlowLogs, cleaned up on DeleteFlowLogs; fl- prefix registered in the resource-type guesser so flow-log IDs resolve via the Resource Groups Tagging API. Contributed by @lahmish.Enable, Disable, ListFindings with filtering/sorting/pagination, BatchGetFindingDetails, ListCoverage, ListCoverageStatistics, ListFindingAggregations, SearchVulnerabilities, tag and filter CRUD); generates deterministic stub vulnerability findings for ECR images, Lambda functions, and EC2 instances. Contributed by @ry-allan. RDS auto-respawn at boot with PERSIST_STATE=1 — MiniStack eager-imports the RDS module at startup and respawns the Docker container for every persisted instance immediately, no client API call required. Zero idle cost when no rds.json exists. Reported by @doodaz. Glue persists view fields on CreateTable / UpdateTable — ViewOriginalText / ViewExpandedText (contributed by @yonatoasis) so Trino's iceberg connector stops failing with viewOriginalText must be present, plus ViewDefinition and IsMultiDialectView for newer Spark 3.4+ / Glue 4.0 / Lake Formation view clients. AppSync Events resources persist across restarts (PERSIST_STATE=1) — Event APIs, channel namespaces, and API keys were silently dropped on restart because the events module was reached only via a cross-service call from the parent AppSync handler; same fix covers related restart drops for apigateway_v1 first-boot, Lambda-auto-created CloudWatch log groups, and EventBridge targets fired by S3 notifications. Reported by @yaegassy. RDS respawn no longer fails with port is already allocated — restored instances were trying to bind the engine's standard port instead of the original docker host port; the host port is now tracked separately, probed for freeness before reuse, and falls back to a fresh free port if taken. Reported by @doodaz. CloudFront DistributionSummary parity — ListDistributions round-trips the stored origin configuration (Origins, DefaultCacheBehavior; contributed by @CoffeeRaptor), plus the remaining required fields of the real AWS shape (Aliases, CacheBehaviors, CustomErrorResponses, PriceClass, ViewerCertificate, Restrictions, WebACLId, HttpVersion, IsIPV6Enabled, Staging) so strict-parsing SDKs (Go v2, Java v2) don't reject the response.GetObjectAcl and PutObjectAcl — both ?acl subresource operations are now implemented. GetObjectAcl returns the stored policy or, if none has been set, the AWS default of a single FULL_CONTROL Grant to the request account-id owner. PutObjectAcl accepts either a canned ACL via the x-amz-acl header (private, public-read, public-read-write, authenticated-read, aws-exec-read, bucket-owner-read, bucket-owner-full-control) or a full <AccessControlPolicy> XML body; invalid canned values return InvalidArgument and malformed bodies return MalformedACLError. As with retention, legal-hold, and bucket policies, the ACL is stored and round-tripped but not enforced on the data plane. NoSuchKey for missing keys. Reported by @smpial. RDS persistence-restore module-import race — the v1.3.47 restore-respawn daemon threads called _get_docker() which was defined further down in the same module, so a thread reaching the lookup before the parser finished raised NameError and stranded the restored instance in creating. The load_state("rds") block now runs at the bottom of the module, after every helper the restore threads can touch. Reported by @doodaz.AWS::CloudFormation::Stack resources now fetch their child template from TemplateURL (resolved against the local S3 emulator), pass Parameters through, provision the child's resources inline, and expose the child's Outputs back to the parent via Fn::GetAtt: [Nested, Outputs.<Name>] — the same form CDK's NestedStack emits. Ref resolves to the child StackId ARN; delete and update propagate to the child. CloudFront CreateInvalidation is now idempotent on repeated CallerReference (path comparison is set-based so different orderings count as the same batch). S3 DeleteObjects now removes persisted files from disk, mirroring DeleteObject. RDS respawns the backing Docker container for persisted DB instances at reload (creating → available/failed based on container liveness) instead of leaving them as zombie metadata that StartDBInstance can't recover; per-instance threads carry the original account context. Cognito /oauth2/idpresponse and /saml2/idpresponse errors now distinguish missing code vs missing state vs unknown/expired relay, with a server-side WARNING log so federated-login configuration drift (Keycloak, Auth0, Okta) is diagnosable. Cognito .well-known/* falls through to S3 when the pool prefix isn't a registered user pool, so apps storing their own OIDC discovery doc as an S3 object aren't shadowed by a fake Cognito JWKS.PutObject conditional writes — If-None-Match: "*" gives create-once semantics, If-Match: "<etag>" gives optimistic concurrency. Both are now enforced on PutObject, matching the AWS feature shipped November 2024. Precondition violations return 412 PreconditionFailed (with one documented exception: If-Match against a missing key returns 404 NoSuchKey). ETag comparison strips surrounding quotes on both sides. The symmetric x-amz-copy-source-if-match headers on CopyObject were already supported; this closes the gap on plain PutObject. Cognito JWT iss claim now uses the pool's region, not the request region — a SigV4 scope carrying a different region from the pool's creation region used to stamp the JWT with the request region, so standards-compliant validators (which check iss == https://cognito-idp.<region>.amazonaws.com/<poolId>) rejected the token. A new _pool_region(pool_id) resolver parses the region from the pool ID and is applied to iss, PreTokenGeneration trigger event region, user-pool ARN, OIDC discovery issuer, and hosted-UI CloudFront URLs on CreateUserPoolDomain / DescribeUserPoolDomain. Accepts 3-segment commercial and 4-segment GovCloud / ISO regions.GetLogEvents / FilterLogEvents now accept logGroupIdentifier (either a bare group name or a full arn:aws:logs:<region>:<account>:log-group:<name>[:*] ARN) in addition to logGroupName — calls passing an ARN no longer fail with ResourceNotFoundException: The specified log group does not exist: None. ElastiCache DescribeCacheClusters per-node XML now includes CacheNodeCreateTime (ISO8601), ParameterGroupStatus, CustomerAvailabilityZone, and SourceCacheNodeId, so hashicorp/terraform-provider-aws v6.45.0's read of CacheNodeCreateTime stops crashing with Unexpected nil pointer in: {CacheNodeCreateTime:<nil> ...}. API Gateway v1 UpdateStage now coerces the patch value string to bool for tracingEnabled and cacheClusterEnabled (AWS sends every patch value as a string, but the SDK v2 deserializer expects *bool on the response) — exact path match so a stage variable named tracingEnabled is unaffected.$uppercase, $lowercase, $substring, $trim, $contains, $split, $join, $replace, $pad), numeric ($sum, $average, $max, $min, $abs, $floor, $ceil, $round, $power, $sqrt, $formatNumber), array ($sort with comparator-function form, $reverse, $distinct, $append), object ($keys, $values, $lookup over both objects and arrays-of-objects, $exists), type ($type, $boolean), date/time ($now()/$now(picture)/$now(picture, timezone), $millis), and utility ($uuid, $base64encode, $base64decode). $contains/$split/$replace accept JSONata regex literals (/pattern/flags); $exists now distinguishes a missing path from an explicit null. The motivating "Condition": "{% $exists($states.input.userId) %}" in Choice routes correctly in every case. Implemented natively in Python with no new runtime dependency. RDS Data API stops silently acking writes against a still-booting container — container-backed clusters whose endpoint can't be reached now surface DatabaseUnavailableException (HTTP 504) instead of falling through to the in-memory SQL stub. CreateDBInstance returns immediately with status=creating matching real AWS — readiness finalisation runs on a daemon thread, no wall-clock timeout, transitions to available or failed based on container liveness. ECS RunTask containers now carry the five canonical com.amazonaws.ecs.* labels real ECS sets (cluster ARN, container-name, task-arn, task-definition-family, task-definition-version), so host-side agents identify them the same way they would against real ECS.DescribeEndpoint on the control plane, MQTT 3.1.1 over WebSocket on the gateway port plus HTTP iot-data Publish on the data plane. Persistent sessions, QoS 1 with DUP-flag retransmits, Last Will and Testament, retained messages, multi-tenancy via account-prefixed topics — all per the MQTT 3.1.1 spec. Local CA cert at GET /_ministack/iot/ca.pem; CA + broker state persist across restarts. Requires cryptography (in [full]). Athena now resolves database.table references against Glue's GetTable so queries pick up table locations automatically, and completed query results persist to OutputLocation as <id>.csv (with the column-name header row, matching real Athena) plus a <id>.csv.metadata sidecar. DuckDB execution offloaded to a worker thread so the event loop stays free under concurrent queries. EventBridge rule targets pointing at arn:aws:states:...:stateMachine:<name> now actually dispatch — they were silently dropped before — passing the transformed event payload verbatim as the execution input.apache/airflow:<version> containers for both 2.x and 3.x — CreateEnvironment spawns a container in standalone mode, syncs DAGs from your S3 bucket into /opt/airflow/dags/, forces aggressive scan intervals so DAGs become visible in seconds, and InvokeRestApi proxies straight through to Airflow's REST API (auth handled transparently for both v2 basic-auth and v3 Simple Auth Manager). End-to-end verified with real DAGs visible on both apache/airflow:2.10.4 and apache/airflow:3.0.6. CloudWatch alarm actions now publish to SNS on every OK ↔ ALARM ↔ INSUFFICIENT_DATA transition with the AWS-shaped payload (NewStateValue, StateChangeTime, Trigger sub-object) — alerting-driven test scenarios work end-to-end. Lambda emits the four canonical AWS/Lambda metrics on every invocation (Invocations, Errors, Duration, Throttles), dimensioned by FunctionName; combined with the alarm-action fix, end-to-end Lambda observability tests (invoke → error → alarm fires → SNS notification arrives) work in one local run. CFN AWS::ApiGateway::Account closes the gap that blocked CDK new RestApi({ cloudWatchRole: true }) stacks with Unsupported resource type.Decrypt on a malformed CiphertextBlob without an explicit KeyId now returns InvalidCiphertextException (matches real AWS) instead of NotFoundException. The KeyId-given branch is unchanged — explicit-key-not-found still returns NotFoundException, also matching AWS. Wrapper libraries that catch encryption faults separately from key-lookup faults (retry on NotFound, surface InvalidCiphertext immediately) now see the same code locally as in production. Encrypt/Decrypt round-trips, asymmetric key paths (RSAES_OAEP_SHA_256, etc.), and every other KMS operation are untouched.AdminCreateUser, SignUp, ResendConfirmationCode, ForgotPassword, and AdminResetUserPassword all hand their welcome / temporary-password / verification messages to SES, so tests see them at /_ministack/ses/messages and they relay via SMTP when SMTP_HOST is set. MessageAction=SUPPRESS/RESEND, DesiredDeliveryMediums, InviteMessageTemplate / VerificationMessageTemplate placeholders, and the EmailConfiguration.From override all match AWS; ResendConfirmationCode ships alongside as a previously-missing action. Step Functions JSONata gains state-level Assign + execution-scoped variables: bind values to $name in any state, reference them in any later JSONata expression with dotted-path access, with States.QueryEvaluationError for undefined refs. Cognito sign-in honors AliasAttributes and UsernameAttributes — users can sign in by email, phone_number, or preferred_username (verification gate on email/phone, matching AWS), routed through every auth/verify call site. SQS RedrivePolicy is validated at CreateQueue / SetQueueAttributes — malformed values return 400 InvalidAttributeValue instead of crashing the queue's ReceiveMessage with InternalError. DynamoDB SET v = (if_not_exists(v, :d) - :amt) now actually subtracts (the outer parens used to hide the operator from the top-level scan). S3 → Lambda notifications fire for non-boto3 SDK clients: the XML parser accepts both the legacy <CloudFunction> tag (botocore wire form) and the modern <LambdaFunctionArn> tag (AWS SDK Java v2, Go SDK, Terraform, hand-crafted XML).Arguments and success/Catch Output against $states.input / $states.result / $states.errorOutput (was dispatching with empty payloads); Pass evaluates Output (was silently ignored); Choice evaluates per-branch Condition and per-branch Output (was always falling through to Default). The evaluator gained comparison, arithmetic, string concat (&), and/or/in, $count / $length / $not / $string / $number, paren grouping, and left-associative parsing. Step Functions executions no longer stall at ExecutionStarted under non-default 12-digit account IDs — the background worker now inherits the request's contextvars via copy_context().run, with per-thread snapshots at the Parallel and Map spawn sites. Cognito OIDC federation completes: /oauth2/idpresponse exchanges the IdP's code against its token_url, decodes the id_token, applies AttributeMapping, and provisions the federated user (SAML federation continues to use /saml2/idpresponse). Node.js Lambda handlers can now require('@aws-sdk/client-*') the same way real AWS-managed runtimes do — Lambda gets a dedicated REST stub, 28 awsJson1.x services resolve via a generic X-Amz-Target Proxy stub, errors expose err.name for the v3 catch-by-name convention, and the HTTPS→HTTP localhost downgrade now covers CDK Provider Framework's cfn-response.js PUT.AWS::CertificateManager::Certificate (every HTTPS IaC stack now applies); AWS::ElasticLoadBalancingV2::TargetGroup and AWS::ElasticLoadBalancingV2::ListenerRule (the ALB CFN story was previously partial — Listener had nothing to forward to); AWS::RDS::DBInstance (standalone DBs and Aurora cluster members, metadata-only like the existing DBCluster handler); and Step Functions Definition + DefinitionS3Location with DefinitionSubstitutions (so CDK's DefinitionBody.fromFile() stops producing InvalidDefinition: StartAt state 'None' not found). ECS task IAM role credentials endpoint at GET /v2/credentials/<uuid> with the AWS-strict 5-field shape (AccessKeyId, SecretAccessKey, Token, Expiration, RoleArn) — distinct from the IMDS endpoint at /latest/meta-data/iam/security-credentials/<role>. RunTask injects AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_CONTAINER_AUTHORIZATION_TOKEN, and AWS_ENDPOINT_URL so unmodified SDKs in the task work end-to-end. ECS connectivityAt/stoppingAt now wire as JSON numbers (Go SDK v2 strict parsing); CFN AWS::ECS::TaskDefinition populates registeredAt/registeredBy/compatibilities.AWS::ApiGateway::Authorizer (TOKEN / REQUEST / COGNITO_USER_POOLS) provisions instead of failing the stack. SQS AddPermission / RemovePermission wire through to the queue's Policy attribute in AWS-canonical shape (bare account ID in Principal.AWS, lowercase sqs: action prefix). RDS DescribePendingMaintenanceActions accepts the call and returns an empty list. Six AWS-parity correctness fixes: SQS SendMessage validates body against MaximumMessageSize (was silently accepting oversized); SNS Publish/PublishBatch enforce the 256 KiB Message+Attributes limit; EventBridge SQS targets now stamp SqsParameters.MessageGroupId on FIFO queues (was dropped at dispatch); SQS DeleteQueue raises QueueDoesNotExist for missing queues (was silently 200); S3 UploadPartCopy validates x-amz-copy-source-range (malformed values were 500, reversed/out-of-bounds were silent 200s); S3 _parse_bucket_key strips absolute-form request targets (AWS SDK for .NET v4 was hitting NoSuchBucket: http:).arn:aws:iam::aws:policy/<Name>) now resolve from any session account, pre-seeded with 20 of the most-referenced canonical documents (Administrator/PowerUser/ReadOnly/SecurityAudit, the AmazonS3/EC2/DynamoDB/SQS/SNS Full and ReadOnly variants, AWSLambdaBasicExecutionRole / VPCAccessExecutionRole, AmazonSSMManagedInstanceCore, AmazonECSTaskExecutionRolePolicy, CloudWatchAgentServerPolicy / LogsFullAccess, AWSCloudFormationFullAccess). Unknown AWS-managed ARNs return NoSuchEntity so typos surface locally; opt in to permissive autovivify with MINISTACK_AUTOCREATE_AWS_MANAGED=1. AttachmentCount is per-session-account. Full 7-operation Cost and Usage Reports service for IaC validation (no cost data emulation — Terraform / CDK / Bash that manages aws_cur_report_definition can now plan and apply locally). Lambda ruby4.0 wired to AWS's official base image (tracking botocore 1.42.94). RDS DescribeDBClusters serialization fixed for DatabaseName / NetworkType / EngineLifecycleSupport; DescribeDBClusterParameters emits <Source>. Two warm-boot persistence gaps closed (CUR was never loading state on import; IAM AttachmentCount sidecar was missing from get_state / restore_state).CreateCluster works again — the k3s server container is now launched with privileged=True (k3s needs to remount /sys/fs/cgroup, which no granular capability set permits, so it was exiting on boot with failed to evacuate root cgroup). SNS FIFO topics can now subscribe standard SQS queues, matching AWS behaviour since 2023-09-14 — the stale validation that returned InvalidParameterException is removed. RDS CreateDBInstance now honours caller-supplied PreferredMaintenanceWindow instead of hardcoding sun:05:00-sun:06:00.docker push and docker pull against MiniStack work end-to-end: /v2/ ping, _catalog, chunked and single-shot blob uploads, cross-repo blob mounts, manifest PUT/GET/HEAD/DELETE, and tags/list. Pushed images show up immediately in aws ecr describe-images. CloudFormation Custom::* and AWS::CloudFormation::CustomResource resources run the full Create / Update / Delete lifecycle through a local /_ministack/cfn-response/{token} intercept — CDK cr.Provider Lambdas are now supported. Cognito OAuth2 id_token now echoes the client-supplied nonce per OIDC Core 1.0 §3.1.3.7.AWS::DynamoDB::GlobalTable — what CDK TableV2 emits — now provision in MiniStack. KeySchema, AttributeDefinitions, BillingMode, StreamSpecification, GSIs, LSIs, SSESpecification, TimeToLiveSpecification, TableName are honoured. For PROVISIONED billing, WriteProvisionedThroughputSettings.WriteCapacityAutoScalingSettings.MinCapacity (and the read counterpart) translate to static ProvisionedThroughput since the emulator doesn't simulate auto-scaling. Replicas, MultiRegionConsistency, GlobalTableWitnesses, GlobalTableSourceArn, WarmThroughput, and the on-demand throughput settings are accepted and ignored./.well-known/openid-configuration now returns reachable URLs at the MiniStack gateway (was pointing at cognito-idp.<region>.amazonaws.com URLs that don't serve OAuth2 anywhere); response_types_supported advertises both code and token per AWS. Cognito OAuth2 / OIDC endpoints (/oauth2/authorize, /oauth2/token, /oauth2/userInfo, /logout, /.well-known/*) now send wildcard CORS so Amplify, oidc-client-ts, and react-oidc-context work cross-origin. EC2 VPN Connection CRUD plus a DescribeRouteTables fix that emits propagatingVgwSet. EC2 RunInstances honours --private-ip-address and --iam-instance-profile (both were silently dropped; default IPs were malformed). DynamoDB GSI Query pagination now tiebreaks on the base table primary key, so ExclusiveStartKey doesn't drop or cycle items when the GSI sort key collides.AWS_ACCESS_KEY_ID from the function ARN (warm pool keyed per account), so STS GetCallerIdentity from inside the handler resolves to the owning tenant. EC2 RunInstances auto-attaches a root EBS volume so DescribeInstances emits BlockDeviceMappings matching real AWS — Cloud Custodian and AWS Config policies no longer break. S3 versioned GetObject emits RFC 7231 Last-Modified, fixing AWS SDK for JavaScript v3's strict header parser. EC2 AWS-managed prefix lists return deterministic CIDRs (s3, dynamodb, s3express, vpc-lattice, route53-healthchecks, ec2-instance-connect, cloudfront, groundstation) for Gateway-type VPC endpoints.aws-sdk integrations (e.g. aws-sdk:rdsdata:executeStatement) now expose output keys with the same PascalCase convention as the query and REST-XML dispatchers (Records, NumberOfRecordsUpdated) instead of raw camelCase wire keys, so ResultSelector paths like $.Records resolve correctly.DescribeVpcEndpointServices with the standard 2 Gateway + 17 Interface PrivateLink catalog. DynamoDB legacy AttributeUpdates (PUT / DELETE / ADD) for .NET SDK upserts. Step Functions aws-sdk:ec2 security-group dispatch now uses EC2-shaped Filter.1.Value.1 instead of generic member.N; aws-sdk:s3 integrations gain a REST-XML dispatcher covering ListBuckets, CreateBucket, DeleteBucket, HeadBucket, GetBucketVersioning, ListObjectsV2, ListObjects, HeadObject, CopyObject, DeleteObject, GetObjectTagging, PutObjectTagging. SQS ReceiveMessage honours the modern MessageSystemAttributeNames for AWS SDK v2 (Java/Kotlin). CFN AWS::SNS::Subscription honours RawMessageDelivery.RunTask gets ECS_CONTAINER_METADATA_URI_V4 injected, and the gateway serves /v4/<token>, /v4/<token>/task (with sibling Containers), and /stats. RunTask also translates privileged, linuxParameters.capabilities.add, pidMode: host, and volumes + mountPoints into Docker bind mounts. DynamoDB legacy Expected (PutItem / UpdateItem / DeleteItem) and KeyConditions (Query) now evaluated correctly with all 13 comparison operators and type-aware numeric compare. TransactWriteItems CancellationReasons now reports every failing item, not just the first.CLOUDTRAIL_RECORDING=1; all 8 LookupAttributes) and AWS Resource Groups (19 of 23 spec ops). Plus a sweep of AWS-spec parity fixes: API Gateway v1 GetUsagePlanKey / HTTP_PROXY path-param substitution / UpdateModel; Transfer Family LOGICAL root home directories; STS Credentials.Expiration int epoch; DynamoDB Item populated on ConditionalCheckFailedException when ReturnValuesOnConditionCheckFailure="ALL_OLD"; CloudFormation AWS::S3::Bucket physical-id preservation across stack updates; CloudFormation AWS::Lambda::Function returns real CodeSize and CodeSha256.s3files-2025-05-05) routes and shapes now match the published AWS spec end to end: PUT /file-systems (was POST), camelCase request/response bodies, /resource-tags/{resourceId} for tagging, PutSynchronizationConfiguration optimistic concurrency. OpenSearch non-VPC domains stop emitting empty VPCOptions alongside Endpoint, which was causing the Terraform AWS provider to misclassify the domain as VPC-backed and fail. CloudFormation AWS::CloudFront::KeyValueStore provisioning lands with in-place Comment update + ImportSource support on the native CloudFront API.aws-appsync-event-ws subprotocol) and CloudFront KeyValueStore (management plane + the separate cloudfront-keyvaluestore data-plane SDK service). EventBridge cron() now has full AWS-spec parity — L, LW, <n>W, <n>L, <n>#<k> operators and DoM/DoW mutual-exclusion enforced at PutRule. Plus 8 EventBridge AWS-spec divergences fixed (CreatedBy/ManagedBy, PutEvents 10-cap, int Time, exists:false on absent keys, ListRules pagination, opaque NextToken, omitted empty Policy, EventSource state enum).x-amzn-errortype response header that Java SDK v2, Go SDK v2, and Rust SDK read — without it they surface SdkClientException: unknown error type instead of the actual code. AppConfig 404 bodies include __type alongside the existing Code/Message. Three previously-stateless services (account, waf-classic, resourcegroupstaggingapi) expose a no-op reset() so /_ministack/reset no longer logs warnings.aws CLI. Write init scripts in Shell or Python with automatic credentials.