github ministackorg/ministack v1.5.13

9 hours ago

What's Changed

New Contributors

[1.5.13] — 2026-09-17

Added

  • CloudFormation — the AWS::LanguageExtensions transform — a template declaring it was provisioned unexpanded, so an Fn::ForEach left the stack in CREATE_IN_PROGRESS for good and an Fn::ToJsonString reached SSM as a Python dict. The transform now runs between AWS::Include and SAM: Fn::ForEach over literal, CommaDelimitedList and intrinsic collections, nested and inside Properties, plus Fn::Length and Fn::ToJsonString. Where the identifier is substituted, the error sentences and the unexpanded GetTemplateSummary follow measurements on a real account. Contributed by @iot-rocket.
  • RDS — IAM database authentication tokens are verified — a helper validates an SDK-generated token against the endpoint, port, database username, signing scope, lifetime and signature. Nothing calls it yet; database login itself is a later stage. Contributed by @Areson.

Changed

  • Persistence — every saved snapshot is restored through the registry — a service restored its own state as a side effect of being imported, so the boot path carried a hand-maintained list of eager imports to cover the modules the router never reached. The registry now drives one restore loop, and the runtime work a restore implies runs from each module's load_persisted_state instead of its import. No user-visible change. Contributed by @jgrumboe.

Fixed

  • Router — the first request to any service no longer loads CloudFormation — the WaitCondition signal handler imported cloudformation.wait_conditions above the path check, so every first request pulled in the whole package and, through its provisioners, AppSync and graphql; the first /_ministack/reset ran appsync.reset() with it. The import now sits behind the path match, and a guard keeps it there. Reported by @ThailerL.
  • DynamoDB — ImportTable reads the S3 source — the import created the table, reported COMPLETED and imported nothing: the source objects were never opened. CSV and DYNAMODB_JSON, GZIP or uncompressed, are now read from the prefix and written into the table, with the counters reported as it runs and per-item errors in the /aws-dynamodb/imports log group. A missing bucket or prefix fails the import and leaves no table behind; ION and ZSTD are refused with a stated reason. Contributed by @gakuto-cw21.
  • IAM — a Secrets Manager request is authorized against the stored secret ARN — the resource was built from the name in the request, secret:<name>, while AWS evaluates the stored ARN with the six random characters minted at CreateSecret. The grant shape the CDK writes for a secret looked up by name, secret:<name>-?????? or secret:<name>-*, matched nothing under AUTH=true. The resource now comes from the store through the handlers' own lookup; a secret that does not exist keeps the name-derived ARN. Contributed by @iot-rocket.
  • IAM — a group policy document is validated, and an AWS::IAM::Policy naming a missing entity failsPutGroupPolicy stored a malformed document; all three inline handlers now answer NoSuchEntity before MalformedPolicyDocument. An AWS::IAM::Policy skipped a Role, User or Group that was not there and reported CREATE_COMPLETE; the resource now fails with The role with name <name> cannot be found., and an update checks names and document before it takes the old policy off. Contributed by @iot-rocket.
  • IAM — three calls are authorized against the action and resource AWS uses — a Lambda Function URL invoke is checked against its function ARN, alias qualifier included, and supplies lambda:FunctionUrlAuthType, so the policy grantInvokeUrl writes matches. The WebSocket @connections API asks for execute-api:ManageConnections instead of execute-api:Invoke. iot-jobs-data operations are authorized under iotjobsdata:, except StartCommandExecution, which stays on iot:. A policy written for the old action names stops matching, as on AWS. Contributed by @iot-rocket.
  • Lambda — a layer shared through AddLayerVersionPermission attaches — every layer ARN from another account was refused before the stored policy was read. Attachment, from the API and from a CloudFormation function, and GetLayerVersionByArn now evaluate it for account, root, public and organization grants, and an attached function keeps the content after the grant is revoked or the version is deleted. A foreign layer version that no grant covers stays refused. Contributed by @iot-rocket.

Don't miss a new ministack release

NewReleases is sending notifications on new releases.