Guides, changelogs, and community highlights for the free LocalStack alternative.
.github/workflows/ file that runs your AWS tests on every push.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.