# Release notes 0.1.154

> 25 October 2026: A vulnerable container image can be rebuilt by a step runbook under a new tag, with an opt-in block of pulls from its repository; a fix's validation rounds can ask AWS Reachability…

_Release notes · Updated 2026-10-28 · Describes release 0.1.164_

## 0.1.154 — 25 October 2026 {#0-1-154-25-october-2026}

A vulnerable container image can be rebuilt by a step runbook under a new tag, with an opt-in block of pulls from its repository; a fix's validation rounds can ask AWS Reachability Analyzer whether its neighbours still reach the changed instance; and the runbook permission check no longer reads a permission the write role lacks as *unknown* (live test of 0.1.153). No schema change and no new route. New settings `aiops_ecr_block_pulls` and `aiops_reachability_checks` (both off), `aiops_reachability_max_per_change` and `aiops_image_reminder_h`; new write-role permissions (see the [upgrade row](/help/ops-upgrade-and-verify.md)).

- **Container image rebuild:** the step-runbook operation `aws.ecr.rebuild_image` (runbook only: the analysis never proposes it) starts ONE build of the customer's own CodeBuild project `aiops-image-rebuild`, which pulls the vulnerable image by digest, upgrades the packages the scanner named to the versions it says fix them in a layer on top (OS packages through apt, apk, dnf, microdnf or yum, Python packages through pip — only packages the image already has, never to an older version) and pushes the result to the same repository under a NEW tag, `<tag>-aiops-chg-<change>`. The old tag and digest stay untouched and nothing running is redeployed, so the rollback step is `none`. A package compiled into a binary, or one with no fixed version, refuses the whole step (rebuild it from source with a pull request), and so does a multi-architecture image (the build rebuilds `linux/amd64` only). The runbook binds the image from the finding's `annotation:resource_arn` and the packages from `annotation:vulnerable_packages`. The platform never creates or edits the project: `deploy/aws` creates it with `image_rebuild = true` (its buildspec refuses a tag that exists or is not a rebuild tag, matches each of the five variables as a whole value and passes the change id as a build label, never as a Dockerfile line; its own role pulls and pushes only repositories tagged `aiops-managed=true`). A build the platform stopped waiting on is read again on the scheduler's tick. Not yet run against a live registry: tested against simulated ECR and CodeBuild answers.
- **Built, not deployed:** once the new tag is pushed, the validation reads the scanner's finding on the OLD digest ($0, no agent run). While it is still open the change completes, the incident goes to a person (the deploy is theirs) and the incident and finding pages show **New image built, not deployed** with the new tag and digest. Notification targets that take the new event `image_not_deployed` hear it then and again every `aiops_image_reminder_h` hours (24; `0` = once) until the scanner stops reporting the old digest, which resolves the incident (audit `image.not_deployed`, one row per reminder). Moving the workloads to the new tag does not stop the reminders on its own: the old tag and digest stay in the registry and the scanner keeps reporting them until someone deletes or untags the old digest, or the scanner's re-scan period for it ends. Incident and finding details carry `image_rebuilds`.
- **Block pulls of this image (opt-in, off):** with **Allow a runbook to block pulls of a vulnerable image** on (**Change safety**, `aiops_ecr_block_pulls`), a runbook step `aws.ecr.block_image_pulls` adds one Deny statement to the image's ECR repository policy (pulls refused to every principal but the account's `aiops-*` roles). ECR authorizes a pull per repository, so it blocks every image there, the rebuilt tag included. Always L3 (two people), never automatic; the policy read before the write is recorded and **Roll back** puts it back, or deletes the policy when there was none. The guided setup never grants the repository-policy actions: only `deploy/aws` with `image_pull_block = true`. Not yet run against live AWS: tested against simulated ECR answers.
- **Neighbour reachability in the validation rounds (AWS, off):** with `aiops_reachability_checks` on (API only), a validation window chosen from the service graph also asks Reachability Analyzer whether a path on any TCP port exists between each one-hop neighbour that has an EC2 network interface and the changed instance, once per window (later rounds carry the answer). The path and analysis are created through the change's write connection, tagged `aiops:change`, and deleted as soon as the answer is in; an analysis not finished in 60 seconds reads *not observed*; while the switch is on a sweep removes any such path older than an hour. AWS bills about USD 0.10 per analysis to the account: at most `aiops_reachability_max_per_change` (10, `0`–`60`) a change. It uses the write role's Reachability statements added in 0.1.146. Not yet run against live AWS: tested against simulated EC2 answers.
- **The runbook permission check reads an absent permission as missing:** on the live test of 0.1.153 a write role lacking `ec2:ModifyNetworkInterfaceAttribute` and `ssm:DescribeInstancePatchStates` read *unknown* for both and the runbook was certified. IAM's `MissingContextValues` lists every condition key the role's policies use, related to the action or not, even on a deny; the check read any listed key as *unknown*. A deny — implicit or explicit, whether a statement matched or not (the write role's Deny boundary, a permissions boundary) — is now *missing*, and the certification is refused. *Unknown* is kept for an allow IAM answered with a key still absent and for a real target whose tags could not be read (before an automatic run, the instance's network interfaces); a listed key the check can supply after all (a region key, a resource tag under another service's prefix) is filled in and asked once more. The image operations' ECR actions are simulated against the image's repository, the isolation's group side against the security groups it attaches. The route editor and the certification line now say *unknown does not mean granted*, and a refusal says the role lacks the permission or grants it only under a condition the check cannot supply (a source IP or VPC endpoint, a principal tag). With no target the check simulates a resource tagged with the write connection's `scope.resource_tag` — which `deploy/aws`'s `datasource_snippet` now prints from `resource_tag_key` / `resource_tag_value` — else `aiops-managed=true`: a role scoped by another tag reads *missing* and is refused until the connection names its tag. The S3 Block Public Access fix's rollback is checked for `s3:PutAccountPublicAccessBlock` only (it also authorizes the delete when the account had no block before; the check asked for an `s3:DeleteAccountPublicAccessBlock` IAM does not have).


## Next steps

- Next: [Release notes 0.1.153](/help/release-notes-0-1-153.md)
- [All What's new pages](/help/what-s-new/llms.txt)
- [Documentation home](/help/)
